我正在尝试禁用 JTable 中除 1 列之外的所有行的选择。(示例屏幕截图中的图层列)。在其他列中,我有我希望用户能够与之交互的微调器和复选框,而不会影响图层列中的选择。
我最初的尝试是在任何选定的行出现时存储它们,然后在选择 A 列之外的单元格时恢复到该组选定的行。它有点工作,但问题是它在选择另一个单元格时“闪烁”,然后再将其恢复。如何防止“闪退”?
这是我设置的一个示例来说明问题:
public class TableTest {
static int[] selectedRows = new int[0];
final static String[] columns = new String[] { "Layer", "Enabled", "Read Only", "Storage" };
final static DefaultTableModel model = new DefaultTableModel(new Vector(), new Vector(Arrays.asList(columns))) {
@Override
public void setValueAt(Object obj, int row, int col) {
if (obj instanceof Boolean || obj instanceof Integer) {
Object localObject = super.getValueAt(row, col);
if (localObject instanceof Integer) {
Integer val = (Integer) localObject;
((SpinnerCell) obj).getSpinner().setValue(val);
} else if (localObject instanceof Boolean) {
Boolean val = (Boolean) localObject;
((CheckboxCell) obj).getCheckBox().setEnabled(val);
}
} else {
super.setValueAt(obj, row, col);
}
}
@Override
public boolean isCellEditable(int rowIndex, int colIndex) {
return colIndex != 0;
}
};
public static void main(String[] a) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JTable table = new JTable(model) {
@Override
public TableCellRenderer getCellRenderer(final int rowIndex, int colIndex) {
int reaRowlIndex = convertRowIndexToModel(rowIndex);
int realColumnIndex = convertColumnIndexToModel(colIndex);
Object o = model.getValueAt(reaRowlIndex, realColumnIndex);
if (o instanceof TableCellRenderer) {
return (TableCellRenderer) o;
} else {
return super.getCellRenderer(reaRowlIndex, realColumnIndex);
}
}
//
@Override
public TableCellEditor getCellEditor(final int rowIndex, int colIndex) {
int reaRowlIndex = convertRowIndexToModel(rowIndex);
int realColumnIndex = convertColumnIndexToModel(colIndex);
Object o = model.getValueAt(reaRowlIndex, realColumnIndex);
if (o instanceof TableCellEditor) {
return (TableCellEditor) o;
} else {
return super.getCellEditor(reaRowlIndex, realColumnIndex);
}
}
};
table.getTableHeader().setReorderingAllowed(false);
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent arg0) {
if (table.getSelectedColumn() == 0) {
selectedRows = table.getSelectedRows();
System.out.println("Selected Rows before " + Arrays.toString(selectedRows));
}
}
});
final ListSelectionModel columnListSelectionModel = table.getColumnModel().getSelectionModel();
columnListSelectionModel.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (table.getSelectedColumn() != 0) {
table.clearSelection();
System.out.println("Selected Rows during " + Arrays.toString(table.getSelectedRows()));
for (int i = 0; i < selectedRows.length; i++) {
table.getSelectionModel().addSelectionInterval(selectedRows[i], selectedRows[i]);
}
System.out.println("Selected Rows after " + Arrays.toString(table.getSelectedRows()));
}
}
});
model.addRow(new Object[] { "Bird", new CheckboxCell(new JCheckBox()),
new CheckboxCell(new JCheckBox()), new SpinnerCell(new JSpinner()) });
model.addRow(new Object[] { "Cat", new CheckboxCell(new JCheckBox()), new CheckboxCell(new JCheckBox()),
new SpinnerCell(new JSpinner()) });
model.addRow(new Object[] { "Dog", new CheckboxCell(new JCheckBox()), new CheckboxCell(new JCheckBox()),
new SpinnerCell(new JSpinner()) });
model.addRow(new Object[] { "Fish", new CheckboxCell(new JCheckBox()),
new CheckboxCell(new JCheckBox()), new SpinnerCell(new JSpinner()) });
model.addRow(new Object[] { "Pig", new CheckboxCell(new JCheckBox()), new CheckboxCell(new JCheckBox()),
new SpinnerCell(new JSpinner()) });
frame.add(new JScrollPane(table));
frame.setSize(300, 200);
frame.setVisible(true);
}
});
}
static class CheckboxCell extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private static final long serialVersionUID = 1L;
private JCheckBox checkBox;
public CheckboxCell(JCheckBox inputCheckBox) {
checkBox = inputCheckBox;
}
@Override
public Object getCellEditorValue() {
return checkBox.isSelected();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row,
int column) {
return checkBox;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
return checkBox;
}
public JCheckBox getCheckBox() {
return checkBox;
}
@Override
public boolean isCellEditable(EventObject evt) {
return true;
}
public String toString() {
return checkBox.isSelected() + "";
}
}
static class SpinnerCell extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private static final long serialVersionUID = 1L;
private JSpinner editSpinner, renderSpinner;
public SpinnerCell() {
editSpinner = new JSpinner();
JTextField tf = ((JSpinner.DefaultEditor) editSpinner.getEditor()).getTextField();
tf.setForeground(Color.black);
renderSpinner = new JSpinner();
JTextField tf2 = ((JSpinner.DefaultEditor) renderSpinner.getEditor()).getTextField();
tf2.setForeground(Color.black);
}
public SpinnerCell(JSpinner showSpinner) {
editSpinner = showSpinner;
JTextField tf = ((JSpinner.DefaultEditor) editSpinner.getEditor()).getTextField();
tf.setForeground(Color.black);
renderSpinner = showSpinner;
JTextField tf2 = ((JSpinner.DefaultEditor) renderSpinner.getEditor()).getTextField();
tf2.setForeground(Color.black);
}
@Override
public Object getCellEditorValue() {
return editSpinner.getValue();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row,
int column) {
return editSpinner;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
return renderSpinner;
}
public String toString() {
return editSpinner.getValue().toString();
}
public JSpinner getSpinner() {
return editSpinner;
}
@Override
public boolean isCellEditable(EventObject evt) {
return true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的简短示例:
JTable#changeSelection(...)table.setCellSelectionEnabled(true);ListSelectionModel#isSelectedIndex(...)import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class TableTest2 {
public JComponent makeUI() {
String[] columnNames = {"Layer", "Enabled", "Read Only"};
Object[][] data = {
{"Bird", true, false}, {"Cat", true, false},
{"Dog", true, false}, {"Fish", true, false}, {"Pig", true, false}
};
TableModel model = new DefaultTableModel(data, columnNames) {
@Override public Class<?> getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
@Override public boolean isCellEditable(int row, int col) {
return col != 0;
}
};
JTable table = new JTable(model) {
@Override public void changeSelection(
int rowIndex, int columnIndex, boolean toggle, boolean extend) {
if (convertColumnIndexToModel(columnIndex) != 0) {
return;
}
super.changeSelection(rowIndex, columnIndex, toggle, extend);
}
};
table.setAutoCreateRowSorter(true);
table.setCellSelectionEnabled(true);
table.getColumnModel().setSelectionModel(new DefaultListSelectionModel() {
@Override public boolean isSelectedIndex(int index) {
return table.convertColumnIndexToModel(index) == 0;
}
});
return new JScrollPane(table);
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new TableTest2().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3330 次 |
| 最近记录: |