我正在尝试调整子菜单中的代码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);
}
}
暂无答案!
目前还没有任何答案,快来回答吧!