“上下文菜单”模式的控件需要有下面的行为特征:
当鼠标在窗口外部点击时,或者控件失去焦点、被 deacitvated 时,应该自动关闭。
其他GUI框架中,这种特性可以响应 deactivated event 来实现,但 JavaFX 的 window/stage 并没有这个事件。
但 JavaFX 中有一个特殊的类,PopupWindow 及其子类 Popup 可以用来实现这个功能。
查看 PopupWindow 的代码可以发现,原来 Window 类中有一个 increaseFocusGrabCounter() 函数,可以强制获取焦点,但可惜的是这个类是 package 访问权限,外部的使用者无法调用。
示例代码
package javafx;
import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Popup;
import javafx.stage.Stage;
public class PopupWindowExample extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
TextField textField = new TextField("显示popup");
primaryStage.setScene(new Scene(new VBox(textField)));
primaryStage.setWidth(500);
primaryStage.setHeight(600);
textField.setOnMouseClicked(event -> {
Popup popup = new Popup();
VBox vbox = new VBox(new CheckBox("左高低"),
new CheckBox("左高低"), new CheckBox("左高低")
);
vbox.setStyle("-fx-background-color: lightgreen");
popup.getContent().add(vbox);
popup.setAutoHide(true);
Point2D screenLoc = textField.localToScreen(0, textField.getHeight() + 5);
popup.show(primaryStage, screenLoc.getX(), screenLoc.getY());
});
primaryStage.show();
}
}