【问题标题】:JTable: single selection for the user, multiple selections programmaticallyJTable:用户单选,以编程方式多选
【发布时间】:2012-08-13 19:12:04
【问题描述】:

我有一个JTable,用户应该只能选择一行,但是每当用户选择一行时,也应该以编程方式选择其他一些行(根据某些逻辑相关)。问题是如果我将表格的选择模式设置为ListSelectionModel.SINGLE_SELECTIONaddRowSelectionInterval也会只选择一行。有任何想法吗?

编辑:我认为所有想法(自定义选择模型、清除除最后一个用户选择之外的所有选择、用于突出显示的自定义渲染器)都很好,但最好是使用 SwingX,因为它不需要太多基础架构代码,只需要一个巧妙地使用图书馆。 (当 SwingX 专家提供帮助时,很容易变得聪明 :)

【问题讨论】:

  • 你可能想看看替换选择管理器
  • 您会让您的用户感到困惑 - 他们如何区分自己选择的人和被魔法选择的其他人?
  • 抱歉选择型号:P long day
  • kleopatra:用户知道行是相关的。做出选择后,所有相关的行都会发生一些事情。
  • hmm ...可以直观地选择(又名:突出显示)相关行,而不实际选择它们吗?无论如何,您需要将“相关”逻辑与“选择”分开。

标签: java swing jtable selection swingx


【解决方案1】:

您可以为表格设置多选,但每次选择更改 - 只取 1(最后选择)行,清除其他选择并添加您自己的计算选择。

【讨论】:

  • 我要提到的另一点:您需要在 ListSelectionListener 中设置一个标志来说明您是否正在以编程方式更改选择,如果是,请不要对选择事件做出反应。否则你会陷入无限循环。
  • @Adamski 也是如此。或者在执行计算的选择时删除所有选择侦听器,然后将它们存储回来。如果您在该表上有其他选择侦听器,这可能会更好。
【解决方案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,然后可以突出显示所需的行、列或任何内容,直到程序规则保持不变

  3. ...maybe will help you

【讨论】:

    【解决方案3】:

    有偏见的我会说:在 SwingX 中肯定更容易:-)

    你只需要

    • 一个自定义的 HighlightPredicate 决定什么是相关的
    • 使用 selectionColors 配置的 ColorHighlighter
    • 在从选择模型接收更改通知时设置自定义谓词

    一些代码:

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

    【讨论】:

      猜你喜欢
      • 2013-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多