Флажок только в одной ячейке JTable
Я хочу создать JTable
с 2 столбцами, который выглядит как опрос. Слева находятся вопросы, а справа пользователь может дать свои ответы. Но в одной строке должен быть флажок с правой стороны, чтобы пользователь мог ответить только да или нет.
Можно ли это сделать с JTable
и как мне этого добиться?
С уважением
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();
}
});
}
}
Скриншоты
Вы можете реализовать интерфейс 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);
}
}