Рендеринг JButton для получения поведения JCheckBox в JTable с использованием изображений не обновляет мою таблицу

Я визуализирую JButton с изображением на нем в основном для имитации поведения JCheckBox. Почему бы мне просто не позволить JTable отображать JCheckbox? Просто потому, что мне нужны флажки большего размера, и я не могу изменить их размер (насколько я знаю).

Итак, у меня есть собственный рендеринг и редактор ячеек таблицы. Оба отображают JButton и изображения флажков на них. Что я пытаюсь сделать, так это изменить изображение с проверенного изображения на непроверенное изображение (или наоборот) и обновить значение ячейки (логическое значение true или false). Однако по какой-то причине getCellEditorValue() не обновляет мою таблицу. Итак, как только я отпускаю мышь, их значение возвращается к исходному.

Любая помощь будет оценена! Большое спасибо!

    public class TableExample extends JFrame {

    JScrollPane pane;
    JPanel panel;
    JTable table;
    Object[][] data;
    MyTableModel tm;
    Renderer buttonColumn;

    public TableExample(Object[][] data) throws IOException {

        String[] columns = {"Column#1", "Column#2", "Column#3", "Column#4", "Column#5", "Column#6"};
        this.data = data;
        this.setPreferredSize(new Dimension(700, 500));
        this.setMinimumSize(new Dimension(700, 500));
        this.setMaximumSize(new Dimension(700, 500));
        tm = new MyTableModel(this.data, columns);
        this.table = new JTable(tm);
        this.table.setRowHeight(50);
        table.setDefaultRenderer(Boolean.class, new Renderer(this, table, 5));
        table.setDefaultEditor(Boolean.class, new Editor(this, table, 5));
        this.pane = new JScrollPane(this.table);
        this.add(this.pane);

    }

    /**
     *
     * TABLE MODEL
     */
    public class MyTableModel extends AbstractTableModel {

        private Object[][] data;
        private String[] columns;

        public MyTableModel(Object[][] data, String[] columns) {
            this.data = data;
            this.columns = columns;

        }

        public void setColumns(String[] columns1) {
            this.columns = columns1;
        }

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

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

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

        @Override
        public Class<?> getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

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

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

        public void setValueAt(String value, int row, int col) {

            if (DEBUG) {
                System.out.println("Setting value at " + row + "," + col
                        + " to " + value
                        + " (an instance of "
                        + value.getClass() + ")");
            }

            data[row][col] = value;
            fireTableCellUpdated(row, col);

            if (DEBUG) {
                System.out.println("New value of data:");
                printDebugData();
            }
        }

        private void printDebugData() {
            int numRows = getRowCount();
            int numCols = getColumnCount();

            for (int i = 0; i < numRows; i++) {
                System.out.print("    row " + i + ":");
                for (int j = 0; j < numCols; j++) {
                    System.out.print("  " + data[i][j]);
                }
                System.out.println();
            }
            System.out.println("--------------------------");
        }

    }
    /**
     *
     * CELL RENDERER
     */

    private class Renderer extends JButton implements TableCellRenderer {

        ImageIcon check;
        ImageIcon uncheck;
        boolean isChecked;

        public Renderer(JFrame frame, JTable table, int column) throws IOException {

            Image checkI = ImageIO.read(getClass().getResource("ukbuttonblue.png"));
            Image unCheckI = ImageIO.read(getClass().getResource("ukbuttonrev.png"));
            this.setBorderPainted(false);
            check = new ImageIcon(checkI);
            uncheck = new ImageIcon(unCheckI);

        }

        @Override
        public Component getTableCellRendererComponent(
                JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            this.isChecked = (boolean) value;
            if (isChecked) {
                setIcon(check);

            } else {
                setIcon(uncheck);

            }

            return this;
        }
    }

    /**
     *
     * CELL EDITOR
     */

    private class Editor extends AbstractCellEditor implements TableCellEditor, ActionListener {

        private JButton editButton;

        ImageIcon check;
        ImageIcon uncheck;
        boolean isChecked;

        public Editor(JFrame frame, JTable table, int column) throws IOException {

            editButton = new JButton();
            editButton.addActionListener(this);
            editButton.setBorderPainted(false);

            Image checkI = ImageIO.read(getClass().getResource("check.png"));
            Image unCheckI = ImageIO.read(getClass().getResource("uncheck.png"));
            check = new ImageIcon(checkI);
            uncheck = new ImageIcon(unCheckI);

        }

        @Override
        public Component getTableCellEditorComponent(
                JTable table, Object value, boolean isSelected, int row, int column) {

            this.isChecked = (boolean) value;
            if (this.isChecked) {
                editButton.setIcon(uncheck);
            } else {
                editButton.setIcon(check);
            }
            System.out.println("Edit " + isChecked);

            return editButton;

        }

        @Override
        public Object getCellEditorValue() {

            System.out.println("giden " + isChecked);
            return this.isChecked;

        }

        @Override
        public void actionPerformed(ActionEvent e) {

            if (this.isChecked) {
                this.isChecked = false;
            } else {
                this.isChecked = true;
            }

            fireEditingStopped();

        }
    }

    public static void main(String[] args) throws IOException {

        Object[][] data = {
            {"1", "Allan", "Smith", false, true, false},
            {"2", "Jerry", "Tucker", true, false, true}
        };

        TableExample app = new TableExample(data);
        app.setVisible(true);

    }
}

