Флажок только в одной ячейке JTable

Я хочу создать JTable с 2 столбцами, который выглядит как опрос. Итак, слева находятся вопросы, а справа пользователь может дать свои ответы. Но в одной строке справа должен быть флажок, чтобы пользователь мог ответить только да или нет.

Возможно ли это сделать с помощью JTable и как этого добиться?

С Уважением


person Jaran    schedule 21.02.2014    source источник
comment
Выбрать только один вариант? Это звучит как работа для JRadioButton вместо JCheckbox.   -  person anonymous    schedule 21.02.2014
comment
я попробовал это со столбцом JCheckboxes, я работаю, но я просто хочу, чтобы он был в одной ячейке Class [] columnTypes = new Class [] { Object.class, Object.class, Boolean.class }; открытый класс getColumnClass (int columnIndex) { return columnTypes [columnIndex]; };   -  person Jaran    schedule 21.02.2014


Ответы (2)


Вы указали в комментарии:

Я попробовал это со столбцом JCheckboxes, он работает, но я просто хочу, чтобы он был в одной ячейке.

Обратите внимание, что это требование немного сложно. Я думаю, вы можете переопределить getCellRenderer(int row, int column) и getCellEditor(int row, int column) запрашивают класс значения ячейки.

Таким образом, визуализатор/редактор ячеек будет JCheckbox, даже если строки таблицы отсортированы или столбцы таблицы переупорядочены.

Что-то вроде этого:

    JTable table = new JTable(model) {
        @Override
        public TableCellRenderer getCellRenderer(int row, int column) {
            if(getValueAt(row, column) instanceof Boolean) {
                return super.getDefaultRenderer(Boolean.class);
            } else {
                return super.getCellRenderer(row, column);
            }
        }

        @Override
        public TableCellEditor getCellEditor(int row, int column) {
            if(getValueAt(row, column) instanceof Boolean) {
                return super.getDefaultEditor(Boolean.class);
            } else {
                return super.getCellEditor(row, column);
            }
        }
    };

Пример

Вот полный пример для игры.

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class Demo {

    private void createAndShowGUI() { 

        DefaultTableModel model = new DefaultTableModel(new Object[]{"Column # 1", "Column # 2"}, 0);
        model.addRow(new Object[]{"Property # 1", "Value # 1"});
        model.addRow(new Object[]{"Property # 2", Boolean.TRUE});
        model.addRow(new Object[]{"Property # 3", "Value # 3"});

        JTable table = new JTable(model) {
            @Override
            public TableCellRenderer getCellRenderer(int row, int column) {
                if(getValueAt(row, column) instanceof Boolean) {
                    return super.getDefaultRenderer(Boolean.class);
                } else {
                    return super.getCellRenderer(row, column);
                }
            }

            @Override
            public TableCellEditor getCellEditor(int row, int column) {
                if(getValueAt(row, column) instanceof Boolean) {
                    return super.getDefaultEditor(Boolean.class);
                } else {
                    return super.getCellEditor(row, column);
                }
            }
        };
        table.setAutoCreateRowSorter(true);

        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(new JScrollPane(table));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {                
                new Demo().createAndShowGUI();
            }
        });
    }    
}

Скриншоты

введите здесь описание изображения

person dic19    schedule 21.02.2014

Вы можете реализовать интерфейс TableCellRenderer для создания пользовательского средства визуализации для ячеек с разными объектами, такими как JTextField и JLabel. Вы должны реализовать метод getTableCellRendererComponent, и из него вы можете вернуть компонент (например, JPanel или что вы хотите) с компонентами, которые вы хотите отобразить в ячейке. В таблице вы будете использовать JTable.setDefaultRenderer(), чтобы установить новый рендерер для пользовательского класса.

Если у вас есть только 2 значения, возможно, вы также можете установить для своих данных логические значения и позволить таблице отображать их как CheckBox (рендеринг по умолчанию).

Это код для второго метода, который больше похож на то, что вы хотите.

class CheckBoxModel extends AbstractTableModel{

        private final Object[][] rowData = {{"John" , true}, {"Mary", false}};
        final String columnNames[] = { "Student", "Approve" };

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

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

        @Override
        public Class<?> getColumnClass(final int columnIndex) {
            if (columnIndex == 1) {
                return Boolean.class; //renders column as a CheckBox
            }
            return super.getColumnClass(columnIndex);
        }

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

        @Override
        public void setValueAt(final Object aValue, final int rowIndex, final int columnIndex) {
            rowData[rowIndex][columnIndex] = aValue;
            fireTableCellUpdated(rowIndex, columnIndex);
        }

        @Override
        public boolean isCellEditable(final int rowIndex, final int columnIndex) {
            return true;    //makes all cells editable
        }
}

И тестовый класс:

public class TestTable {

    public static void main(String[] args) {
        final JFrame frame = new JFrame("Editable Color Table");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JTable table = new JTable(new CheckBoxModel());
        final JScrollPane scrollPane = new JScrollPane(table);
        frame.add(scrollPane, BorderLayout.CENTER);
        frame.setSize(500, 500);
        frame.setVisible(true);
    }
}
person Slimu    schedule 21.02.2014
comment
Можете ли вы привести пример? - person Jaran; 21.02.2014
comment
@Jaran Я опубликовал код, который делает то, что я предложил. - person Slimu; 21.02.2014
comment
ответ может быть очень простым, прочитайте официальный учебник Oracle - Как использовать таблицы - person mKorbel; 21.02.2014
comment
Кроме того, я немного запутался в первом абзаце: хотя он и правильный, он не имеет отношения к вопросу (как я понял) - person kleopatra; 21.02.2014
comment
@kleopatra Вы правы, я забыл об этом событии. Я обновил код. Первое решение, возможно, слишком много для того, чего хочет пользователь, но я позволю его, так как его можно использовать для более сложного отображения данных, например, для использования списка с более чем двумя параметрами. - person Slimu; 21.02.2014