【问题标题】:JList - set allowed selection combinationsJList - 设置允许的选择组合
【发布时间】:2015-07-16 11:03:01
【问题描述】:

我有一个 JList 有 8 个字符串项。客户希望有四种可能的选择组合。代码示例生成这样的列表。我用鼠标监听器以一种丑陋的方式部分地完成了这一点。

import javax.swing.*;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.util.ArrayList;

class Selections {
    public static void main(String[] args) throws Exception {
        ArrayList<String> items = new ArrayList<String>();
        items.add("11");
        items.add("21");
        items.add("31");
        items.add("41");
        items.add("12");
        items.add("22");
        items.add("32");
        items.add("42");

        final ArrayList<String> combinationOne = new ArrayList<String>();
        combinationOne.add("11");
        combinationOne.add("12");
        final ArrayList<String> combinationTwo = new ArrayList<String>();
        combinationTwo.add("21");
        combinationTwo.add("22");
        final ArrayList<String> combinationThree = new ArrayList<String>();
        combinationThree.add("31");
        combinationThree.add("32");
        final ArrayList<String> combinationFour = new ArrayList<String>();
        combinationFour.add("41");
        combinationFour.add("42");

        JList list = new JList(items.toArray());

        MouseListener mouseListener = new MouseAdapter() {
            public void mouseReleased(MouseEvent mouseEvent) {
                JList eventList = (JList) mouseEvent.getSource();
                int index = eventList.locationToIndex(mouseEvent.getPoint());
                if (index >= -1) {
                    Object o = eventList.getModel().getElementAt(index);
                    System.out.println(o.toString());
                    if (combinationOne.contains(eventList.getSelectedValue())) {
                        eventList.addSelectionInterval(0, 0);
                        eventList.addSelectionInterval(4, 4);
                    } else if (combinationTwo.contains(eventList.getSelectedValue())) {
                        eventList.addSelectionInterval(1, 1);
                        eventList.addSelectionInterval(5, 5);
                    } else if(combinationThree.contains(eventList.getSelectedValue())) {
                        eventList.addSelectionInterval(2, 2);
                        eventList.addSelectionInterval(6, 6);
                    } else if (combinationFour.contains(eventList.getSelectedValue())) {
                        eventList.addSelectionInterval(3, 3);
                        eventList.addSelectionInterval(7, 7);
                    }
                }
            }
        };
        list.addMouseListener(mouseListener);

        list.setSelectionMode(
            ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        // Set the default selection
        list.addSelectionInterval(0, 0);
        list.addSelectionInterval(4, 4);

        JOptionPane.showMessageDialog(null, new JScrollPane(list));
    }
}

以下是此实现的一些问题:

  1. 选择在鼠标单击时开始,但第二次选择在鼠标释放后发生。这会造成不一致的印象。

  2. 您还会看到第二个项目选择有一个短暂的延迟,因为它发生在鼠标释放之后。

  3. 在第二个选定项目周围设置了边框,这是不需要的。

  4. 您可以使用向上/向下箭头在项目之间移动,但未处理。

此外,我不喜欢这种实现方式,因为它不是一个干净的方式。

我尝试过使用ListSelectionListener,但我无法避免选择事件循环并且它溢出了。

【问题讨论】:

  • 如果在给定时间点,您想从同一个列表中两个明显不同的集合中选择列表中的两个项目,那么为什么不能有两个单独的 JList?您可以同步它们之间的选择。
  • 好点,但我总是会变成不同的物品配置。所以它可能恰好只有两个项目和一个组合,或 20 个项目和 3 个组合。使用不同的 JList 计数太难了。另外,请考虑项目顺序应保持不变。

标签: java selection combinations jlist


【解决方案1】:

看这个没有第 4 点。

    class Selections{

    ArrayList<String> items = new ArrayList<String>();
    final ArrayList<String> combinationOne = new ArrayList<String>();
    final ArrayList<String> combinationTwo = new ArrayList<String>();
    final ArrayList<String> combinationThree = new ArrayList<String>();
    final ArrayList<String> combinationFour = new ArrayList<String>();

    JList list = null;
    public Selections(){
        items.add("11");
        items.add("21");
        items.add("31");
        items.add("41");
        items.add("12");
        items.add("22");
        items.add("32");
        items.add("42");

        list = new JList(items.toArray());

        combinationOne.add("11");
        combinationOne.add("12");
        combinationTwo.add("21");
        combinationTwo.add("22");
        combinationThree.add("31");
        combinationThree.add("32");
        combinationFour.add("41");
        combinationFour.add("42");
    }
    public static void main(String[] args) throws Exception {
        Selectionsselections = new Selections();
        selections.runApp();

    }

    private void runApp() {
    MouseMotionListener mouseMotionListener = new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            JList eventList = (JList) e.getSource();
            addSelectionInterval(eventList);
        }
    };
        MouseListener mouseListener = new MouseAdapter() {
            public void mousePressed(MouseEvent mouseEvent) {
                JList eventList = (JList) mouseEvent.getSource();
                int index = eventList.locationToIndex(mouseEvent.getPoint());
                if (index >= -1) {
                    addSelectionInterval(eventList);
                }
            }
        };
        list.addMouseListener(mouseListener);
        list.addMouseMotionListener(mouseMotionListener );
        list.setCellRenderer(getRenderer());
        list.setSelectionMode(
                ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        // Set the default selection
        list.addSelectionInterval(0, 0);
        list.addSelectionInterval(4, 4);

        JOptionPane.showMessageDialog(null, new JScrollPane(list));
    }

    private void addSelectionInterval(JList eventList) {
        if (combinationOne.contains(eventList.getSelectedValue())) {
            eventList.addSelectionInterval(0, 0);
            eventList.addSelectionInterval(4, 4);
        } else if (combinationTwo.contains(eventList.getSelectedValue())) {
            eventList.addSelectionInterval(1, 1);
            eventList.addSelectionInterval(5, 5);
        } else if(combinationThree.contains(eventList.getSelectedValue())) {
            eventList.addSelectionInterval(2, 2);
            eventList.addSelectionInterval(6, 6);
        } else if (combinationFour.contains(eventList.getSelectedValue())) {
            eventList.addSelectionInterval(3, 3);
            eventList.addSelectionInterval(7, 7);
        }
    }

    private ListCellRenderer<? super String> getRenderer() {
        return new DefaultListCellRenderer(){
            @Override
            public Component getListCellRendererComponent(JList<?> list,
                                                          Object value, int index, boolean isSelected,
                                                          boolean cellHasFocus) {
                JLabel listCellRendererComponent = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected,cellHasFocus);
                listCellRendererComponent.setBorder(BorderFactory.createEmptyBorder());
                return listCellRendererComponent;
            }
        };
    }
}

【讨论】:

  • 感谢您的出色回答。我自己修复了第 4 点:list.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "none");和 list.getInputMap().put(KeyStroke.getKeyStroke("UP"), "none"); .现在,当鼠标在按下和释放之间移动时,问题仍然存在。
  • 刚刚用您当前的问题更新了答案。添加了运动监听器来处理这个问题。
  • 现在就像一个魅力!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-03
  • 2012-11-19
相关资源
最近更新 更多