person pininfarina    schedule 14.07.2015    source источник


Ответы (1)


Поработав над этим некоторое время, я понял, что метод isCellEditable myTableModel не работает должным образом. Я просто переключился на DetafultTableModel, переопределяя класс столбца get.

    @Override
    public Class<?> getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

Одна из проблем с использованием DefaultTableModel заключается в том, что логический класс автоматически преобразуется в обычные JCheckBox. Итак, вместо использования логического класса я использовал класс Integer для имитации истинности и ложности просто с 0 и 1.

Вот окончательная программа для имитации поведения JCheckBox в JTable с использованием кнопки и изображения. Это дает большую гибкость для рендеринга различных изображений и при этом обеспечивает поведение JCheckBox. Итак, наслаждайтесь!

    public class TableExample extends JFrame {

    JScrollPane pane;
    JPanel panel;
    JTable table;
    Object[][] data;
    DefaultTableModel tm;
    Renderer buttonColumn;

    public TableExample(Object[][] data) throws IOException {

        String[] columns = {"Column#1", "Column#2", "Column#3", "Column#4", "Column#5", "Column#6"};
        this.data = data;
        this.setPreferredSize(new Dimension(700, 500));
        this.setMinimumSize(new Dimension(700, 500));
        this.setMaximumSize(new Dimension(700, 500));
        //tm = new DefaultTableModel(this.data, columns);
        DefaultTableModel tm = new DefaultTableModel(this.data, columns) {
            @Override
            public Class<?> getColumnClass(int c) {

                return getValueAt(0, c).getClass();
            }
        };

        this.table = new JTable(tm);
        this.table.setRowHeight(50);
        table.setDefaultRenderer(Integer.class, new Renderer(this, table, 5));
        table.setDefaultEditor(Integer.class, new Editor(this, table, 5));
        this.pane = new JScrollPane(this.table);
        this.add(this.pane);

    }

    /**
     *
     * RENDERER
     */
    private class Renderer extends JButton implements TableCellRenderer {

        ImageIcon check;
        ImageIcon uncheck;
        int isChecked;

        public Renderer(JFrame frame, JTable table, int column) throws IOException {

            Image checkI = ImageIO.read(getClass().getResource("check.png"));
            Image unCheckI = ImageIO.read(getClass().getResource("uncheck.png"));
            this.setBorderPainted(false);
            check = new ImageIcon(checkI);
            uncheck = new ImageIcon(unCheckI);

        }

        @Override
        public Component getTableCellRendererComponent(
                JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            this.isChecked = (int) value;
            if (isChecked == 1) {
                setIcon(check);

            } else {
                setIcon(uncheck);

            }

            return this;
        }
    }
    /**
     *
     * EDITOR
     */

    private class Editor extends AbstractCellEditor implements TableCellEditor, ActionListener {

        private JButton editButton;

        ImageIcon check;
        ImageIcon uncheck;
        int isChecked;

        public Editor(JFrame frame, JTable table, int column) throws IOException {

            editButton = new JButton();
            editButton.addActionListener(this);
            editButton.setBorderPainted(false);

            Image checkI = ImageIO.read(getClass().getResource("check.png"));
            Image unCheckI = ImageIO.read(getClass().getResource("uncheck.png"));
            check = new ImageIcon(checkI);
            uncheck = new ImageIcon(unCheckI);

        }

        @Override
        public Component getTableCellEditorComponent(
                JTable table, Object value, boolean isSelected, int row, int column) {

            this.isChecked = (int) value;
            if (this.isChecked == 1) {
                editButton.setIcon(uncheck);
                this.isChecked = 0;
            } else {
                editButton.setIcon(check);
                this.isChecked = 1;
            }

            return editButton;

        }

        @Override
        public Object getCellEditorValue() {

            return this.isChecked;

        }

        @Override
        public void actionPerformed(ActionEvent e) {

            fireEditingStopped();

        }

        public void updateValue() {

        }
    }

    public static void main(String[] args) throws IOException {

        Object[][] data = {
            {"1", "Allan", "Smith", false, false, 0},
            {"2", "Jerry", "Tucker", true, true, 1}
        };

        TableExample app = new TableExample(data);
        app.setVisible(true);

    }

}
person pininfarina    schedule 14.07.2015