向子菜单添加可滚动菜单

如何解决向子菜单添加可滚动菜单

我正试图适应子菜单https://coderanch.com/t/343946/java/Scrolling-JMenu中的代码,以便具有滚动条而不是像Java: Creating a scrolling submenu的答案中所建议的按钮。但是我在获得“标准”行为时遇到了一些麻烦:

  1. 当鼠标聚焦/悬停在可滚动菜单上时,父菜单不应消失(请参见“字体”菜单)。
  2. 当鼠标未聚焦/悬停在其或其父子菜单上时,可滚动菜单应消失(请参见“字体”菜单)。
  3. 即使子菜单的文本很长,滚动菜单也不应该消失(请参阅“帮助”菜单)。

在此先感谢您的帮助。这是我的代码

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,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(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],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);
    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?