Check Boxes not able to be Selected — They are Editable! Java Swing

落花浮王杯 提交于 2019-12-24 02:47:10

问题


I have read so many questions on this website concerning this problem and I cannot find why it is still not working.

The Problem:

I made a JTable to be displayed inside a JScrollPane. The JTable is constructed as follows:

table = new JTable(new DataTableModel());   

As you can see, I use a custom AbstractDataModel called DataTableModel. Now, when I display this the checkboxes appear, but they are not able to be selected. They are editable as you can see below. Here is the pertinent code in the DataTableModel class: (note that my column for check boxes is the first column, at index 0, and that my data in my array at this column is "null"). For some

public class DataTableModel extends AbstractTableModel
{
    private String[][] data;
    private String[] header =
    { "", "KB Name", "fpGUID" };

    public DataTableModel() throws SQLException
    {
        // ========= CONNECTS TO DB AND PULLS RESULTS ==========

        // GETS RESULTS SET CALLED "rs"

        // populate data array
        int counter = 0;
        while (rs.next())
        {
            //data[counter][0] = "sfsdfsdfs ";
            data[counter][1] = (String) rs.getObject(2);
            data[counter][2] = (String) rs.getObject(4);

            counter++;
        }
        // =====================================================

    }

@Override
public String getValueAt(int rowIndex, int columnIndex)
{
    return data[rowIndex][columnIndex];
}

public boolean isCellEditable(int row, int col)
{
    return col == 0;
}

public Class getColumnClass(int column)
{
    if (column == 0)
    {
        return Boolean.class;
    } else
    {
        return String.class;
    }
}

So, it seems my getColumnClass() method is fine, so what is the problem? Could it be something with my "data" which I store the data for the table. Here is the data array:


回答1:


There are a number of things that jump out...

  • (As has already begin pointed out) getValueAt appears to be declared wrong. It should be returning Object. Think about it for a second. Your expectation is that the first column will be boolean, so how can you return String from this method...which leads to...
  • Your data array is an array of String...where, again, the expectation is that the first value should be boolean. Now you can actually keep this, but you will need to translate the value to boolean from the getValueAt method and back again for the setValueAt method...which leads to...
  • You've not implemented setValueAt, so there is no way that the changes to the cell value can be stored
  • You're also not implementing getRowCount, which is required, getColumnCount, which is required and you should implement getColumnName, since you actually have some.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.sql.SQLException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;

public class TestTableModel02 {

    public static void main(String[] args) {
        new TestTableModel02();
    }

    public TestTableModel02() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(new JTable(new DataTableModel())));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class DataTableModel extends AbstractTableModel {

        private Object[][] data;
        private String[] header = {"", "KB Name", "fpGUID"};

        public DataTableModel() {//throws SQLException {
            // ========= CONNECTS TO DB AND PULLS RESULTS ==========

            // GETS RESULTS SET CALLED "rs"

            // populate data array
//            int counter = 0;
//            while (rs.next()) {
//                //data[counter][0] = "sfsdfsdfs ";
//                data[counter][1] = (String) rs.getObject(2);
//                data[counter][2] = (String) rs.getObject(4);
//
//                counter++;
//            }
            // =====================================================

            data = new Object[4][3];
            data[0] = new Object[]{false, "Help", "1234"};
            data[1] = new Object[]{false, "On fire", "5648"};
            data[2] = new Object[]{false, "Drowning", "9012"};
            data[3] = new Object[]{false, "Micky Mouse", "3456"};
        }

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

        @Override
        public boolean isCellEditable(int row, int col) {
            return col == 0;
        }

        @Override
        public Class getColumnClass(int column) {
            if (column == 0) {
                return Boolean.class;
            } else {
                return String.class;
            }
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            if (columnIndex == 0) {
                if (aValue instanceof Boolean) {
                    data[rowIndex][columnIndex] = (Boolean)aValue;
                    fireTableCellUpdated(rowIndex, columnIndex);
                }
            }
        }

        @Override
        public int getRowCount() {
            return data.length;
        }

        @Override
        public int getColumnCount() {
            return header.length;
        }

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

Now, there are ways you can get around the whole "first column must be boolean" issue, but to be frank, it's much less code to do it this way.

I would also, strongly, recommend that you take a look at SwingWorker and do all your data loading using it, otherwise you may find that your UI comes to a grinding halt while the data is begin loaded, which is generally rather unpleasant.

Take a look at...

  • Concurrency in Swing
  • How to use Tables

For more details



来源:https://stackoverflow.com/questions/17604459/check-boxes-not-able-to-be-selected-they-are-editable-java-swing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!