JList 渲染不可见 "selection marker"

JList render invisible "selection marker"

JList支持按住control键多选:按Ctrl+Up/Down移动一些不可见的标记(nimbus LAF)。如果您不按 space,该元素将被选中。

示例:您的JList 有三个元素,第一个被选中。你知道按 Ctrl + Down、Ctrl + Down 然后 Space。现在选择了最后一个元素。

问题是:如何渲染使用 Ctrl+up/down 移动的不可见标记?

例如,windows 文件资源管理器使用虚线边框呈现此标记,我喜欢呈现类似的内容。问题是,使用 Ctrl + Up/Down 你不会更改选择,但你会更改元素 selected/deselected 如果你按 Space.

DefaultListCellRenderer 使用特殊边框自动完成。如果要更改此边框,可以在UIManager.

中更改L&F的适当设置
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;

import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.StrokeBorder;

public class ListTryout {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                UIManager.put("List.focusCellHighlightBorder", BorderFactory.createDashedBorder(Color.GRAY));
                final JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.add(new JScrollPane(new JList<String>(new String[] {"one", "two", "three"})));
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

如果您想做其他事情,您可以编写自己的渲染器。

import java.awt.Color;
import java.awt.Component;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class ListTryout {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
//                UIManager.put("List.focusCellHighlightBorder", new StrokeBorder(new BasicStroke(2f)));
                final JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                JList<String> l = new JList<String>(new String[] {"one", "two", "three"});
                l.setCellRenderer(new MyRenderer());
                f.add(new JScrollPane(l));
                f.pack();
                f.setVisible(true);
            }
        });
    }

    private static class MyRenderer extends DefaultListCellRenderer {
        /**
         * {@inheritDoc}
         */
        @Override
        public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            Component result = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            if (!isSelected && cellHasFocus) { // custom highlight of focused but not-selected cell
                result.setBackground(Color.LIGHT_GRAY);
                ((JComponent) result).setBorder(null);
            }
            return result;
        }
    }
}