morpheus05
morpheus05

Reputation: 4872

JList render invisible "selection marker"

The JList supports multiple selection when you holding the control key: Press Ctrl+Up/Down to move some invisible marker (nimbus LAF). If you no press space, the element gets selected.

Example: Your JList has three elements, the first one is selected. You know press Ctrl + Down, Ctrl + Down and then Space. The last element is now selected.

The question is: How can I render the invisible marker I move with Ctrl+up/down?

For example the windows file explorer renders this marker with a dotted border and I like to render something similar. The thing is that with Ctrl + Up/Down you don't change the selection but you change the element which would be selected/deselected if you press Space.

Upvotes: 0

Views: 251

Answers (1)

Sergiy Medvynskyy
Sergiy Medvynskyy

Reputation: 11327

DefaultListCellRenderer do it automatically using special border. If you want to change this border, you can change the appropriate setting of L&F in UIManager.

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

If you want to do something else you can write your own renderer.

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

Upvotes: 2

Related Questions