views:

166

answers:

1

Right now when a user right clicks on a selected JList item in my program the resulting JPopupMenu clears the selection (at least visually) until the popup menu is closed. This isn't consistent with the native look and feel of any platform I know of. The item should stay visually selected or have a selected-color border around it. But I can't find anythin in the API about popup menus changing selection appearance. Is there any way I can control this behavior?

+2  A: 

How are you implementing your Mouse Listener that shows the popup? I have created a test application to demonstrate the behaviour of List selections and popup menus that I would typically expect. On Windows with Java 1.5/6 this behaves correctly.

Maybe this will help you with your particular problem.

package jlist;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class Test extends JPanel implements ListSelectionListener {
    private static final String ACTION_FEED = "Feed";
    private JList list;
    private JPopupMenu menu;
    // Initialise a JList and add to JPanel.
    public Test() {
        super(new BorderLayout());
        list = new JList(new Object[]{"Badger", "Ferret", "Stoat", "Weasel"});
        initActions();
        list.addListSelectionListener(this);
        // Add mouse listener
        list.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (e.isPopupTrigger()) showPopup(e);
            }
            @Override
            public void mouseReleased(MouseEvent e) {
                if (e.isPopupTrigger()) showPopup(e);
            }
            private void showPopup(MouseEvent e) {
                menu.show(e.getComponent(), e.getX(), e.getY());
            }
        });
        add(new JScrollPane(list), BorderLayout.CENTER);
        valueChanged(null);
    }

    // Triggered when List Selection changes. Used to control Actions enabled state.
    public void valueChanged(ListSelectionEvent e) {
        boolean selected = list.getSelectedValue() != null;
        getActionMap().get(ACTION_FEED).setEnabled(selected);
    }

    // Initialise Actions and Popup Menu
    private void initActions() {
        menu = new JPopupMenu();
        Action feed = new AbstractAction(ACTION_FEED) {
            public void actionPerformed(ActionEvent e) {
                String value = (String) list.getSelectedValue();
                JOptionPane.showMessageDialog(Test.this, "Fed " + value);
            }
        };
        getActionMap().put(ACTION_FEED, feed);
        menu.add(feed);
    }

    public static void main(String [] args) {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(new Test());
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
}
gencoreoperative