首页 > 解决方案 > JavaFX 应用程序:为什么在 MenuButton 上单击一次左键会导致 ContextMenu 闪烁?

问题描述

我不明白为什么当我左键单击 MenuButton 时,ContextMenu 不会简单地出现和停留,或者当我第二次单击时像可见性切换一样消失。下面详细介绍了一个简短的代码示例和我的经验。

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.*;

public class BtnTest extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Scene scene = new Scene(new MenuButton("Options", null, new MenuItem("test1"), new MenuItem("test2")), 650, 500);
        primaryStage.setTitle("Testing Btn");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

我在 Windows 10 上的 BlueJ IDE 中运行这个简单的代码

  1. 如果我单击 MenuButton,应用程序窗口似乎被聚焦然后失去焦点,并且按钮的 ContextMenu 出现然后消失。
  2. 如果我再次单击,则 ContextMenu 会出现并保留(即使我从应用程序窗口单击到另一个程序)。
  3. 如果我第三次单击,ContextMenu 就会消失。
  4. 如果我第四次单击,ContextMenu 会再次闪烁。
  5. 如果我第五次单击,则 ContextMenu 会出现并保持不变。
  6. 如果我第六次单击,ContextMenu 就会消失。

这种情况继续重复。

标签: javajavafxcontextmenumenuitembluej

解决方案


我可能是错的,但问题似乎是 ContextMenu/PopupWindow 的 autoHide 布尔属性默认设置为 true。当您单击 MenuButton 以显示 MenuItems 时,MenuButton 使用默认的 ContextMenu。

我试图将 MenuButton 的 ContextMenu 设置为预定义的 ContextMenu,其中一个 autoHide 设置为 false,但这会导致事件重叠,导致它在单击时显示然后隐藏,或者 ContextMenu 被 MenuButton 设置回 null?

无论哪种方式,我找到了一个解决方案,通过切换到彼此分开使用 Button 和 ContextMenu,并将 ContextMenu 的 autoHide 设置为 false:

import javafx.geometry.Side;
import javafx.event.Event;
import javafx.event.EventHandler;

public class BtnTest2 extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        
        Button btn = new Button("Options");
        
        MenuItem item1 = new MenuItem("test1");
        MenuItem item2 = new MenuItem("test2");
        
        ContextMenu cm = new ContextMenu();
        cm.setAutoHide(false);
        cm.getItems().addAll(item1, item2);
        
        
        btn.addEventHandler(ActionEvent.ACTION, e -> {
            cm.show(btn, Side.BOTTOM, 0, 0);
            e.consume();
        });
        
        
        Scene scene = new Scene(btn, 650, 500);
        primaryStage.setTitle("Testing Btn");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

推荐阅读