Java - setSelectedIcon() и setPressedIcon() не регистрируются

У меня есть JPopupMenu на JTree с JCheckboxMenuItem, где я хотел бы использовать пользовательские значки (Windows L&F). Я могу использовать setIcon() на JCheckboxMenuItem успешно, но по какой-то причине setSelectedIcon() и setPressedIcon() не работают.

Код ниже завершен и скомпилируется без ошибок. Однако это просто не работает. Я подтвердил, что изображения загружаются правильно, установив их через setIcon() и увидев их там.

Проводя некоторые исследования, я заметил этот вопрос, поэтому я попытался применить обходной путь, используя его, но, похоже, он не работает с использованием JPopupMenu. Я пытаюсь найти возможный обходной путь с JPopupMenu, но у меня проблемы. Я думал о добавлении MouseListener, но я хочу, чтобы он также реагировал на события клавиатуры... К сожалению, Menulistener не работает на JPopupMenu.

Вот скомпилированный, безошибочный код:

package mypackage;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

public class test extends JFrame {

    public static final ImageIcon icon_properties   = new ImageIcon(mypackage.class.getResource("options.png"));
    public static final ImageIcon icon_checked      = new ImageIcon(mypackage.class.getResource("checkbox_checked.png"));
    public static final ImageIcon icon_unchecked    = new ImageIcon(mypackage.class.getResource("checkbox_unchecked.png"));
    public static final ImageIcon icon_pressed      = new ImageIcon(mypackage.class.getResource("checkbox_pressed.png"));

    String SINGLE_LEFT      = "single left click";
    String SINGLE_MIDDLE    = "single middle click";
    String SINGLE_RIGHT     = "single right click";
    String DOUBLE_LEFT      = "double left click";
    String DOUBLE_MIDDLE    = "double middle click";
    String DOUBLE_RIGHT     = "double right click";

    String MENU_VISIBLE     = "Visible";
    String MENU_SELECTABLE  = "Selectable";
    String MENU_DRAGGABLE   = "Draggable";
    String MENU_PROPERTIES  = "Properties";

    protected JTree  theTree;
    protected DefaultMutableTreeNode theModel;

    ContextMenu menu = new ContextMenu();

