Mega Code Archive

 
Categories / Java / Swing Components
 

Mixed Table Example

// Example from http://www.crionics.com/products/opensource/faq/swing_ex/SwingExamples.html /*  * (swing1.1beta3)  */ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Enumeration; import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JColorChooser; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.TableModelEvent; import javax.swing.plaf.basic.BasicTableUI; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableModel; /**  * @version 1.0 11/22/98  */ public class MixedExample extends JFrame {   public MixedExample() {     super("Mixed Example");     AttributiveCellTableModel ml = new AttributiveCellTableModel(20, 5) {       public Object getValueAt(int row, int col) {         return "" + row + "," + col;       }     };     CellAttribute cellAtt = ml.getCellAttribute();     MultiSpanCellTable table = new MultiSpanCellTable(ml);     table.setCellSelectionEnabled(true);     table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);     table.setDefaultRenderer(Object.class, new AttributiveCellRenderer());     JScrollPane scroll = new JScrollPane(table);     ColorPanel colorPanel = new ColorPanel(table, (ColoredCell) cellAtt);     FontPanel fontPanel = new FontPanel(table, (CellFont) cellAtt);     SpanPanel spanPanel = new SpanPanel(table, (CellSpan) cellAtt);     Box boxAtt = new Box(BoxLayout.Y_AXIS);     boxAtt.add(colorPanel);     boxAtt.add(fontPanel);     boxAtt.add(spanPanel);     Box box = new Box(BoxLayout.X_AXIS);     box.add(scroll);     box.add(new JSeparator(SwingConstants.HORIZONTAL));     box.add(boxAtt);     getContentPane().add(box);     setSize(400, 300);     setVisible(true);   }   class ColorPanel extends JPanel {     JTable table;     ColoredCell cellAtt;     ColorPanel(final JTable table, final ColoredCell cellAtt) {       this.table = table;       this.cellAtt = cellAtt;       setLayout(new GridLayout(2, 1));       setBorder(BorderFactory.createTitledBorder("Color"));       JButton b_fore = new JButton("Foreground");       b_fore.addActionListener(new ActionListener() {         public void actionPerformed(ActionEvent e) {           changeColor(true);         }       });       JButton b_back = new JButton("Background");       b_back.addActionListener(new ActionListener() {         public void actionPerformed(ActionEvent e) {           changeColor(false);         }       });       JPanel p_buttons = new JPanel();       add(b_fore);       add(b_back);     }     private final void changeColor(boolean isForeground) {       int[] columns = table.getSelectedColumns();       int[] rows = table.getSelectedRows();       if ((rows == null) || (columns == null))         return;       if ((rows.length < 1) || (columns.length < 1))         return;       Color target = cellAtt.getForeground(rows[0], columns[0]);       Color reference = cellAtt.getBackground(rows[0], columns[0]);       for (int i = 0; i < rows.length; i++) {         int row = rows[i];         for (int j = 0; j < columns.length; j++) {           int column = columns[j];           target = (target != cellAtt.getForeground(row, column)) ? null               : target;           reference = (reference != cellAtt               .getBackground(row, column)) ? null : reference;         }       }       String title;       if (isForeground) {         target = (target != null) ? target : table.getForeground();         reference = (reference != null) ? reference : table             .getBackground();         title = "Foreground Color";       } else {         target = (reference != null) ? reference : table             .getBackground();         reference = (target != null) ? target : table.getForeground();         title = "Foreground Color";       }       TextColorChooser chooser = new TextColorChooser(target, reference,           isForeground);       Color color = chooser.showDialog(MixedExample.this, title);       if (color != null) {         if (isForeground) {           cellAtt.setForeground(color, rows, columns);         } else {           cellAtt.setBackground(color, rows, columns);         }         table.clearSelection();         table.revalidate();         table.repaint();       }     }   }   class FontPanel extends JPanel {     String[] str_size = { "10", "12", "14", "16", "20" };     String[] str_style = { "PLAIN", "BOLD", "ITALIC" };     JComboBox name, style, size;     FontPanel(final JTable table, final CellFont cellAtt) {       setLayout(new BorderLayout());       setBorder(BorderFactory.createTitledBorder("Font"));       Box box = new Box(BoxLayout.X_AXIS);       JPanel p2 = new JPanel(new GridLayout(3, 1));       JPanel p3 = new JPanel(new GridLayout(3, 1));       JPanel p4 = new JPanel(new BorderLayout());       p2.add(new JLabel("Name:"));       p2.add(new JLabel("Style:"));       p2.add(new JLabel("Size:"));       Toolkit toolkit = Toolkit.getDefaultToolkit();       name = new JComboBox(toolkit.getFontList());       style = new JComboBox(str_style);       size = new JComboBox(str_size);       size.setEditable(true);       JButton b_apply = new JButton("Apply");       b_apply.addActionListener(new ActionListener() {         public void actionPerformed(ActionEvent e) {           int[] columns = table.getSelectedColumns();           int[] rows = table.getSelectedRows();           if ((rows == null) || (columns == null))             return;           if ((rows.length < 1) || (columns.length < 1))             return;           Font font = new Font((String) name.getSelectedItem(), style               .getSelectedIndex(), Integer.parseInt((String) size               .getSelectedItem()));           cellAtt.setFont(font, rows, columns);           table.clearSelection();           table.revalidate();           table.repaint();         }       });       p3.add(name);       p3.add(style);       p3.add(size);       p4.add(BorderLayout.CENTER, b_apply);       box.add(p2);       box.add(p3);       add(BorderLayout.CENTER, box);       add(BorderLayout.SOUTH, p4);     }   }   class SpanPanel extends JPanel {     JTable table;     CellSpan cellAtt;     SpanPanel(final JTable table, final CellSpan cellAtt) {       this.table = table;       this.cellAtt = cellAtt;       setLayout(new GridLayout(2, 1));       setBorder(BorderFactory.createTitledBorder("Span"));       JButton b_one = new JButton("Combine");       b_one.addActionListener(new ActionListener() {         public void actionPerformed(ActionEvent e) {           int[] columns = table.getSelectedColumns();           int[] rows = table.getSelectedRows();           cellAtt.combine(rows, columns);           table.clearSelection();           table.revalidate();           table.repaint();         }       });       JButton b_split = new JButton("Split");       b_split.addActionListener(new ActionListener() {         public void actionPerformed(ActionEvent e) {           int column = table.getSelectedColumn();           int row = table.getSelectedRow();           cellAtt.split(row, column);           table.clearSelection();           table.revalidate();           table.repaint();         }       });       add(b_one);       add(b_split);     }   }   public static void main(String[] args) {     MixedExample frame = new MixedExample();     frame.addWindowListener(new WindowAdapter() {       public void windowClosing(WindowEvent e) {         System.exit(0);       }     });   } } class AttributiveCellTableModel extends DefaultTableModel {   protected CellAttribute cellAtt;   public AttributiveCellTableModel() {     this((Vector) null, 0);   }   public AttributiveCellTableModel(int numRows, int numColumns) {     Vector names = new Vector(numColumns);     names.setSize(numColumns);     setColumnIdentifiers(names);     dataVector = new Vector();     setNumRows(numRows);     cellAtt = new DefaultCellAttribute(numRows, numColumns);   }   public AttributiveCellTableModel(Vector columnNames, int numRows) {     setColumnIdentifiers(columnNames);     dataVector = new Vector();     setNumRows(numRows);     cellAtt = new DefaultCellAttribute(numRows, columnNames.size());   }   public AttributiveCellTableModel(Object[] columnNames, int numRows) {     this(convertToVector(columnNames), numRows);   }   public AttributiveCellTableModel(Vector data, Vector columnNames) {     setDataVector(data, columnNames);   }   public AttributiveCellTableModel(Object[][] data, Object[] columnNames) {     setDataVector(data, columnNames);   }   public void setDataVector(Vector newData, Vector columnNames) {     if (newData == null)       throw new IllegalArgumentException(           "setDataVector() - Null parameter");     dataVector = new Vector(0);     setColumnIdentifiers(columnNames);     dataVector = newData;     //     cellAtt = new DefaultCellAttribute(dataVector.size(), columnIdentifiers         .size());     newRowsAdded(new TableModelEvent(this, 0, getRowCount() - 1,         TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));   }   public void addColumn(Object columnName, Vector columnData) {     if (columnName == null)       throw new IllegalArgumentException("addColumn() - null parameter");     columnIdentifiers.addElement(columnName);     int index = 0;     Enumeration enumeration = dataVector.elements();     while (enumeration.hasMoreElements()) {       Object value;       if ((columnData != null) && (index < columnData.size()))         value = columnData.elementAt(index);       else         value = null;       ((Vector) enumeration.nextElement()).addElement(value);       index++;     }     //     cellAtt.addColumn();     fireTableStructureChanged();   }   public void addRow(Vector rowData) {     Vector newData = null;     if (rowData == null) {       newData = new Vector(getColumnCount());     } else {       rowData.setSize(getColumnCount());     }     dataVector.addElement(newData);     //     cellAtt.addRow();     newRowsAdded(new TableModelEvent(this, getRowCount() - 1,         getRowCount() - 1, TableModelEvent.ALL_COLUMNS,         TableModelEvent.INSERT));   }   public void insertRow(int row, Vector rowData) {     if (rowData == null) {       rowData = new Vector(getColumnCount());     } else {       rowData.setSize(getColumnCount());     }     dataVector.insertElementAt(rowData, row);     //     cellAtt.insertRow(row);     newRowsAdded(new TableModelEvent(this, row, row,         TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));   }   public CellAttribute getCellAttribute() {     return cellAtt;   }   public void setCellAttribute(CellAttribute newCellAtt) {     int numColumns = getColumnCount();     int numRows = getRowCount();     if ((newCellAtt.getSize().width != numColumns)         || (newCellAtt.getSize().height != numRows)) {       newCellAtt.setSize(new Dimension(numRows, numColumns));     }     cellAtt = newCellAtt;     fireTableDataChanged();   }   /*    * public void changeCellAttribute(int row, int column, Object command) {    * cellAtt.changeAttribute(row, column, command); }    *     * public void changeCellAttribute(int[] rows, int[] columns, Object    * command) { cellAtt.changeAttribute(rows, columns, command); }    */ } class DefaultCellAttribute //implements CellAttribute ,CellSpan {     implements CellAttribute, CellSpan, ColoredCell, CellFont {   //   // !!!! CAUTION !!!!!   // these values must be synchronized to Table data   //   protected int rowSize;   protected int columnSize;   protected int[][][] span; // CellSpan   protected Color[][] foreground; // ColoredCell   protected Color[][] background; //   protected Font[][] font; // CellFont   public DefaultCellAttribute() {     this(1, 1);   }   public DefaultCellAttribute(int numRows, int numColumns) {     setSize(new Dimension(numColumns, numRows));   }   protected void initValue() {     for (int i = 0; i < span.length; i++) {       for (int j = 0; j < span[i].length; j++) {         span[i][j][CellSpan.COLUMN] = 1;         span[i][j][CellSpan.ROW] = 1;       }     }   }   //   // CellSpan   //   public int[] getSpan(int row, int column) {     if (isOutOfBounds(row, column)) {       int[] ret_code = { 1, 1 };       return ret_code;     }     return span[row][column];   }   public void setSpan(int[] span, int row, int column) {     if (isOutOfBounds(row, column))       return;     this.span[row][column] = span;   }   public boolean isVisible(int row, int column) {     if (isOutOfBounds(row, column))       return false;     if ((span[row][column][CellSpan.COLUMN] < 1)         || (span[row][column][CellSpan.ROW] < 1))       return false;     return true;   }   public void combine(int[] rows, int[] columns) {     if (isOutOfBounds(rows, columns))       return;     int rowSpan = rows.length;     int columnSpan = columns.length;     int startRow = rows[0];     int startColumn = columns[0];     for (int i = 0; i < rowSpan; i++) {       for (int j = 0; j < columnSpan; j++) {         if ((span[startRow + i][startColumn + j][CellSpan.COLUMN] != 1)             || (span[startRow + i][startColumn + j][CellSpan.ROW] != 1)) {           //System.out.println("can't combine");           return;         }       }     }     for (int i = 0, ii = 0; i < rowSpan; i++, ii--) {       for (int j = 0, jj = 0; j < columnSpan; j++, jj--) {         span[startRow + i][startColumn + j][CellSpan.COLUMN] = jj;         span[startRow + i][startColumn + j][CellSpan.ROW] = ii;         //System.out.println("r " +ii +" c " +jj);       }     }     span[startRow][startColumn][CellSpan.COLUMN] = columnSpan;     span[startRow][startColumn][CellSpan.ROW] = rowSpan;   }   public void split(int row, int column) {     if (isOutOfBounds(row, column))       return;     int columnSpan = span[row][column][CellSpan.COLUMN];     int rowSpan = span[row][column][CellSpan.ROW];     for (int i = 0; i < rowSpan; i++) {       for (int j = 0; j < columnSpan; j++) {         span[row + i][column + j][CellSpan.COLUMN] = 1;         span[row + i][column + j][CellSpan.ROW] = 1;       }     }   }   //   // ColoredCell   //   public Color getForeground(int row, int column) {     if (isOutOfBounds(row, column))       return null;     return foreground[row][column];   }   public void setForeground(Color color, int row, int column) {     if (isOutOfBounds(row, column))       return;     foreground[row][column] = color;   }   public void setForeground(Color color, int[] rows, int[] columns) {     if (isOutOfBounds(rows, columns))       return;     setValues(foreground, color, rows, columns);   }   public Color getBackground(int row, int column) {     if (isOutOfBounds(row, column))       return null;     return background[row][column];   }   public void setBackground(Color color, int row, int column) {     if (isOutOfBounds(row, column))       return;     background[row][column] = color;   }   public void setBackground(Color color, int[] rows, int[] columns) {     if (isOutOfBounds(rows, columns))       return;     setValues(background, color, rows, columns);   }   //   //   // CellFont   //   public Font getFont(int row, int column) {     if (isOutOfBounds(row, column))       return null;     return font[row][column];   }   public void setFont(Font font, int row, int column) {     if (isOutOfBounds(row, column))       return;     this.font[row][column] = font;   }   public void setFont(Font font, int[] rows, int[] columns) {     if (isOutOfBounds(rows, columns))       return;     setValues(this.font, font, rows, columns);   }   //   //   // CellAttribute   //   public void addColumn() {     int[][][] oldSpan = span;     int numRows = oldSpan.length;     int numColumns = oldSpan[0].length;     span = new int[numRows][numColumns + 1][2];     System.arraycopy(oldSpan, 0, span, 0, numRows);     for (int i = 0; i < numRows; i++) {       span[i][numColumns][CellSpan.COLUMN] = 1;       span[i][numColumns][CellSpan.ROW] = 1;     }   }   public void addRow() {     int[][][] oldSpan = span;     int numRows = oldSpan.length;     int numColumns = oldSpan[0].length;     span = new int[numRows + 1][numColumns][2];     System.arraycopy(oldSpan, 0, span, 0, numRows);     for (int i = 0; i < numColumns; i++) {       span[numRows][i][CellSpan.COLUMN] = 1;       span[numRows][i][CellSpan.ROW] = 1;     }   }   public void insertRow(int row) {     int[][][] oldSpan = span;     int numRows = oldSpan.length;     int numColumns = oldSpan[0].length;     span = new int[numRows + 1][numColumns][2];     if (0 < row) {       System.arraycopy(oldSpan, 0, span, 0, row - 1);     }     System.arraycopy(oldSpan, 0, span, row, numRows - row);     for (int i = 0; i < numColumns; i++) {       span[row][i][CellSpan.COLUMN] = 1;       span[row][i][CellSpan.ROW] = 1;     }   }   public Dimension getSize() {     return new Dimension(rowSize, columnSize);   }   public void setSize(Dimension size) {     columnSize = size.width;     rowSize = size.height;     span = new int[rowSize][columnSize][2]; // 2: COLUMN,ROW     foreground = new Color[rowSize][columnSize];     background = new Color[rowSize][columnSize];     font = new Font[rowSize][columnSize];     initValue();   }   /*    * public void changeAttribute(int row, int column, Object command) { }    *     * public void changeAttribute(int[] rows, int[] columns, Object command) { }    */   protected boolean isOutOfBounds(int row, int column) {     if ((row < 0) || (rowSize <= row) || (column < 0)         || (columnSize <= column)) {       return true;     }     return false;   }   protected boolean isOutOfBounds(int[] rows, int[] columns) {     for (int i = 0; i < rows.length; i++) {       if ((rows[i] < 0) || (rowSize <= rows[i]))         return true;     }     for (int i = 0; i < columns.length; i++) {       if ((columns[i] < 0) || (columnSize <= columns[i]))         return true;     }     return false;   }   protected void setValues(Object[][] target, Object value, int[] rows,       int[] columns) {     for (int i = 0; i < rows.length; i++) {       int row = rows[i];       for (int j = 0; j < columns.length; j++) {         int column = columns[j];         target[row][column] = value;       }     }   } } interface CellAttribute {   public void addColumn();   public void addRow();   public void insertRow(int row);   public Dimension getSize();   public void setSize(Dimension size); } interface ColoredCell {   public Color getForeground(int row, int column);   public void setForeground(Color color, int row, int column);   public void setForeground(Color color, int[] rows, int[] columns);   public Color getBackground(int row, int column);   public void setBackground(Color color, int row, int column);   public void setBackground(Color color, int[] rows, int[] columns); } interface CellFont {   public Font getFont(int row, int column);   public void setFont(Font font, int row, int column);   public void setFont(Font font, int[] rows, int[] columns); } interface CellSpan {   public final int ROW = 0;   public final int COLUMN = 1;   public int[] getSpan(int row, int column);   public void setSpan(int[] span, int row, int column);   public boolean isVisible(int row, int column);   public void combine(int[] rows, int[] columns);   public void split(int row, int column); } class MultiSpanCellTable extends JTable {   public MultiSpanCellTable(TableModel model) {     super(model);     setUI(new MultiSpanCellTableUI());     getTableHeader().setReorderingAllowed(false);     setCellSelectionEnabled(true);     setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);   }   public Rectangle getCellRect(int row, int column, boolean includeSpacing) {     Rectangle sRect = super.getCellRect(row, column, includeSpacing);     if ((row < 0) || (column < 0) || (getRowCount() <= row)         || (getColumnCount() <= column)) {       return sRect;     }     CellSpan cellAtt = (CellSpan) ((AttributiveCellTableModel) getModel())         .getCellAttribute();     if (!cellAtt.isVisible(row, column)) {       int temp_row = row;       int temp_column = column;       row += cellAtt.getSpan(temp_row, temp_column)[CellSpan.ROW];       column += cellAtt.getSpan(temp_row, temp_column)[CellSpan.COLUMN];     }     int[] n = cellAtt.getSpan(row, column);     int index = 0;     int columnMargin = getColumnModel().getColumnMargin();     Rectangle cellFrame = new Rectangle();     int aCellHeight = rowHeight + rowMargin;     cellFrame.y = row * aCellHeight;     cellFrame.height = n[CellSpan.ROW] * aCellHeight;     Enumeration enumeration = getColumnModel().getColumns();     while (enumeration.hasMoreElements()) {       TableColumn aColumn = (TableColumn) enumeration.nextElement();       cellFrame.width = aColumn.getWidth() + columnMargin;       if (index == column)         break;       cellFrame.x += cellFrame.width;       index++;     }     for (int i = 0; i < n[CellSpan.COLUMN] - 1; i++) {       TableColumn aColumn = (TableColumn) enumeration.nextElement();       cellFrame.width += aColumn.getWidth() + columnMargin;     }     if (!includeSpacing) {       Dimension spacing = getIntercellSpacing();       cellFrame.setBounds(cellFrame.x + spacing.width / 2, cellFrame.y           + spacing.height / 2, cellFrame.width - spacing.width,           cellFrame.height - spacing.height);     }     return cellFrame;   }   private int[] rowColumnAtPoint(Point point) {     int[] retValue = { -1, -1 };     int row = point.y / (rowHeight + rowMargin);     if ((row < 0) || (getRowCount() <= row))       return retValue;     int column = getColumnModel().getColumnIndexAtX(point.x);     CellSpan cellAtt = (CellSpan) ((AttributiveCellTableModel) getModel())         .getCellAttribute();     if (cellAtt.isVisible(row, column)) {       retValue[CellSpan.COLUMN] = column;       retValue[CellSpan.ROW] = row;       return retValue;     }     retValue[CellSpan.COLUMN] = column         + cellAtt.getSpan(row, column)[CellSpan.COLUMN];     retValue[CellSpan.ROW] = row         + cellAtt.getSpan(row, column)[CellSpan.ROW];     return retValue;   }   public int rowAtPoint(Point point) {     return rowColumnAtPoint(point)[CellSpan.ROW];   }   public int columnAtPoint(Point point) {     return rowColumnAtPoint(point)[CellSpan.COLUMN];   }   public void columnSelectionChanged(ListSelectionEvent e) {     repaint();   }   public void valueChanged(ListSelectionEvent e) {     int firstIndex = e.getFirstIndex();     int lastIndex = e.getLastIndex();     if (firstIndex == -1 && lastIndex == -1) { // Selection cleared.       repaint();     }     Rectangle dirtyRegion = getCellRect(firstIndex, 0, false);     int numCoumns = getColumnCount();     int index = firstIndex;     for (int i = 0; i < numCoumns; i++) {       dirtyRegion.add(getCellRect(index, i, false));     }     index = lastIndex;     for (int i = 0; i < numCoumns; i++) {       dirtyRegion.add(getCellRect(index, i, false));     }     repaint(dirtyRegion.x, dirtyRegion.y, dirtyRegion.width,         dirtyRegion.height);   } } class MultiSpanCellTableUI extends BasicTableUI {   public void paint(Graphics g, JComponent c) {     Rectangle oldClipBounds = g.getClipBounds();     Rectangle clipBounds = new Rectangle(oldClipBounds);     int tableWidth = table.getColumnModel().getTotalColumnWidth();     clipBounds.width = Math.min(clipBounds.width, tableWidth);     g.setClip(clipBounds);     int firstIndex = table.rowAtPoint(new Point(0, clipBounds.y));     int lastIndex = table.getRowCount() - 1;     Rectangle rowRect = new Rectangle(0, 0, tableWidth, table         .getRowHeight()         + table.getRowMargin());     rowRect.y = firstIndex * rowRect.height;     for (int index = firstIndex; index <= lastIndex; index++) {       if (rowRect.intersects(clipBounds)) {         //System.out.println(); // debug         //System.out.print("" + index +": "); // row         paintRow(g, index);       }       rowRect.y += rowRect.height;     }     g.setClip(oldClipBounds);   }   private void paintRow(Graphics g, int row) {     Rectangle rect = g.getClipBounds();     boolean drawn = false;     AttributiveCellTableModel tableModel = (AttributiveCellTableModel) table         .getModel();     CellSpan cellAtt = (CellSpan) tableModel.getCellAttribute();     int numColumns = table.getColumnCount();     for (int column = 0; column < numColumns; column++) {       Rectangle cellRect = table.getCellRect(row, column, true);       int cellRow, cellColumn;       if (cellAtt.isVisible(row, column)) {         cellRow = row;         cellColumn = column;         //  System.out.print(" "+column+" "); // debug       } else {         cellRow = row + cellAtt.getSpan(row, column)[CellSpan.ROW];         cellColumn = column             + cellAtt.getSpan(row, column)[CellSpan.COLUMN];         //  System.out.print(" ("+column+")"); // debug       }       if (cellRect.intersects(rect)) {         drawn = true;         paintCell(g, cellRect, cellRow, cellColumn);       } else {         if (drawn)           break;       }     }   }   private void paintCell(Graphics g, Rectangle cellRect, int row, int column) {     int spacingHeight = table.getRowMargin();     int spacingWidth = table.getColumnModel().getColumnMargin();     Color c = g.getColor();     g.setColor(table.getGridColor());     g.drawRect(cellRect.x, cellRect.y, cellRect.width - 1,         cellRect.height - 1);     g.setColor(c);     cellRect.setBounds(cellRect.x + spacingWidth / 2, cellRect.y         + spacingHeight / 2, cellRect.width - spacingWidth,         cellRect.height - spacingHeight);     if (table.isEditing() && table.getEditingRow() == row         && table.getEditingColumn() == column) {       Component component = table.getEditorComponent();       component.setBounds(cellRect);       component.validate();     } else {       TableCellRenderer renderer = table.getCellRenderer(row, column);       Component component = table.prepareRenderer(renderer, row, column);       if (component.getParent() == null) {         rendererPane.add(component);       }       rendererPane.paintComponent(g, component, table, cellRect.x,           cellRect.y, cellRect.width, cellRect.height, true);     }   } } class AttributiveCellRenderer extends JLabel implements TableCellRenderer {   protected static Border noFocusBorder;   public AttributiveCellRenderer() {     noFocusBorder = new EmptyBorder(1, 2, 1, 2);     setOpaque(true);     setBorder(noFocusBorder);   }   public Component getTableCellRendererComponent(JTable table, Object value,       boolean isSelected, boolean hasFocus, int row, int column) {     Color foreground = null;     Color background = null;     Font font = null;     TableModel model = table.getModel();     if (model instanceof AttributiveCellTableModel) {       CellAttribute cellAtt = ((AttributiveCellTableModel) model)           .getCellAttribute();       if (cellAtt instanceof ColoredCell) {         foreground = ((ColoredCell) cellAtt).getForeground(row, column);         background = ((ColoredCell) cellAtt).getBackground(row, column);       }       if (cellAtt instanceof CellFont) {         font = ((CellFont) cellAtt).getFont(row, column);       }     }     if (isSelected) {       setForeground((foreground != null) ? foreground : table           .getSelectionForeground());       setBackground(table.getSelectionBackground());     } else {       setForeground((foreground != null) ? foreground : table           .getForeground());       setBackground((background != null) ? background : table           .getBackground());     }     setFont((font != null) ? font : table.getFont());     if (hasFocus) {       setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));       if (table.isCellEditable(row, column)) {         setForeground((foreground != null) ? foreground : UIManager             .getColor("Table.focusCellForeground"));         setBackground(UIManager.getColor("Table.focusCellBackground"));       }     } else {       setBorder(noFocusBorder);     }     setValue(value);     return this;   }   protected void setValue(Object value) {     setText((value == null) ? "" : value.toString());   } } class TextPreviewLabel extends JLabel {   private String sampleText = "  Sample Text  Sample Text  ";   boolean isForgroundSelection;   public TextPreviewLabel() {     this(Color.black, Color.white, true);   }   public TextPreviewLabel(Color fore, Color back, boolean isForgroundSelection) {     setOpaque(true);     setForeground(fore);     setBackground(back);     this.isForgroundSelection = isForgroundSelection;     setText(sampleText);   }   public void setForeground(Color col) {     if (isForgroundSelection) {       super.setForeground(col);     } else {       super.setBackground(col);     }   } } class ColorChooserDialog extends JDialog {   private Color initialColor;   private Color retColor;   private JColorChooser chooserPane;   public ColorChooserDialog(Component c, String title,       final JColorChooser chooserPane) {     super(JOptionPane.getFrameForComponent(c), title, true);     setResizable(false);     this.chooserPane = chooserPane;     String okString = UIManager.getString("ColorChooser.okText");     String cancelString = UIManager.getString("ColorChooser.cancelText");     String resetString = UIManager.getString("ColorChooser.resetText");     Container contentPane = getContentPane();     contentPane.setLayout(new BorderLayout());     contentPane.add(chooserPane, BorderLayout.CENTER);     JPanel buttonPane = new JPanel();     buttonPane.setLayout(new FlowLayout(FlowLayout.CENTER));     JButton okButton = new JButton(okString);     getRootPane().setDefaultButton(okButton);     okButton.addActionListener(new ActionListener() {       public void actionPerformed(ActionEvent e) {         retColor = chooserPane.getColor();         setVisible(false);       }     });     buttonPane.add(okButton);     JButton cancelButton = new JButton(cancelString);     cancelButton.addActionListener(new ActionListener() {       public void actionPerformed(ActionEvent e) {         retColor = null;         setVisible(false);       }     });     buttonPane.add(cancelButton);     JButton resetButton = new JButton(resetString);     resetButton.addActionListener(new ActionListener() {       public void actionPerformed(ActionEvent e) {         chooserPane.setColor(initialColor);       }     });     buttonPane.add(resetButton);     contentPane.add(buttonPane, BorderLayout.SOUTH);     pack();     setLocationRelativeTo(c);     addWindowListener(new WindowAdapter() {       public void windowClosing(WindowEvent e) {         setVisible(false);       }     });   }   public Color getColor() {     return retColor;   } } class TextColorChooser extends JColorChooser {   public TextColorChooser(Color target, Color reference,       boolean isForgroundSelection) {     super(target);     if (isForgroundSelection) {       setPreviewPanel(new TextPreviewLabel(target, reference,           isForgroundSelection));     } else {       setPreviewPanel(new TextPreviewLabel(reference, target,           isForgroundSelection));     }     updateUI();   }   public Color showDialog(Component component, String title) {     ColorChooserDialog dialog = new ColorChooserDialog(component, title,         this);     dialog.show();     Color col = dialog.getColor();     dialog.dispose();     return col;   } }