java—将可滚动菜单添加到子菜单

eni9jsuy  于 2021-07-05  发布在  Java
关注(0)|答案(0)|浏览(254)

我正在尝试调整子菜单中的代码https://coderanch.com/t/343946/java/scrolling-jmenu 为了有一个滚动条,而不是像java的答案中建议的按钮:创建一个滚动子菜单。然而,我有一些麻烦,以获得一个“标准”的行为:
当鼠标在可滚动菜单上聚焦/悬停时,父菜单不应消失(请参见字体菜单)。
当鼠标未在其上或其父子菜单上聚焦/悬停时,可滚动菜单应消失(请参见字体菜单)。
即使子菜单的文本很长,可滚动菜单也不应消失(参见帮助菜单)。
事先谢谢你的帮助。这是我的密码:

import java.awt.Dimension;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;

public class ScrollingMenu extends JFrame {

    private final JPopupMenu fontNameMenu = new JPopupMenu();
    private final JMenu[] fontMenuArray = new JMenu[] {new JMenu("Font Name"), new JMenu("Font Style")};
    private JMenu menu = new JMenu("Font");
    private final JMenu[] helpMenuArray = new JMenu[] {new JMenu("Very very very very very very very long Font Name Menu")};
    private JMenu hmenu = new JMenu("Help");

    public static void main(String[] args) {
        JFrame scrollingMenu = new ScrollingMenu();
        scrollingMenu.setVisible(true);
    }

    public ScrollingMenu() {

        // Creating a long array
        String[] systemFontArray = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
        JCheckBoxMenuItem[] fontNameArray = new JCheckBoxMenuItem[systemFontArray.length];

        // Creating the scrollable menu
        GridBagLayout fontNameLayout=new GridBagLayout();
        JPanel fontNamePanel = new JPanel();
        fontNamePanel.setLayout(fontNameLayout);
        for (int i=0;i<systemFontArray.length;i++) {
            fontNameArray[i] = new JCheckBoxMenuItem(systemFontArray[i]);
            fontNameLayout.setConstraints(fontNameArray[i],new GridBagConstraints(0,i,1,1,0,0,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0));
            fontNamePanel.add(fontNameArray[i]);
        }
        JScrollPane fontScrollPane = new JScrollPane(fontNamePanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        this.fontNameMenu.add(fontScrollPane);

        // Adding the scrollable menu to a submenu
        addML(ScrollingMenu.this.fontMenuArray[0], ScrollingMenu.this.fontNameMenu, new Dimension(200, 200));

        // Creating the Font Style submenu (for underlining problem 2)
        this.fontMenuArray[1].add(new JCheckBoxMenuItem("Bold"));
        this.fontMenuArray[1].add(new JCheckBoxMenuItem("Italic"));
        this.fontMenuArray[1].add(new JCheckBoxMenuItem("Plain"));

        // Adding the submenus to the Font menu
        for (int i=0;i<this.fontMenuArray.length;i++) {
            this.menu.add(this.fontMenuArray[i]);
        }

        // Adding the scrollable menu to a long text submenu (problem 3)
        addML(ScrollingMenu.this.helpMenuArray[0], ScrollingMenu.this.fontNameMenu, new Dimension(200, 200));

        // Adding the submenu to the Help menu
        for (int i=0;i<this.helpMenuArray.length;i++) {
            this.hmenu.add(this.helpMenuArray[i]);
        }

        JMenuBar menuBar = new JMenuBar();
        menuBar.add(this.menu);
        menuBar.add(this.hmenu);
        this.setJMenuBar(menuBar);
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        this.pack();
        this.setLocationRelativeTo(null);
    }

    private static void addML (JMenu subMenu, JPopupMenu popupMenu, Dimension dimension) {
        popupMenu.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent focusEvent) {
                if(popupMenu.isVisible() && !subMenu.isSelected())
                    popupMenu.setVisible(false);
            }
        });
        popupMenu.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseExited(MouseEvent mouseEvent) {
                if(!subMenu.isSelected())
                    popupMenu.setVisible(false);
            }
        });
        popupMenu.setInvoker(subMenu);
        popupMenu.setPreferredSize(dimension);
        subMenu.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent mouseEvent) {
                if(!popupMenu.isVisible())
                    displayFontNameMenu(subMenu, popupMenu);
                else
                    popupMenu.setVisible(false);
            }
           @Override
            public void mouseEntered(MouseEvent mouseEvent) {
                if(!popupMenu.isVisible() && subMenu.isSelected())
                    displayFontNameMenu(subMenu, popupMenu);
            }
           @Override
            public void mouseExited(MouseEvent mouseEvent) {
                if(popupMenu.isVisible() && !popupMenu.contains(mouseEvent.getPoint())) {
                    popupMenu.setVisible(false);
                }
            }
        });
    }

    private static void displayFontNameMenu(JMenu subMenu, JPopupMenu popupMenu) {
        Rectangle rectangle = subMenu.getBounds();
        Point point = new Point(rectangle.x  +rectangle.width, rectangle.y);
        SwingUtilities.convertPointToScreen(point, subMenu.getParent());
        popupMenu.setLocation(point.x, point.y);
        popupMenu.setVisible(true);
    }

}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题