Java JTable cell中的多个jcheckbox

Java JTable cell中的多个jcheckbox,java,swing,jtable,jcheckbox,tablecelleditor,Java,Swing,Jtable,Jcheckbox,Tablecelleditor,我试着在一个JTable单元格中放入多个复选框。 我的TableModel如下所示: public class MyTableModel extends AbstractTableModel { CheckBoxPanel[][] data; int length; Object[] columns; public MyTableModel(Object[] o, int length){ columns = o; this.len

我试着在一个JTable单元格中放入多个复选框。 我的TableModel如下所示:

 public class MyTableModel extends AbstractTableModel {

   CheckBoxPanel[][] data;
   int length;
   Object[] columns;

    public MyTableModel(Object[] o, int length){
        columns = o;
        this.length = length;
        data = new CheckBoxPanel[o.length][length];
        for(int i=0;i<o.length;i++){
            for(int a=0;a<length;a++){
                data[i][a] = new CheckBoxPanel();
            }
        }

    }

    public int getRowCount() {
        return length;
    }

    public int getColumnCount() {
        return columns.length;
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        return data[rowIndex][columnIndex];
    }

    @Override
    public String getColumnName(int column) {
        return (String)columns[column];
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return true;
    }


    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return data[0][columnIndex].getClass();
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {

            data[rowIndex][columnIndex] = (CheckBoxPanel)aValue;
            fireTableCellUpdated(rowIndex, columnIndex);

    }
}class CheckBoxPanel extends JPanel
{

    JCheckBox jo = new JCheckBox("jo",false);
    JCheckBox ju = new JCheckBox("ju",false);
    JCheckBox no = new JCheckBox("no",false);
    JCheckBox nu = new JCheckBox("nu",false);
    JCheckBox[] boxes = {jo,ju,no,nu};
    ButtonGroup btnGrp = new ButtonGroup();
    CheckBoxPanel()
    {

        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
        jo.setBackground(Color.white);
        ju.setBackground(Color.white);
        no.setBackground(Color.white);
        nu.setBackground(Color.white);

        add(jo);
        add(ju);
        add(no);
        add(nu);
        setBackground(Color.white);
    }

    public void setSelectedIndex(int index)
    {
        for (int i=0;i<boxes.length;i++)
        {
            if(index ==i){
                if(boxes[i].isSelected()){
                    boxes[i].setSelected(false);
                    break;
                }else{
                    boxes[i].setSelected(true);
                    break;
                }
            }
        //    boxes[i].setSelected(i == index);
        }
    }

    public int getSelectedIndex()
    {
        int[] values = new int[4];
        for (int i=0; i<boxes.length; i++)
        {
            if (boxes[i].isSelected())
            {
                values[i]= 1;
            }else{
                values[i]= 0;
            }
        }
        return -1;
    }

    public JCheckBox[] getButtons()
    {
        return boxes;
    }
    public void updateData(Attribute att, boolean isSelected, JTable table){

        jo.setSelected(att.jo);
        ju.setSelected(att.ju);
        no.setSelected(att.no);
        nu.setSelected(att.nu);

        if (isSelected) {
              setBackground(table.getSelectionBackground());
            }else{
              setBackground(table.getBackground());
            }
    }
}

class CheckBoxRenderer implements TableCellRenderer
{
    private CheckBoxPanel panel;
    CheckBoxRenderer(CheckBoxPanel panel)
    {
       this.panel = panel;
    }

    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column)
    {
        if(value!=null){
            CheckBoxPanel oldpanel = (CheckBoxPanel) value;
            if(isSelected){

        panel.jo.setSelected(oldpanel.jo.isSelected());
        panel.ju.setSelected(oldpanel.ju.isSelected());
        panel.no.setSelected(oldpanel.no.isSelected());
        panel.nu.setSelected(oldpanel.nu.isSelected());
        return panel;
            }
            else{
                return oldpanel;
            }
        }
        else{
    return new CheckBoxPanel();
        }

    }
}

class CheckBoxEditor extends AbstractCellEditor
implements TableCellEditor
{
    CheckBoxPanel panel;

    public CheckBoxEditor()
    {
  //  panel = new CheckBoxPanel();
    }


    public Component getTableCellEditorComponent
            (JTable table, Object value,boolean isSelected, int row, int column)
    {
        if(value!=null){
            CheckBoxPanel oldpanel = (CheckBoxPanel) value;
            if(isSelected){

        panel.jo.setSelected(oldpanel.jo.isSelected());
        panel.ju.setSelected(oldpanel.ju.isSelected());
        panel.no.setSelected(oldpanel.no.isSelected());
        panel.nu.setSelected(oldpanel.nu.isSelected());
        return panel;
            }
            else{
                return oldpanel;
            }
        }
        else{
    return new CheckBoxPanel();
        }
    }

    public Object getCellEditorValue()
    {
        return null;
    }

}
公共类MyTableModel扩展了AbstractTableModel{
CheckBoxPanel[]数据;
整数长度;
对象[]列;
公共MyTableModel(对象[]o,整数长度){
列=o;
这个长度=长度;
数据=新的复选框面板[o.length][length];
对于(int i=0;i
但当我单击单元格中的复选框,然后切换到另一个单元格时
单元格,复选框的状态被重置。我认为
“setValueAt”和“getValueAt”可以处理这个问题,但它不起作用

比如说

(要禁用
table.setDefaultEditor(Status.class,
public table测试面板()

import javax.swing.*;
导入javax.swing.table.*;
导入java.util.Date;
导入java.util.Vector;
导入java.awt.*;
导入java.awt.event.*;
导入java.text.DateFormat;
导入java.text.simpleDataFormat;
导入javax.swing.UIManager.LookAndFeelInfo;
公共类TableTestPanel扩展了JPanel{
私有最终字符串[]列名称={“列表ID”、“到期日期”、“状态”、“创建日期”};
私有最终日期格式日期\格式=新的简化格式(“dd/MM/yyyy”);
私有静态最终长serialVersionUID=1L;
公共类状态面板扩展了JPanel{
私有静态最终长serialVersionUID=1L;
//私人JRadioButton单选按钮;
//结婚时的私人约会;
//专用JRadioButton选项;
私人JCheckBox-theSingleOption;
私人JCheckBox婚姻登记;
私人JCheckBox期权;
私人JCheckBox theHappyOption;
公共地位小组(){
超级(新网格布局(4,1));
set不透明(true);
ButtonGroup ButtonGroup=新建ButtonGroup();
singleoption=新的JCheckBox(“单个”);
设置不透明(假);
添加(单选项);
按钮组。添加(单选选项);
theMarriedOption=新JCheckBox(“已婚”);
theMarriedOption.set不透明(false);
添加(婚姻介绍);
按钮组。添加(婚姻介绍);
DevorcedOption=新的JCheckBox(“离婚”);
设置不透明(false);
添加(选项);
按钮组。添加(删除选项);
happyOption=新JCheckBox(“Happy”);
theHappyOption.set不透明(false);
添加(快乐选项);
按钮组。添加(快乐选项);
}
公共状态getStatus(){
如果(happyOption.isSelected()){
返回状态。快乐;
}else if(theMarriedOption.isSelected()){
返回状态。已婚;
}else if(devorcedoption.isSelected()){
返回状态。离婚;
}否则{
返回状态为.SINGLE;
}
}
公共无效设置状态(状态){
如果(status==status.HAPPY){
幸福选项。选择设置(真);
}else if(status==status.marred){
选择的婚姻记录设置(真);
}else if(状态==状态.离婚){
DevorDecedOption.setSelected(真);
}否则{
singleoption.setSelected(true);
}
}
}
静态类状态{
静态最终状态单一=新状态(“单一”);
静态最终状态已婚=新状态(“已婚”);
静态最终离婚状态=新状态(“离婚”);
静态最终状态快乐=新状态(“快乐”);
私有最终字符串myName;//仅用于调试
私有状态(字符串名称){
我的名字=名字;
}
@凌驾
公共字符串toString(){
返回我的名字;
}
}
私有类表格条目{
私有int instanceNumber;
私人Long-theId;
私有日期-扩张日期;
私人身份状态;
创建日期的私人日期;
公共表格条目(){
instanceNumber++;
theId=新长(instanceNumber);
expirationdate=新日期();
状态=Status.SINGLE;
创建日期=新日期();
}
公共表条目(长anId、日期anExpirationDate、状态Status、日期aCreationDate){
theId=anId;
expirationdate=expirationdate;
状态=无状态;
创建日期=创建日期;
}
公共长getId(){
返回theId;
}
公共日期getExpirationDate(){
返回ExpirationDate;
}
公共状态getStatus(){
返回状态;
}
公开日期getCreationDate(){
返回创建日期;
}
公共无效设置ID(长anId){
theId=anId;
}
公共作废设置过期日期(日期anExpirationDate){
expirationdate=expirationdate;
}
公共无效设置状态(状态设置状态){
状态=无状态;
}
公共无效设置创建日期(创建日期){
创建日期=创建日期;
}
}
公共类MyTableModel扩展了AbstractTableModel{
私有静态最终长serialVersionUID=1L;
私有向量入口;
公共MyTableModel(){
entries=新向量();
}
@抑制警告(“未选中”)
公共作废添加(表格条目输入){
int index=entries.size();
输入。添加(输入);
fireTableRowsInserted(索引,索引);
}
公共空间移除(INTA)
import javax.swing.*;
import javax.swing.table.*;
import java.util.Date;
import java.util.Vector;
import java.awt.*;
import java.awt.event.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.swing.UIManager.LookAndFeelInfo;

public class TableTestPanel extends JPanel {

    private final String[] COLUMN_NAMES = {"List ID", "Expiration Date", "Status", "Date Created"};
    private final DateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy");
    private static final long serialVersionUID = 1L;

    public class StatusPanel extends JPanel {

        private static final long serialVersionUID = 1L;
        //private JRadioButton theSingleOption;
        //private JRadioButton theMarriedOption;
        //private JRadioButton theDivorcedOption;

        private JCheckBox theSingleOption;
        private JCheckBox theMarriedOption;
        private JCheckBox theDivorcedOption;
        private JCheckBox theHappyOption;

        public StatusPanel() {
            super(new GridLayout(4, 1));
            setOpaque(true);
            ButtonGroup buttonGroup = new ButtonGroup();
            theSingleOption = new JCheckBox("Single");
            theSingleOption.setOpaque(false);
            add(theSingleOption);
            buttonGroup.add(theSingleOption);
            theMarriedOption = new JCheckBox("Married");
            theMarriedOption.setOpaque(false);
            add(theMarriedOption);
            buttonGroup.add(theMarriedOption);
            theDivorcedOption = new JCheckBox("Divorced");
            theDivorcedOption.setOpaque(false);
            add(theDivorcedOption);
            buttonGroup.add(theDivorcedOption);
            theHappyOption = new JCheckBox("Happy");
            theHappyOption.setOpaque(false);
            add(theHappyOption);
            buttonGroup.add(theHappyOption);
        }

        public Status getStatus() {
            if (theHappyOption.isSelected()) {
                return Status.HAPPY;
            } else if (theMarriedOption.isSelected()) {
                return Status.MARRIED;
            } else if (theDivorcedOption.isSelected()) {
                return Status.DIVORCED;
            } else {
                return Status.SINGLE;
            }
        }

        public void setStatus(Status status) {
            if (status == Status.HAPPY) {
                theHappyOption.setSelected(true);
            } else if (status == Status.MARRIED) {
                theMarriedOption.setSelected(true);
            } else if (status == Status.DIVORCED) {
                theDivorcedOption.setSelected(true);
            } else {
                theSingleOption.setSelected(true);
            }
        }
    }

    static class Status {

        static final Status SINGLE = new Status("Single");
        static final Status MARRIED = new Status("Married");
        static final Status DIVORCED = new Status("Divorced");
        static final Status HAPPY = new Status("Happy");
        private final String myName; // for debug only

        private Status(String name) {
            myName = name;
        }

        @Override
        public String toString() {
            return myName;
        }
    }

    private class TableEntry {

        private int instanceNumber;
        private Long theId;
        private Date theExpirationDate;
        private Status theStatus;
        private Date theCreationDate;

        public TableEntry() {
            instanceNumber++;
            theId = new Long(instanceNumber);
            theExpirationDate = new Date();
            theStatus = Status.SINGLE;
            theCreationDate = new Date();
        }

        public TableEntry(Long anId, Date anExpirationDate, Status aStatus, Date aCreationDate) {
            theId = anId;
            theExpirationDate = anExpirationDate;
            theStatus = aStatus;
            theCreationDate = aCreationDate;
        }

        public Long getId() {
            return theId;
        }

        public Date getExpirationDate() {
            return theExpirationDate;
        }

        public Status getStatus() {
            return theStatus;
        }

        public Date getCreationDate() {
            return theCreationDate;
        }

        public void setId(Long anId) {
            theId = anId;
        }

        public void setExpirationDate(Date anExpirationDate) {
            theExpirationDate = anExpirationDate;
        }

        public void setStatus(Status aStatus) {
            theStatus = aStatus;
        }

        public void setCreationDate(Date aCreationDate) {
            theCreationDate = aCreationDate;
        }
    }

    public class MyTableModel extends AbstractTableModel {

        private static final long serialVersionUID = 1L;
        private Vector<Object> theEntries;

        public MyTableModel() {
            theEntries = new Vector<Object>();
        }

        @SuppressWarnings("unchecked")
        public void add(TableEntry anEntry) {
            int index = theEntries.size();
            theEntries.add(anEntry);
            fireTableRowsInserted(index, index);
        }

        public void remove(int aRowIndex) {
            if (aRowIndex < 0 || aRowIndex >= theEntries.size()) {
                return;
            }
            theEntries.removeElementAt(aRowIndex);
            fireTableRowsDeleted(aRowIndex, aRowIndex);

        }

        @Override
        public int getRowCount() {
            return theEntries.size();
        }

        @Override
        public String getColumnName(int column) {
            return COLUMN_NAMES[column];
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            switch (columnIndex) {
                case 0:
                    return Long.class;
                case 1:
                    return Date.class;
                case 2:
                    return Status.class;
                case 3:
                    return Date.class;
            }
            return Object.class;
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            TableEntry entry = (TableEntry) theEntries.elementAt(rowIndex);
            switch (columnIndex) {
                case 0:
                    try {
                        entry.setId(new Long(Long.parseLong(aValue.toString())));
                    } catch (NumberFormatException nfe) {
                        return;
                    }
                    break;
                case 1:
                    entry.setExpirationDate((Date) aValue);
                    break;
                case 2:
                    entry.setStatus((Status) aValue);
                    break;
                case 3:
                    entry.setCreationDate((Date) aValue);
                    break;
                default:
                    return;
            }
            fireTableCellUpdated(rowIndex, columnIndex);
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return true;
        }

        @Override
        public int getColumnCount() {
            return 4;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            TableEntry entry = (TableEntry) theEntries.elementAt(rowIndex);
            switch (columnIndex) {
                case 0:
                    return entry.getId();
                case 1:
                    return entry.getExpirationDate();
                case 2:
                    return entry.getStatus();
                case 3:
                    return entry.getCreationDate();
            }
            return null;
        }
    }

    public class DateRenderer extends DefaultTableCellRenderer {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            if (!(value instanceof Date)) {
                return this;
            }
            setText(DATE_FORMAT.format((Date) value));
            return this;
        }
    }

    public class DateEditor extends AbstractCellEditor implements TableCellEditor {

        private static final long serialVersionUID = 1L;
        private JSpinner theSpinner;
        private Object value;

        DateEditor() {
            theSpinner = new JSpinner(new SpinnerDateModel());
            theSpinner.setOpaque(true);
            theSpinner.setEditor(new JSpinner.DateEditor(theSpinner, "dd/MM/yyyy"));
        }

        @Override
        public Object getCellEditorValue() {
            return theSpinner.getValue();
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            theSpinner.setValue(value);
            if (isSelected) {
                theSpinner.setBackground(table.getSelectionBackground());
            } else {
                theSpinner.setBackground(table.getBackground());
            }
            return theSpinner;
        }
    }

    public class StatusEditor extends AbstractCellEditor implements TableCellEditor {

        private static final long serialVersionUID = 1L;
        private StatusPanel theStatusPanel;

        StatusEditor() {
            theStatusPanel = new StatusPanel();
        }

        @Override
        public Object getCellEditorValue() {
            return theStatusPanel.getStatus();
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            theStatusPanel.setStatus((Status) value);
            if (isSelected) {
                theStatusPanel.setBackground(table.getSelectionBackground());
            } else {
                theStatusPanel.setBackground(table.getBackground());
            }
            return theStatusPanel;
        }
    }

    public class StatusRenderer extends StatusPanel implements TableCellRenderer {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            setStatus((Status) value);
            if (isSelected) {
                setBackground(table.getSelectionBackground());
            } else {
                setBackground(table.getBackground());
            }
            return this;
        }
    }
    private MyTableModel theTableModel;
    private JTable theTable;

    public TableTestPanel() {
        super(new BorderLayout(0, 5));
        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        theTableModel = new MyTableModel();
        theTable = new JTable(theTableModel);
        theTable.setDefaultEditor(Date.class, new DateEditor());
        theTable.setDefaultRenderer(Date.class, new DateRenderer());
        theTable.setDefaultEditor(Status.class, new StatusEditor());
        theTable.setDefaultRenderer(Status.class, new StatusRenderer());
// comment out the two preceding lines and uncomment the following one 
// if you want a more standard editor
        theTable.setDefaultEditor(Status.class, new DefaultCellEditor(
                new JComboBox(new Status[]{Status.SINGLE, Status.MARRIED, Status.DIVORCED, Status.HAPPY})));
        add(new JScrollPane(theTable), BorderLayout.CENTER);
        JToolBar toolBar = new JToolBar();
        toolBar.setFloatable(false);
        toolBar.add(new AbstractAction("Add new") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                theTableModel.add(new TableEntry());
                packTable();
            }
        });
        toolBar.add(new AbstractAction("Remove") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                theTableModel.remove(theTable.getSelectedRow());
            }
        });
        add(toolBar, BorderLayout.NORTH);
    }

    private void packTable() {
        TableColumnModel columnModel = theTable.getColumnModel();
        int columnCount = theTable.getColumnCount();
        int rowCount = theTable.getRowCount();
        int[][] preferredHeights = new int[columnCount][rowCount];
        TableCellRenderer renderer;
        Component comp;
        for (int col = 0; col < columnCount; col++) {
            renderer = columnModel.getColumn(col).getCellRenderer();
            if (renderer == null) {
                renderer = theTable.getDefaultRenderer(theTableModel.getColumnClass(col));
            }
            for (int row = 0; row < rowCount; row++) {
                comp = renderer.getTableCellRendererComponent(theTable, theTableModel.getValueAt(row, col), false, false, row, col);
                preferredHeights[col][row] = (int) comp.getPreferredSize().getHeight();
            }
        }
        for (int row = 0; row < rowCount; row++) {
            int pref = 0;
            for (int col = 0; col < columnCount; col++) {
                pref = Math.max(pref, preferredHeights[col][row]);
            }
            theTable.setRowHeight(row, pref);
        }
    }

    public static void main(String[] args) {
        /*try {
            // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if (info.getName().equals("Nimbus")) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }*/
        final JFrame frame = new JFrame("TestRadioButtonRenderer");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(new TableTestPanel());
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                //frame.setSize(400, 300);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}