2012-08-17 27 views
1

我有一個JTable,用戶應該只能選擇一行,但每當用戶選擇一行時,其他一些行(根據一些邏輯)也應該以編程方式選擇。問題是,如果我將表的選擇模式設置爲ListSelectionModel.SINGLE_SELECTIONaddRowSelectionInterval也將只選擇一行。有任何想法嗎?編輯:我認爲所有的想法(自定義選擇模型,清除所有,但最後的用戶選擇,高亮自定義渲染器)是好的,但最好是使用SwingX,因爲它不需要太多的基礎結構代碼,只有圖書館的巧妙使用。 (當SwingX-guru在幫助時很容易變得更加靈巧:)JTable:用戶的單選,用編程方式選擇多個

+0

請提供一些SSCCE – 2012-08-17 10:31:27

+0

你可能會想看看替代選擇管理 – MadProgrammer 2012-08-17 10:34:04

+0

你會迷惑你的用戶 - 他們將如何區分自己選擇的人和神奇選擇的人? – kleopatra 2012-08-17 10:41:54

回答

3

偏見我會說:在SwingX肯定更容易:-)

所有你需要的是

  • 定製HighlightPredicate它決定什麼是相關的
  • 配置了選擇的ColorHighlighterColors
  • 設置自定義謂詞從選擇模型收到變更通知

一些代碼:

// the custom predicate 
public static class RelatedHighlightPredicate implements HighlightPredicate { 
    List<Integer> related; 

    public RelatedHighlightPredicate(Integer... related) { 
     this.related = Arrays.asList(related); 

    } 
    @Override 
    public boolean isHighlighted(Component renderer, 
      ComponentAdapter adapter) { 
     int modelIndex = adapter.convertRowIndexToModel(adapter.row); 
     return related.contains(modelIndex); 
    } 

} 

// its usage 
JXTable table = new JXTable(someModel); 
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
final ColorHighlighter hl = new ColorHighlighter(HighlightPredicate.NEVER, 
     table.getSelectionBackground(), table.getSelectionForeground()); 
table.addHighlighter(hl); 
ListSelectionListener l = new ListSelectionListener() { 

    @Override 
    public void valueChanged(ListSelectionEvent e) { 
     if (e.getValueIsAdjusting()) return; 
     invokeUpdate((ListSelectionModel) e.getSource()); 
    } 

    private void invokeUpdate(final ListSelectionModel source) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       int singleSelection = source.getMinSelectionIndex(); 
       if (singleSelection >= 0) { 
        int first = Math.max(0, singleSelection - 2); 
        int last = singleSelection + 2; 
        hl.setHighlightPredicate(new RelatedHighlightPredicate(first, last)); 
       } else { 
        hl.setHighlightPredicate(HighlightPredicate.NEVER); 
       } 
      } 
     }); 

    } 

}; 
table.getSelectionModel().addListSelectionListener(l); 
2

您可以爲表格設置多選,但每次選擇更改 - 只取1(最後選定)行,清除其他選項並添加您的自己計算的選擇。

+0

另一點我會提到:你需要在你的ListSelectionListener中設置一個標誌來表示你是否以編程方式改變選擇,如果是的話,不要對選擇事件作出反應。否則,你會以無限循環結束。 – Adamski 2012-08-17 10:42:17

+0

@Adamski也是如此。或者,在您執行所選計算並將其存儲回來時,只刪除所有選擇監聽器。如果您在該表上有其他選擇偵聽器,情況可能會更好。 – 2012-08-17 10:56:31

2
  1. The problem is that if I set the selection mode of the table

    使用ListSelectionModel.SINGLE_SELECTION事件從mousekeyborad來到

  2. some other rows (that are related according to some logic) should also be selected programmatically

    Renderer有找JTable,則需要行(S),列或任何可能突出顯示,直到編程規則保持不變

  3. ... maybe will help you