// 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.GridLayout;
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.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JColorChooser;
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.TableModelEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
/**
* @version 1.0 11/22/98
*/
public class ColoredCellTableExample extends JFrame {
private JTable table;
private ColoredCell cellAtt;
public ColoredCellTableExample() {
super("Colored Cell Example");
AttributiveCellTableModel ml = new AttributiveCellTableModel(10, 6);
cellAtt = (ColoredCell) ml.getCellAttribute();
table = new JTable(ml);
table.setCellSelectionEnabled(true);
table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
table.setDefaultRenderer(Object.class, new AttributiveCellRenderer());
JScrollPane scroll = new JScrollPane(table);
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();
p_buttons.setLayout(new GridLayout(2, 1));
p_buttons.add(b_fore);
p_buttons.add(b_back);
Box box = new Box(BoxLayout.X_AXIS);
box.add(scroll);
box.add(new JSeparator(SwingConstants.HORIZONTAL));
box.add(p_buttons);
getContentPane().add(box);
setSize(400, 200);
setVisible(true);
}
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(ColoredCellTableExample.this, title);
if (color != null) {
if (isForeground) {
cellAtt.setForeground(color, rows, columns);
} else {
cellAtt.setBackground(color, rows, columns);
}
table.clearSelection();
table.revalidate();
table.repaint();
}
}
public static void main(String[] args) {
ColoredCellTableExample frame = new ColoredCellTableExample();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
/*
* (swing1.1beta3)
*
*/
/**
* @version 1.0 11/22/98
*/
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 eeration = dataVector.elements();
while (eeration.hasMoreElements()) {
Object value;
if ((columnData != null) && (index < columnData.size()))
value = columnData.elementAt(index);
else
value = null;
((Vector) eeration.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); }
*/
}
/**
* @version 1.0 11/22/98
*/
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;
}
}
}
}
/**
* @version 1.0 11/22/98
*/
/*
* (swing1.1beta3)
*
*/
/**
* @version 1.0 11/22/98
*/
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);
}
/**
* @version 1.0 11/22/98
*/
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());
}
}
/**
* @version 1.0 11/22/98
*/
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;
}
}
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);
}