JTable使用ctrl + click组合选择多个非连续单元格

时间:2014-09-25 07:10:51

标签: java swing jtable cells

我想创建一个JTable,我可以通过 ctrl + click 组合选择多个非连续的单元格。到目前为止,当我从同一行中选择不连续的单元格时,它可以正常工作。

enter image description here

但是当我从不同的行中选择单元格时,我得到了这个

enter image description here

请帮助我吗?

这是我的代码

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;
    }
}

任何意见都会非常有帮助。提前谢谢。

1 个答案:

答案 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);
        }

    };

我希望这会对你有所帮助。