【问题标题】:JTable select multiple non-contiguous cells with ctrl+click combinationJTable用ctrl+click组合选择多个不连续的单元格
【发布时间】:2014-11-19 21:06:08
【问题描述】:

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

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

有人可以帮我解决这个问题吗?

这是我的代码

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

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

【问题讨论】:

    标签: java swing jtable cells


    【解决方案1】:

    这似乎是 JTables 的一个常见问题,您不能选择非连续单元格,但您可以显示“假”非连续单元格。

    您可以检查我的解决方案,但并不完美。在该解决方案中,“班次”选择不起作用。

    这个想法是覆盖 JTable 的 isCellSelected(int row, int colum) 和 changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend)

    所以我存储单独选择的单元格并在 isCellSelected 中使用它们。

    从单元存储中创建这些类:

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

    希望对你有帮助。

    【讨论】:

    • 你是救世主!不过告诉我,class Cell 中的public boolean is(int r, int c) 是做什么的?
    • 这只是检查相等性的另一种方法,就像用 getter 说(如果我有的话) cell.getRow()==r&&cell.getColumn()==c
    猜你喜欢
    • 2016-05-15
    • 1970-01-01
    • 1970-01-01
    • 2017-02-05
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    • 2016-02-17
    • 2014-08-01
    相关资源
    最近更新 更多