在JTable中切换按钮的颜色 [英] Switching color of Buttons in a JTable

查看:279
本文介绍了在JTable中切换按钮的颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在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 booleans)

The columnTypes 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 JCheckBoxs 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中切换按钮的颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