问题描述
我想在JTable的单元格中实现一个点击颜色更改按钮。我已经的颜色是改变onClick,但我不能得到的是,如何背景颜色保持在按钮切换到的颜色。任何时候,我通过点击另一个单元格或表格内的按钮,再次白色松开焦点。我认为它与渲染器有关,也许你可以支持我。
signalTable = new JTable();
signalTable.setModel(new DefaultTableModel(
new Object [] [] {
{AAA,A_SIGNAL,null,null,null,null,null,null,null,null ,Example,Boolean.TRUE},
},
new String [] {
ID,Message Identifier,0,1,2 3,4,5,6,7,Description,
}
){
Class [] columnTypes = new Class [] {
String.class,String.class,JButton.class,JButton.class,JButton.class,JButton.class,JButton.class,JButton.class,JButton.class,JButton.class,String.class,Boolean .class
};
public class getColumnClass(int columnIndex){
return columnTypes [columnIndex];
}
});
TableColorRenderer renderer = new TableColorRenderer();
signalTable.getColumn(0)。setCellRenderer(renderer);
signalTable.getColumn(1)。setCellRenderer(renderer);
signalTable.getColumn(2)。setCellRenderer(renderer);
signalTable.getColumn(3)。setCellRenderer(renderer);
signalTable.getColumn(4)。setCellRenderer(renderer);
signalTable.getColumn(5)。setCellRenderer(renderer);
signalTable.getColumn(6)。setCellRenderer(renderer);
signalTable.getColumn(7)。setCellRenderer(renderer);
signalTable.getColumn(0)。setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn(1)。setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn(2)。setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn(3)。setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn(4)。setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn(5)。setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn(6)。setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn(7)。setCellEditor(new ButtonEditor(new JCheckBox()));
ButtonEditor.java:
public class ButtonEditor extends DefaultCellEditor
{
protected JButton button;
public ButtonEditor(JCheckBox checkBox)
{
super(checkBox);
button = new JButton();
button.setOpaque(true);
button.addActionListener(new ActionListener()
{
)public void actionPerformed(ActionEvent e)
{
button.setBackground(Color.GREEN);
button.repaint();
}
});
}
public Component getTableCellEditorComponent(JTable table,Object value,
boolean isSelected,int row,int column)
{
return button;
}
}
TableColorRenderer.java:
public class TableColorRenderer extends JLabel implements TableCellRenderer
{
@Override
public Component getTableCellRendererComponent(JTable table,对象值,boolean isSelected,boolean hasFocus,int row,int column)
{
return this;
}
你显然误解了编辑器和渲染器的角色。编辑器允许用户编辑单元格的状态,渲染器呈现单元格的状态。
他们通过使用 TableModel
。首先,请查看
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import javax.swing.AbstractCellEditor;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
public class示例{
public static void main(String [] args){
new Example();
}
public Example(){
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex){
ex.printStackTrace();
}
JFrame frame = new JFrame(Testing);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private final JTable signalTable;
public TestPane(){
signalTable = new JTable();
signalTable.setModel(new DefaultTableModel(
new Object [] [] {
{AAA,A_SIGNAL,false,false,false,false,false,false,false,false ,Example,Boolean.TRUE},},
new String [] {
ID,Message Identifier,0,1,2,3 4,5,6,7,Description,
}
){
Class [] columnTypes = new Class [] {
String.class,String.class,Boolean.class,Boolean.class,Boolean.class,Boolean.class,Boolean.class,Boolean.class,Boolean.class,Boolean.class,String.class,Boolean.class
};
public class getColumnClass(int columnIndex){
return columnTypes [columnIndex];
}
});
TableColorRenderer renderer = new TableColorRenderer();
signalTable.getColumn(0)。setCellRenderer(renderer);
signalTable.getColumn(1)。setCellRenderer(renderer);
signalTable.getColumn(2)。setCellRenderer(renderer);
signalTable.getColumn(3)。setCellRenderer(renderer);
signalTable.getColumn(4)。setCellRenderer(renderer);
signalTable.getColumn(5)。setCellRenderer(renderer);
signalTable.getColumn(6)。setCellRenderer(renderer);
signalTable.getColumn(7)。setCellRenderer(renderer);
signalTable.getColumn(0)。setCellEditor(new ButtonEditor());
signalTable.getColumn(1)。setCellEditor(new ButtonEditor());
signalTable.getColumn(2)。setCellEditor(new ButtonEditor());
signalTable.getColumn(3)。setCellEditor(new ButtonEditor());
signalTable.getColumn(4)。setCellEditor(new ButtonEditor());
signalTable.getColumn(5)。setCellEditor(new ButtonEditor());
signalTable.getColumn(6)setCellEditor(new ButtonEditor());
signalTable.getColumn(7)。setCellEditor(new ButtonEditor());
setLayout(new BorderLayout());
add(new JScrollPane(signalTable));
}
}
public class ButtonEditor extends AbstractCellEditor实现TableCellEditor {
private JLabel editor;
public ButtonEditor(){
editor = new JLabel();
editor.setBackground(Color.GREEN);
editor.addMouseListener(new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent e){
editor.setOpaque(!editor.isOpaque()) ;
stopCellEditing();
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table,Object value,boolean isSelected,int row,int column){
if(value instanceof Boolean){
boolean result =(boolean)value;
editor.setOpaque(!result);
}
return editor;
}
@Override
public Object getCellEditorValue(){
return editor.isOpaque();
}
@Override
public boolean isCellEditable(EventObject e){
return true;
}
}
public class TableColorRenderer extends JLabel implements TableCellRenderer {
public TableColorRenderer(){
setBackground 。绿色);
}
@Override
public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column){
if(value instanceof Boolean){
boolean result =(boolean)value;
setOpaque(result);
}
return this;
}
}
}
I'm trying to implement an on click color changing button inside a cell of a JTable. I did already that the color is changed onClick but what i don't get is, how the background color stays in the color the button is switched to. Anytime i loose the focus by clicking in another cell or inside the table the Button is again white. I think it has something to do with the renderers, maybe you can support me.
signalTable = new JTable();
signalTable.setModel(new DefaultTableModel(
new Object[][] {
{"AAA", "A_SIGNAL", null, null, null, null, null, null, null, null, "Example", Boolean.TRUE},
},
new String[] {
"ID", "Message Identifier", "0", "1", "2", "3", "4", "5", "6", "7", "Description", ""
}
) {
Class[] columnTypes = new Class[] {
String.class, String.class, JButton.class, JButton.class, JButton.class, JButton.class, JButton.class, JButton.class, JButton.class, JButton.class, String.class, Boolean.class
};
public Class getColumnClass(int columnIndex) {
return columnTypes[columnIndex];
}
});
TableColorRenderer renderer = new TableColorRenderer();
signalTable.getColumn("0").setCellRenderer(renderer);
signalTable.getColumn("1").setCellRenderer(renderer);
signalTable.getColumn("2").setCellRenderer(renderer);
signalTable.getColumn("3").setCellRenderer(renderer);
signalTable.getColumn("4").setCellRenderer(renderer);
signalTable.getColumn("5").setCellRenderer(renderer);
signalTable.getColumn("6").setCellRenderer(renderer);
signalTable.getColumn("7").setCellRenderer(renderer);
signalTable.getColumn("0").setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn("1").setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn("2").setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn("3").setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn("4").setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn("5").setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn("6").setCellEditor(new ButtonEditor(new JCheckBox()));
signalTable.getColumn("7").setCellEditor(new ButtonEditor(new JCheckBox()));
ButtonEditor.java:
public class ButtonEditor extends DefaultCellEditor
{
protected JButton button;
public ButtonEditor(JCheckBox checkBox)
{
super(checkBox);
button = new JButton();
button.setOpaque(true);
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
button.setBackground(Color.GREEN);
button.repaint();
}
});
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column)
{
return button;
}
}
TableColorRenderer.java:
public class TableColorRenderer extends JLabel implements TableCellRenderer
{
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
return this;
}
You're clearly misunderstanding the roles of the editor and the renderer. A editor allows a user to edit the state of a cell, a renderer renders the state of the cell.
They do this through the use of the TableModel
. Start by having a look at Concepts: Editors and Renderers and Using Other Editors for more details.
To start with the things you're doing wrong...
signalTable.setModel(new DefaultTableModel(
new Object[][] {
{"AAA", "A_SIGNAL", null, null, null, null, null, null, null, null, "Example", Boolean.TRUE},
},
new String[] {
"ID", "Message Identifier", "0", "1", "2", "3", "4", "5", "6", "7", "Description", ""
}
) {
Class[] columnTypes = new Class[] {
String.class, String.class, JButton.class, JButton.class, JButton.class, JButton.class, JButton.class, JButton.class, JButton.class, JButton.class, String.class, Boolean.class
};
public Class getColumnClass(int columnIndex) {
return columnTypes[columnIndex];
}
});
The cell values for the "color" cells should true
or false
(they can be any other "on"/"off" value you want, so long as the editor and renderer know how to deal with them, but for this example, I'm using boolean
s)
The columnType
s for these cells should also be Boolean.class
signalTable.setModel(new DefaultTableModel(
new Object[][]{
{"AAA", "A_SIGNAL", false, false, false, false, false, false, false, false, "Example", Boolean.TRUE},},
new String[]{
"ID", "Message Identifier", "0", "1", "2", "3", "4", "5", "6", "7", "Description", ""
}
) {
Class[] columnTypes = new Class[]{
String.class, String.class, Boolean.class, Boolean.class, Boolean.class, Boolean.class, Boolean.class, Boolean.class, Boolean.class, Boolean.class, String.class, Boolean.class
};
public Class getColumnClass(int columnIndex) {
return columnTypes[columnIndex];
}
});
So, now, if you did nothing else, you would have JCheckBox
s in those cells, but that's not what we want.
public class ButtonEditor extends DefaultCellEditor
{
protected JButton button;
public ButtonEditor(JCheckBox checkBox)
{
super(checkBox);
button = new JButton();
button.setOpaque(true);
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
button.setBackground(Color.GREEN);
button.repaint();
}
});
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column)
{
return button;
}
}
Here, you are ignoring the JCheckBox
which is passed to your editor and creating your own, but there are two problems with this. The DefaultCellEditor
is deriving the cells value from the JCheckBox
, not some other state (so it's always false
) and you never configure the button
to represent the current state of the cell when it's requested.
Because I don't want to deal with other components, I'm going to do something a little different.
public class ButtonEditor extends AbstractCellEditor implements TableCellEditor {
private JLabel editor;
public ButtonEditor() {
editor = new JLabel();
editor.setBackground(Color.GREEN);
editor.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
editor.setOpaque(!editor.isOpaque());
stopCellEditing();
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
if (value instanceof Boolean) {
boolean result = (boolean) value;
editor.setOpaque(!result);
}
return editor;
}
@Override
public Object getCellEditorValue() {
return editor.isOpaque();
}
@Override
public boolean isCellEditable(EventObject e) {
return true;
}
}
This is just a JLabel
which when clicked, will switch it's opaque state. We also use this state to determine the cell value when the editor is "stopped"
public class TableColorRenderer extends JLabel implements TableCellRenderer
{
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
return this;
}
}
Well, frankly, that's a bit useless, it never does anything with the value of cell
public class TableColorRenderer extends JLabel implements TableCellRenderer {
public TableColorRenderer() {
setBackground(Color.GREEN);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof Boolean) {
boolean result = (boolean) value;
setOpaque(result);
} else {
setOpaque(false);
}
return this;
}
}
Again, pretty simple. We check the value of the cell (as passed to us) and change the opaque
state accordingly
And because no one ever believes me, a runnable example
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import javax.swing.AbstractCellEditor;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
public class Example {
public static void main(String[] args) {
new Example();
}
public Example() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private final JTable signalTable;
public TestPane() {
signalTable = new JTable();
signalTable.setModel(new DefaultTableModel(
new Object[][]{
{"AAA", "A_SIGNAL", false, false, false, false, false, false, false, false, "Example", Boolean.TRUE},},
new String[]{
"ID", "Message Identifier", "0", "1", "2", "3", "4", "5", "6", "7", "Description", ""
}
) {
Class[] columnTypes = new Class[]{
String.class, String.class, Boolean.class, Boolean.class, Boolean.class, Boolean.class, Boolean.class, Boolean.class, Boolean.class, Boolean.class, String.class, Boolean.class
};
public Class getColumnClass(int columnIndex) {
return columnTypes[columnIndex];
}
});
TableColorRenderer renderer = new TableColorRenderer();
signalTable.getColumn("0").setCellRenderer(renderer);
signalTable.getColumn("1").setCellRenderer(renderer);
signalTable.getColumn("2").setCellRenderer(renderer);
signalTable.getColumn("3").setCellRenderer(renderer);
signalTable.getColumn("4").setCellRenderer(renderer);
signalTable.getColumn("5").setCellRenderer(renderer);
signalTable.getColumn("6").setCellRenderer(renderer);
signalTable.getColumn("7").setCellRenderer(renderer);
signalTable.getColumn("0").setCellEditor(new ButtonEditor());
signalTable.getColumn("1").setCellEditor(new ButtonEditor());
signalTable.getColumn("2").setCellEditor(new ButtonEditor());
signalTable.getColumn("3").setCellEditor(new ButtonEditor());
signalTable.getColumn("4").setCellEditor(new ButtonEditor());
signalTable.getColumn("5").setCellEditor(new ButtonEditor());
signalTable.getColumn("6").setCellEditor(new ButtonEditor());
signalTable.getColumn("7").setCellEditor(new ButtonEditor());
setLayout(new BorderLayout());
add(new JScrollPane(signalTable));
}
}
public class ButtonEditor extends AbstractCellEditor implements TableCellEditor {
private JLabel editor;
public ButtonEditor() {
editor = new JLabel();
editor.setBackground(Color.GREEN);
editor.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
editor.setOpaque(!editor.isOpaque());
stopCellEditing();
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
if (value instanceof Boolean) {
boolean result = (boolean) value;
editor.setOpaque(!result);
}
return editor;
}
@Override
public Object getCellEditorValue() {
return editor.isOpaque();
}
@Override
public boolean isCellEditable(EventObject e) {
return true;
}
}
public class TableColorRenderer extends JLabel implements TableCellRenderer {
public TableColorRenderer() {
setBackground(Color.GREEN);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof Boolean) {
boolean result = (boolean) value;
setOpaque(result);
}
return this;
}
}
}
这篇关于在JTable中切换按钮的颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!