我想创建一个JTable,我可以通过 ctrl + click 组合选择多个非连续的单元格。到目前为止,当我从同一行中选择不连续的单元格时,它可以正常工作。
但是当我从不同的行中选择单元格时,我得到了这个
请帮助我吗?
这是我的代码
Class TestTimeTable
public class TestTimeTable extends JFrame{
private final int rows = 10;
private final int cols = 8;
private final String daysOfTheWeek[] = {"ΔΕΥΤΕΡΑ", "ΤΡΙΤΗ", "ΤΕΤΑΡΤΗ", "ΠΕΜΠΤΗ", "ΠΑΡΑΣΚΕΥΗ"};
private final JPanel jTablePanel;
private final JScrollPane scrollPane;
private final JTable timeTable;
private final Object[][] rowData;
public TestTimeTable(){
this.rowData = new Object[this.rows][this.cols];
this.timeTable = new JTable(this.rowData,this.daysOfTheWeek){
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
this.timeTable.setRowHeight(200, 200);
this.timeTable.setFillsViewportHeight(true);
this.timeTable.setOpaque(true);
this.timeTable.setColumnSelectionAllowed(true);
this.timeTable.setRowSelectionAllowed(true);
this.timeTable.setCellSelectionEnabled(true);
this.timeTable.setDefaultRenderer(Object.class, new BoardTableCellRenderer());
this.scrollPane = new JScrollPane(this.timeTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
this.jTablePanel = new JPanel();
this.jTablePanel.add(this.scrollPane);
getContentPane().add(new JScrollPane(this.timeTable), BorderLayout.CENTER);
}
public void createAndShowUI(){
setSize(600, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] argas){
TestTimeTable tt = new TestTimeTable();
tt.createAndShowUI();
}
类BoardTableCellRenderer
class BoardTableCellRenderer extends DefaultTableCellRenderer{
Component c;
private static final long serialVersionUID = 1L;
private final Color selectionBlue = new Color(131,166,198);
private final MatteBorder border = new MatteBorder(1, 1, 0, 0, Color.BLACK);
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (table.isCellSelected(row, column)){
c.setBackground(this.selectionBlue);
setBorder(this.border);
}
else {
c.setBackground(Color.WHITE);
}
return c;
}
}
任何意见都会非常有帮助。提前谢谢。
答案 0 :(得分:2)
这似乎是JTables的一个常见问题,你不能选择非连续的单元格,但你可以显示“假的”非连续单元格。
您可以查看我的解决方案,但并不完美。在该解决方案中,“移位”选择不起作用。
我们的想法是覆盖 JTable的 isCellSelected (int row,int colum)和 changeSelection (int rowIndex,int columnIndex,boolean toggle,boolean extend) 强>
所以我存储了单独选择的单元格并在isCellSelected中使用它们。
从fom cell storage创建这些类:
class Cell {
private int row;
private int column;
public Cell(int row, int column) {
this.row = row;
this.column = column;
}
public boolean is(int r, int c) {
return row == r && column == c;
}
}
class CellSelectionSet {
private ArrayList<Cell> cells = new ArrayList<TestTimeTable.Cell>();
public void add(int r, int c) {
if (!contains(r, c)) {
cells.add(new Cell(r, c));
}
}
public boolean containsOneOrLess() {
return cells.size() <= 1;
}
public boolean contains(int r, int c) {
for (Cell cell : cells) {
if (cell.is(r, c)) {
return true;
}
}
return false;
}
public void clear() {
cells.clear();
}
}
在JTable你可以使用:
this.timeTable = new JTable(this.rowData, this.daysOfTheWeek) {
CellSelectionSet cellSelectionSet = new CellSelectionSet();
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
@Override
public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
super.changeSelection(rowIndex, columnIndex, toggle, extend);
if (toggle) {
cellSelectionSet.add(rowIndex, columnIndex);
} else {
if (extend) {
cellSelectionSet.add(rowIndex, columnIndex);
} else {
// reset
cellSelectionSet.clear();
cellSelectionSet.add(rowIndex, columnIndex);
}
}
}
@Override
public boolean isCellSelected(int row, int column) {
if (cellSelectionSet.containsOneOrLess()) {
// show the default
return super.isCellSelected(row, column);
}
return cellSelectionSet.contains(row, column);
}
};
我希望这会对你有所帮助。