我需要关于JTree和JPopupMenu的nimbus行为的帮助。我正在设置一个右键菜单到一个JTree。如果我在打开带有另一个节点的右键菜单后单击某个节点,单击的节点将被选中。但是在nimbus的外观和感觉中,选择另一个节点需要第二次单击。我的代码如下所示,您可以使用默认的外观来尝试它,并通过注释nimbus部分来感受它。
public class JTreeDemo {
public static void main(String[] args) {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception ex) {
}
}
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Root");
rootNode.add(new DefaultMutableTreeNode("Child1"));
rootNode.add(new DefaultMutableTreeNode("Child2"));
rootNode.add(new DefaultMutableTreeNode("Child3"));
DefaultTreeModel model = new DefaultTreeModel(rootNode);
JTree tree = new JTree(model);
tree.addMouseListener(new TreeMouseListener());
JFrame jf = new JFrame();
jf.getContentPane().add(new JScrollPane(tree));
jf.setSize(new Dimension(300, 300));
jf.setVisible(true);
}
}
class TreeMouseListener extends MouseAdapter {
@Override
public void mouseReleased(MouseEvent e) {
if(SwingUtilities.isRightMouseButton(e)) {
JTree tree = (JTree) e.getSource();
TreePath jClickedPath = tree.getPathForLocation(e.getX(), e.getY());
tree.setSelectionPath(jClickedPath);
JPopupMenu menu = new JPopupMenu();
menu.add(new JMenuItem("menu1"));
menu.show(tree, e.getX(), e.getY());
}
}
}发布于 2016-01-11 08:59:59
如果打印出按下的、释放的和单击的鼠标事件,您将看到默认的L&F。
// right click
tree: pressed
tree: released
tree: clicked
// click on node
tree: pressed
tree: released
tree: clicked然而,在Nimbus L&F中,你可以得到
// right click
tree: pressed
tree: released
tree: clicked
// first click on node, the pressed event is not passed to the listener
tree: released
tree: clicked
// second click on node
tree: pressed
tree: released
tree: clicked这是Nimbus弹出窗口在关闭时使用该事件所需的行为。(请参见错误报告#JDK-6770445中的解释)
您可以在设置L&F之后更改此行为。
UIManager.setLookAndFeel(info.getClassName());
UIManager.put("PopupMenu.consumeEventOnClose", false);编辑片段,仅更改特定JTree的默认行为
// instruct the JTree not to close the popup
tree.putClientProperty("doNotCancelPopup",
new JComboBox().getClientProperty("doNotCancelPopup"));
// create the popup menu not inside the listener
JPopupMenu popup = new JPopupMenu();
popup.add(new JMenuItem("menu1"));
// add the listener to the JTree
MouseListener popupListener = new PopupListener(popup);
tree.addMouseListener(popupListener);以编程方式显示和隐藏弹出窗口
static class PopupListener extends MouseAdapter {
JPopupMenu popup;
PopupListener(JPopupMenu popupMenu) {
popup = popupMenu;
}
@Override
public void mousePressed(MouseEvent e) {
togglePopup(e);
}
@Override
public void mouseReleased(MouseEvent e) {
togglePopup(e);
}
private void togglePopup(MouseEvent e) {
if (e.isPopupTrigger()) {
popup.show(e.getComponent(), e.getX(), e.getY());
} else if (popup.isVisible()) {
popup.setVisible(false);
}
}
}发布于 2016-01-08 19:35:08
有两种解决方案,您可以在不改变nimbus的情况下尝试:
1.模拟使用机器人类的第二次单击。
将这个添加到MouseListener中。
if(SwingUtilities.isLeftMouseButton(e) && e.getSource() instanceof JTree) {
Robot bot = null;
try {
bot = new Robot();
} catch (AWTException e1) {
e1.printStackTrace();
}
bot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
}2.添加TreeSelectionLisitener,与第一种方法相同,使用MouseListener使用TreeSelectionListener选择合适的节点。
https://stackoverflow.com/questions/34679216
复制相似问题