У меня есть резюме кодов и ответов ...
Я пытаюсь перекрасить JPanel
(что содержит другие объекты), содержащиеся в JTable
ячейках.
Чтобы следовать этим ответам https://stackoverflow.com/a/28368503/1410223
ПОЛНЫЙ КОД ИСТОЧНИКА
public class JTableSynthTest extends JFrame {
String[] hdrsObjects = new String[]{
"Name", "Last Name", "Sport", " Level"
};
Object[][] matrixInfo = {
{new Info("Kathy"), new Info("Smith"), new Info("Snowboarding"), new Info("1")},
{new Info("John"), new Info("Doe"), new Info("Rowing"), new Info("0")},
{new Info("Sue"), new Info("Black"), new Info("Knitting"), new Info("3")},
{new Info("Jane"), new Info("White"), new Info("Speed reading"), new Info("0")},
{new Info("Joe"), new Info("Brown"), new Info("Pool"), new Info("2")}
};
Object[][] objectMatrix = {
{"Kathy", "Smith", "Snowboarding", "1"},
{"John", "Doe", "Rowing", "0"},
{"Sue", "Black", "Knitting", "3"},
{"Jane", "White", "Speed reading", "0"},
{"Joe", "Brown", "Pool", "2"}
};
public JTableSynthTest() {
List<Point> listSelectedCell = new ArrayList<>();
//JTable table = new JTable(new DefaultTableModel(objectMatrix, hdrsObjects)) {
JTable table = new JTable(new TableModel(matrixInfo, hdrsObjects)) {
@Override
public void updateUI() {
super.updateUI();
setIntercellSpacing(new Dimension(1 /*gapWidth*/, 2/*gapHeight*/));
setGridColor(Color.DARK_GRAY);
setShowHorizontalLines(true);
setShowVerticalLines(true);
getTableHeader().setUI(null);
CellRenderer myCellRenderer = new CellRenderer();
CellEditor myCellEditor = new CellEditor();
//setDefaultRenderer(Object.class, myCellRenderer);
for (int idx = 0; idx < getColumnModel().getColumnCount(); idx++) {
TableColumn tc = getColumnModel().getColumn(idx);
myCellRenderer.setHorizontalAlignment(SwingConstants.CENTER);
tc.setCellRenderer(myCellRenderer);
tc.setCellEditor(myCellEditor);
tc.setPreferredWidth(new Panel().getWidth());
}
setRowHeight(10 + getRowHeight() + getIntercellSpacing().height);
}
@Override
public boolean isCellSelected(int row, int column) {
return listSelectedCell.contains(new Point(row, column));
}
};
JButton button = new JButton("Selected Cells");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
listSelectedCell.clear();
int rows = table.getRowCount();
int cols = table.getColumnCount();
int row = new Random().nextInt(rows);
int col = new Random().nextInt(cols);
Point point = new Point(row, col);
if (!listSelectedCell.contains(point)) {
listSelectedCell.add(point);
}
//((TableModel) table.getModel()).fireTableDataChanged();
//((DefaultTableModel) table.getModel()).fireTableDataChanged();
table.repaint();
}
});
JScrollPane pane = new JScrollPane(table);
JPanel lower = new JPanel();
lower.setLayout(new BoxLayout(lower, BoxLayout.X_AXIS));
lower.add(button);
//lower.add(textPane);
JPanel main = new JPanel();
main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS));
main.add(pane);
main.add(lower);
this.add(main);
this.setSize(800, 600);
this.setVisible(true);
}
public static void main(String[] args) {
try {
/*
javax.swing.UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
javax.swing.UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
javax.swing.UIManager.setLookAndFeel("com.apple.laf.AquaLookAndFeel");
javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel");
*/
javax.swing.UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception ex) {
ex.printStackTrace();
}
new JTableSynthTest();
}
private class Panel extends JPanel {
private final JTextPane textPane = new JTextPane();
public Panel() {
add(textPane, BorderLayout.NORTH);
int minWidth = (new JTextPane()).getMinimumSize().width;
int minHeight = (new JTextPane()).getMinimumSize().height;
textPane.setMinimumSize(new Dimension(minWidth, minHeight));
Dimension d = getMinimumSize();
setSize(d);
setPreferredSize(d);
setMaximumSize(d);
}
public Panel(Info info) {
this();
setData(info);
}
public JTextPane getTextPane() {
return textPane;
}
public Info getData() {
return new Info(textPane.getText()
);
}
public void setData(Info info) {
textPane.setText(info.getData());
}
public void setSelected(boolean isSelected, JTable table, int row) {
/*
if (isSelected) {
this.setBackground(table.getSelectionBackground());
} else {
this.setBackground(table.getBackground());
}
String laf = UIManager.getLookAndFeel().getName().toLowerCase();
if (laf.contains("nimbus")) {
NimbusLookAndFeel nimbusLAF = new NimbusLookAndFeel();
if (isSelected) {
this.getTextPane().setBackground(nimbusLAF.getDerivedColor("Table[Enabled+Selected].textBackground", 0.0f, 0.0f, 0.0f, 0, false));
this.getTextPane().setForeground(nimbusLAF.getDerivedColor("Table[Enabled+Selected].textForeground", 0.0f, 0.0f, 0.0f, 0, false));
} else {
if (row % 2 == 0) {
this.getTextPane().setBackground(nimbusLAF.getDerivedColor("Table.background", 0.0f, 0.0f, 0.0f, 0, false));
} else {
this.getTextPane().setBackground(nimbusLAF.getDerivedColor("Table.alternateRowColor", 0.0f, 0.0f, 0.0f, 0, false));
}
this.getTextPane().setForeground(nimbusLAF.getDerivedColor("Table.foreground", 0.0f, 0.0f, 0.0f, 0, false));
}
}
*/
}
}
private class Info {
private String data;
public Info(String data) {
this.data = data;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
private class CellRenderer extends DefaultTableCellRenderer implements TableCellRenderer {
private final Panel panel = new Panel();
//javax.swing.table.TableCellRenderer
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof Info) {
panel.setData((Info) value);
String laf = UIManager.getLookAndFeel().getName().toLowerCase();
Color background;
Color foreground;
if (laf.contains("nimbus")) {
NimbusLookAndFeel nimbusLAF = new NimbusLookAndFeel();
if (isSelected) {
background = (nimbusLAF.getDerivedColor("nimbusSelectionBackground", 0.0f, 0.0f, 0.0f, 0, false));
foreground = (nimbusLAF.getDerivedColor("nimbusLightBackground", 0.0f, 0.0f, 0.0f, 0, false));
} else {
if (row % 2 == 0) {
background = nimbusLAF.getDerivedColor("Table.background", 0.0f, 0.0f, 0.0f, 0, false);
} else {
background = nimbusLAF.getDerivedColor("Table.alternateRowColor", 0.0f, 0.0f, 0.0f, 0, false);
}
foreground = nimbusLAF.getDerivedColor("Table.foreground", 0.0f, 0.0f, 0.0f, 0, false);
}
} else {
if (isSelected) {
background = (Color) UIManager.get("Table.selectionBackground");
foreground = (Color) UIManager.get("Table.selectionForeground");
} else {
background = (Color) UIManager.get("Table.background");
foreground = (Color) UIManager.get("Table.foreground");
}
}
background = new Color(background.getRed(), background.getGreen(), background.getBlue());
foreground = new Color(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
System.out.println("background:" + background);
System.out.println("foreground:" + foreground);
panel.getTextPane().setBackground(background/*Color.CYAN*/);
panel.getTextPane().setForeground(foreground/*Color.PINK*/);
return panel;
}
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
private class CellEditor extends AbstractCellEditor implements TableCellEditor {
protected Object output;
private final Panel panel = new Panel();
@Override //javax.swing.CellEditor
public Object getCellEditorValue() {
//Returns the value contained in the editor.
if (output instanceof Panel) {
return panel.getData();
}
return null;
}
@Override //javax.swing.table.TableCellEditor
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
//Sets an initial value for the editor.
if (value instanceof Info) {
panel.setData((Info) value);
panel.setSelected(true, table, row);
output = panel;
return panel;
}
return null;
}
}
private class TableModel extends AbstractTableModel {
private Object[][] data;
private Object[] columns;
public TableModel(Object[][] data, Object[] columns) {
this.data = data;
this.columns = columns;
}
//javax.swing.table.TableModel
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
if (data != null) {
if (data.length > 0) {
return data[rowIndex][columnIndex];
}
}
return null;
}
//javax.swing.table.TableModel
@Override
public int getColumnCount() {
return ((columns == null) ? 0 : columns.length);
}
//javax.swing.table.TableModel
@Override
public int getRowCount() {
return ((data == null) ? 0 : data.length);
}
//javax.swing.table.AbstractTableModel
@Override
public Class getColumnClass(int columnIndex) {
if (data != null) {
if (data.length > 0) {
if (data[0][columnIndex] instanceof Panel) {
return Panel.class;
}
return Object.class;
}
}
return Object.class;
}
//javax.swing.table.AbstractTableModel
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
if (data != null) {
if (data.length > 0) {
if (data[0][columnIndex] instanceof Panel) {
return true;
}
return true;
}
}
return false;
}
//javax.swing.table.AbstractTableModel
@Override
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
//javax.swing.table.AbstractTableModel
@Override
public String getColumnName(int columnIndex) {
return (String) columns[columnIndex];
}
}
}
Мой код работает для Look And Feels:
com.apple.laf.AquaLookAndFeel
javax.swing.plaf.metal.MetalLookAndFeel
com.sun.java.swing.plaf.motif.MotifLookAndFeel
com.sun.java.swing.plaf.windows.WindowsLookAndFeel
com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel
Но не удается
javax.swing.plaf.nimbus.NimbusLookAndFeel
// РАБОТА НЕ БУДЕТ ПРЕДОСТАВЛЯТЬСЯ! com.sun.java.swing.plaf.gtk.GTKLookAndFeel
// РАБОТАЕТ НЕ РАБОТАЕТ!
Даже с этим Примером , меняющим свой метод main
.
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception ex) {
Logger.getLogger(JTableTest.class.getName()).log(Level.SEVERE, null, ex);
}
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new JTableTest());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
ПРИМЕЧАНИЕ:
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java
GTKLookAndFeel extends SynthLookAndFeel
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java
NimbusLookAndFeel extends SynthLookAndFeel
Как исправить это поведение (НЕ перекрашивать, когда JTable выбранных / невыбранных ячеек, когда Nimbus
, Gtk
Look And Feels)?