    public test() {
        setSize(400, 300);
        theModel = new DefaultMutableTreeNode("LayerList") {
            {
                String NODE_NAME = " this is an item to select ";
                DefaultMutableTreeNode node_icon = new DefaultMutableTreeNode(new DefaultMutableTreeNode(NODE_NAME));
                add(node_icon);
                node_icon = new DefaultMutableTreeNode(new DefaultMutableTreeNode(NODE_NAME));
                add(node_icon);
                node_icon = new DefaultMutableTreeNode(new DefaultMutableTreeNode(NODE_NAME));
                add(node_icon);
                node_icon = new DefaultMutableTreeNode(new DefaultMutableTreeNode(NODE_NAME));
                add(node_icon);
                node_icon = new DefaultMutableTreeNode(new DefaultMutableTreeNode(NODE_NAME));
                add(node_icon);
                node_icon = new DefaultMutableTreeNode(new DefaultMutableTreeNode(NODE_NAME));
                add(node_icon);
                node_icon = new DefaultMutableTreeNode(new DefaultMutableTreeNode(NODE_NAME));
                add(node_icon);
            }
        };

        theTree = new JTree(theModel);
        theTree.putClientProperty("JTree.lineStyle", "Angled");
        theTree.setRootVisible(false);
        theTree.setShowsRootHandles(true);
        theTree.setEditable(false);

        MouseListener ml = new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                int selRow = theTree.getRowForLocation(e.getX(), e.getY());
                TreePath selPath = theTree.getPathForLocation(e.getX(), e.getY());
                if(selRow != -1) {
                    if( SwingUtilities.isLeftMouseButton(e) ) {
                        if(e.getClickCount() == 1) {
                            ContextMenuClickHander(SINGLE_LEFT, selRow, selPath, e);
                        }
                        else if(e.getClickCount() >= 2) {
                            ContextMenuClickHander(DOUBLE_LEFT, selRow, selPath, e);
                        }
                    }
                    else if( SwingUtilities.isMiddleMouseButton(e) ) {
                        if(e.getClickCount() == 1) {
                            ContextMenuClickHander(SINGLE_MIDDLE, selRow, selPath, e);
                        }
                        else if(e.getClickCount() >= 2) {
                            ContextMenuClickHander(DOUBLE_MIDDLE, selRow, selPath, e);
                        }
                    }
                    else if( SwingUtilities.isRightMouseButton(e) ) {
                        if(e.getClickCount() == 1) {
                            ContextMenuClickHander(SINGLE_RIGHT, selRow, selPath, e);
                        }
                        else if(e.getClickCount() >= 2) {
                            ContextMenuClickHander(DOUBLE_RIGHT, selRow, selPath, e);
                        }
                    }
                }
            }
        };
        theTree.addMouseListener(ml);
        JScrollPane s = new JScrollPane();
        s.getViewport().add(theTree);
        getContentPane().add(s, BorderLayout.CENTER);
        addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });
        setVisible(true);
    }

    class ContextMenu extends JPopupMenu implements ActionListener {
        JCheckBoxMenuItem item;
        public ContextMenu(){
            item = new JCheckBoxMenuItem(MENU_VISIBLE);
            item.setIcon(icon_unchecked);
            item.setSelectedIcon(icon_checked);
            item.setPressedIcon(icon_pressed);
            //item.setRolloverIcon(icon_checked);
            //item.setRolloverSelectedIcon(icon_checked);
            //item.setDisabledIcon(icon_checked);
            //item.setDisabledSelectedIcon(icon_checked);
            item.setActionCommand(MENU_VISIBLE);
            item.addActionListener(this);
            add(item);

            item = new JCheckBoxMenuItem(MENU_SELECTABLE);
            item.setIcon(icon_unchecked);
            item.setSelectedIcon(icon_checked);
            item.setPressedIcon(icon_pressed);
            item.setActionCommand(MENU_SELECTABLE);
            item.addActionListener(this);
            add(item);

            item = new JCheckBoxMenuItem(MENU_DRAGGABLE);
            item.setIcon(icon_unchecked);
            item.setSelectedIcon(icon_checked);
            item.setPressedIcon(icon_pressed);
            item.setActionCommand(MENU_DRAGGABLE);
            item.addActionListener(this);
            add(item);

            JMenuItem item = new JMenuItem(MENU_PROPERTIES+"...");
            item.setIcon(icon_properties);
            item.setActionCommand(MENU_PROPERTIES);
            item.addActionListener(this);
            add(item);
        }

        public void actionPerformed(ActionEvent e) {
            if (MENU_VISIBLE.equals(e.getActionCommand())) {
                System.out.println("Clicked "+MENU_VISIBLE);
                ChangeIcon(e);
            }
            else if (MENU_SELECTABLE.equals(e.getActionCommand())) {
                System.out.println("Clicked "+MENU_SELECTABLE);
                ChangeIcon(e);
            }
            else if (MENU_DRAGGABLE.equals(e.getActionCommand())) {
                System.out.println("Clicked "+MENU_DRAGGABLE);
                ChangeIcon(e);
            }
            else if (MENU_PROPERTIES.equals(e.getActionCommand())) {
                System.out.println("Clicked "+MENU_PROPERTIES);
            }
        }
    }

    public void ChangeIcon(ActionEvent e) {
        if (e.getSource() instanceof AbstractButton) {
            boolean selected = ((AbstractButton) e.getSource()).isSelected();
            if( selected ) {
                ((AbstractButton) e.getSource()).setIcon(icon_checked);
            }
            else {
                ((AbstractButton) e.getSource()).setIcon(icon_unchecked);
            }
        }
    }

    void ContextMenuClickHander(String clickType, int row, TreePath tpath, MouseEvent e) {
        theTree.setSelectionPath(tpath);
        System.out.println(clickType+": row="+row+", treepath="+tpath);
        if( clickType.equals(SINGLE_RIGHT) ) {
            menu.show(e.getComponent(), e.getX(), e.getY());
        }
    }

    public static void main(String argv[]) {
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
        } catch (Exception evt) {}
        new test().setLocationRelativeTo(null);
    }
}

Вот изображения, которые я пытаюсь использовать, если это поможет:
- проверено: проверено https://i.imgur.com/xdsSXVe.png
- не проверено: непроверенный https://i.imgur.com/mFP5T9y.png
- нажал: прессованный https://i.imgur.com/Bt3jliz.png

Обновить:

Не совсем идеальный обходной путь, который я разработал, заключается в том, чтобы вручную устанавливать значок при каждом обнаружении щелчка. В функции "actionPerformed(ActionEvent e)" после каждого оператора println добавьте новую строку с "ChangeIcon(e);", а когда это будет сделано, просто добавьте эту функцию:

Тем не менее, кажется, что Windows L & F все еще добавляет свою собственную наведенную / выбранную границу (см. Изображение) Я надеюсь, что у кого-то еще есть реальное решение...
не очень идеальный обходной путь

Обновление 2:

Обновлен полный код с первым кодом обновления, немного подправлен пост.

0 ответов

Другие вопросы по тегам