2014-09-25 115 views
2

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

enter image description here

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

enter image description here

可能somebofy请帮我在这?

这里是我的代码

类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

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

你可以检查我的解决方案,但不是完美的。在这种解决方案中,“轮班”选择不起作用。

的想法是重写isCellSelected(INT行,INT式柱)和changeSelection的JTable的(INT的rowIndex,INT columnIndex,布尔肘节,布尔延伸)。

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

创建这些类FOM细胞储存:

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

    }; 

我希望这可以帮助你。

+0

你是救世主!告诉我,'class Cell'中的'public boolean是(int r,int c)'是做什么的? – 2014-09-26 07:51:28

+1

这只是一个检查平等的替代方法,就像说getters(如果有的话)cell.getRow()== r && cell.getColumn()== c – sotcha 2014-09-26 09:13:45