我试图让我的JMenuBar来模拟火狐和iTunes的菜单栏的行为。行为:菜单栏最初是隐藏的。但是,当您按Alt时,菜单栏就会出现(选择了第一项),当您没有选择菜单项时,菜单栏就消失了。我的想法是通过JMenuBar上的ChangeListener监听对其选择的更改。
但是,附加的SSCCE的行为并不像预期的那样。当框架加载时,JMenuBar是不可见的。当您按Alt时,会出现菜单栏,其中选择了第一个菜单(多亏了WindowsLookAndFeel)。然而,随后的每个Alt都没有触发ChangeEvents。我搞不懂为什么..。
有人有灯要撒吗?
public class MenuBarTest extends javax.swing.JFrame {
public MenuBarTest() {
initComponents();
jMenuBar1.setVisible(false);
jMenuBar1.getSelectionModel().addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
System.out.println(e.toString());
jMenuBar1.setVisible(jMenuBar1.isSelected());
System.out.println(jMenuBar1.isSelected());
System.out.println(jMenuBar1.getSelectionModel().isSelected());
}
});
}
private void initComponents() {
jMenuBar1 = new javax.swing.JMenuBar();
jMenu1 = new javax.swing.JMenu();
jMenuItem1 = new javax.swing.JMenuItem();
jMenu2 = new javax.swing.JMenu();
jMenuItem2 = new javax.swing.JMenuItem();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jMenu1.setText("File");
jMenuItem1.setText("jMenuItem1");
jMenu1.add(jMenuItem1);
jMenuBar1.add(jMenu1);
jMenu2.setText("Edit");
jMenuItem2.setText("jMenuItem2");
jMenu2.add(jMenuItem2);
jMenuBar1.add(jMenu2);
setJMenuBar(jMenuBar1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE));
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 279, Short.MAX_VALUE));
pack();
}
public static void main(String args[]) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewClass().setVisible(true);
}
});
}
private javax.swing.JMenu jMenu1;
private javax.swing.JMenu jMenu2;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JMenuItem jMenuItem1;
private javax.swing.JMenuItem jMenuItem2;
}发布于 2013-08-07 07:44:08
看起来,一旦被选中,菜单就永远不会被取消。不知道那是不是个窃听器。
直接收听MenuSelectionManager可能是个更好的主意,因为在那里,您可以在任何地方得到菜单选择的所有更改的通知。需要一些逻辑来过滤掉那些与menuBar无关的内容,类似于:
ChangeListener listener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
MenuElement[] elements = MenuSelectionManager.defaultManager().getSelectedPath();
jMenuBar1.setVisible(elements.length > 0 && elements[0] == jMenuBar1);
}
};
MenuSelectionManager.defaultManager().addChangeListener(listener);更新
隐藏脑膜的一个巨大缺点是它的menuItems加速器停止工作。原因是只有显示的组件的componentInputMaps才被要求处理它们。这是在swing包的内部深处完成的,即包私有类KeyboardManager。无法连接自定义管理器(它可能用于处理未显示的菜单)。
不过,在链条的另一端,我们可以进行干预。基本上有两个选项,两个子类菜单栏:
修订后的ChangeListener:
bar.setHidden(true);
ChangeListener listener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
MenuElement[] elements = MenuSelectionManager.defaultManager().getSelectedPath();
bar.setHidden(!(elements.length >0 && elements[0] == bar));
}
};
MenuSelectionManager.defaultManager().addChangeListener(listener);定制的menuBar:
public static class JHideableMenuBar extends JMenuBar {
private boolean hidden;
public void setHidden(boolean hidden) {
if (this.hidden == hidden) return;
this.hidden = hidden;
revalidate();
}
@Override
public Dimension getPreferredSize() {
Dimension pref = super.getPreferredSize();
if (hidden) {
pref.height = 0;
}
return pref;
}
}发布于 2013-08-07 06:20:30
然而,随后的每一个Alt都没有触发任何ChangeEvents。我搞不懂为什么..。
看见
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.ButtonModel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
public class MenuBarTest extends javax.swing.JFrame {
private javax.swing.JMenu jMenu1;
private javax.swing.JMenu jMenu2;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JMenuItem jMenuItem1;
private javax.swing.JMenuItem jMenuItem2;
private JTextField text = new JTextField("text", 10);
public MenuBarTest() {
jMenuBar1 = new javax.swing.JMenuBar();
jMenu1 = new javax.swing.JMenu();
jMenu1.addMenuListener(new MenuListener() {
@Override
public void menuSelected(MenuEvent e) {
System.out.println("MenuListener - Selected: " + e.toString());
}
@Override
public void menuDeselected(MenuEvent e) {
System.out.println("MenuListener - Deselected: " + e.toString());
}
@Override
public void menuCanceled(MenuEvent e) {
System.out.println("MenuListener - Canceled: " + e.toString());
}
});
jMenu1.getModel().addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
ButtonModel model = (ButtonModel) e.getSource();
if (model.isArmed()) {
System.out.println("ButtonModel - Armed: " + e.toString());
} else if (model.isEnabled()) {
System.out.println("ButtonModel - Enabled: " + e.toString());
} else if (model.isPressed()) {
System.out.println("ButtonModel - Pressed: " + e.toString());
} else if (model.isRollover()) {
System.out.println("ButtonModel - Rollover: " + e.toString());
} else if (model.isSelected()) {
System.out.println("ButtonModel - Selected: " + e.toString());
} else {
System.out.println("ButtonModel - !!!!!????: " + e.toString());
}
}
});
jMenuItem1 = new javax.swing.JMenuItem();
jMenu2 = new javax.swing.JMenu();
jMenuItem2 = new javax.swing.JMenuItem();
jMenu1.setText("File");
jMenuItem1.setText("jMenuItem1");
jMenu1.add(jMenuItem1);
jMenuBar1.add(jMenu1);
jMenu2.setText("Edit");
jMenuItem2.setText("jMenuItem2");
jMenu2.add(jMenuItem2);
jMenuBar1.add(jMenu2);
jMenuBar1.setVisible(false);
jMenuBar1.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
String strPropertyName = evt.getPropertyName();
System.out.println("PropertyChangeListener - NewValue: " + evt.getNewValue());
System.out.println("PropertyChangeListener - OldValue: " + evt.getOldValue());
System.out.println("PropertyChangeListener - PropagationId: " + evt.getPropagationId());
System.out.println("PropertyChangeListener - PropertyName: " + evt.getPropertyName());
if ("MENU.MP_BARBACKGROUND".equals(strPropertyName)) {
System.out.println("PropertyChangeListener - MENU.MP_BARBACKGROUND: " + evt.getNewValue());
}
}
});
jMenuBar1.getSelectionModel().addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
System.out.println("ChangeListener - " + e.toString());
jMenuBar1.setVisible(jMenuBar1.isSelected());
System.out.println("ChangeListener - " + jMenuBar1.isSelected());
System.out.println("ChangeListener - " + jMenuBar1.getSelectionModel().isSelected());
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
text.grabFocus();
text.requestFocusInWindow();
text.setText(text.getText());
text.selectAll();
}
});
}
});
setJMenuBar(jMenuBar1);
add(text, BorderLayout.NORTH);
add(new JTextField("text", 10), BorderLayout.SOUTH);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(400, 300));
pack();
}
public static void main(String args[]) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new MenuBarTest().setVisible(true);
}
});
}
}https://stackoverflow.com/questions/18093773
复制相似问题