我一直在尝试Tornadofx。试图创建一个自定义标题栏,这是我当前正在尝试的代码
fun main(args: Array<String>) {
launch<MyApp>(args)
}
class MyApp : App(Title::class) {
override fun start(stage: Stage) {
stage.initStyle(StageStyle.UNDECORATED)
stage.minWidth = 600.0
stage.minHeight = 450.0
stage.isMaximized = false
super.start(stage)
}
}
class Title : View() {
private var xOffset = 0.0
private var yOffset = 0.0
private var screenBounds: Rectangle2D = Screen.getPrimary().visualBounds
private var originalBounds: Rectangle2D = Rectangle2D.EMPTY
init {
primaryStage.isMaximized = false
}
override val root = borderpane {
onMousePressed = EventHandler { ev ->
xOffset = primaryStage.x - ev.screenX
yOffset = primaryStage.y - ev.screenY
}
onMouseDragged = EventHandler { ev ->
primaryStage.x = xOffset + ev.screenX
primaryStage.y = yOffset + ev.screenY
}
center = label("Forms")
right = hbox {
button("Mi") {
action {
with(primaryStage) { isIconified = true }
}
}
button("Ma") {
action {
if (primaryStage.isMaximized) {
with(primaryStage) {
x = originalBounds.minX
y = originalBounds.minY
width = originalBounds.width
height = originalBounds.height
isMaximized = false
}
text = "Ma"
} else {
with(primaryStage) {
originalBounds = Rectangle2D(x, y, width, height)
x = screenBounds.minX
y = screenBounds.minY
width = screenBounds.width
height = screenBounds.height
isMaximized = true
}
text = "Re"
}
}
}
button("X") {
action {
app.stop()
println("exiting")
exitProcess(0)
}
}
}
}
}
以下工作没有问题
但是当最大化的窗口最小化到任务栏,然后从任务栏打开时,它将变为全屏显示(任务栏处于隐藏状态)
我该如何解决此问题,我的代码中是否有任何部分错误,需要更改或需要任何包含?
我的配置是Windows 10 64位,Java 11.0.2,Kotlin 1.4.21,JavaFx 11.0.2,TornadoFx 1.7.20
我认为这是JavaFX中的一个普遍问题(我的意思不是TornadoFX特定)。
造成此问题的根本原因是因为将stage的maximum属性设置为true。不确定JavaFX在内部做什么,但是当您从任务栏打开窗口并且如果最大值为true时,它将以全屏模式呈现。
您可以通过两种方式解决此问题。
方法1:
从任务栏打开窗口时,iconfied属性将关闭,如果最大化为true,则将舞台尺寸再次设置为屏幕边界。
primaryStage.iconifiedProperty().addListener((obs,old,iconified)->{
if(!iconified && primaryStage.isMaximized()){
primaryStage.setWidth(screenBounds.getWidth());
primaryStage.setHeight(screenBounds.getHeight());
}
});
方法2:
不要依赖舞台的最大化属性。我相信您需要该属性来切换窗口尺寸。因此,应维护一个实例变量来进行处理。
boolean maximized = false;
ma.setOnAction(e -> {
if (maximized) {
// Set stage to original bounds
maximized = false;
ma.setText("Ma");
} else {
// Set stage to screen bounds
maximized = false;
ma.setText("Re");
}
});
下面是这两种方法的完整工作演示。您可以根据其他要求决定要走的路。
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class UndecoratedWindowFullScreenDemo extends Application {
private double xOffset = 0.0;
private double yOffset = 0.0;
private Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
private Rectangle2D originalBounds = Rectangle2D.EMPTY;
private boolean maximized = false;
@Override
public void start(Stage primaryStage) throws Exception {
BorderPane root = new BorderPane();
root.setStyle("-fx-background-color:pink;");
Scene scene = new Scene(root, 600, 450);
primaryStage.setScene(scene);
Label label = new Label("Forums");
Button mi = new Button("Mi");
Button ma = new Button("Ma");
Button x = new Button("X");
HBox pane = new HBox(mi, ma, x);
pane.setPadding(new Insets(3));
pane.setSpacing(5);
root.setCenter(label);
root.setRight(pane);
primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.setMinWidth(600);
primaryStage.setMinHeight(450);
primaryStage.setMaximized(false);
primaryStage.show();
root.setOnMousePressed(e -> {
xOffset = primaryStage.getX() - e.getScreenX();
yOffset = primaryStage.getY() - e.getScreenY();
});
root.setOnMouseDragged(e -> {
primaryStage.setX(xOffset + e.getScreenX());
primaryStage.setY(yOffset + e.getScreenY());
});
mi.setOnAction(e -> primaryStage.setIconified(true));
/* Use this approach if you want to go with the Stage maximized property */
// approach1(primaryStage, ma);
/* Use this approach if you want to avoid Stage maximized property and maintain a instance variable */
approach2(primaryStage, ma);
}
private void approach1(Stage primaryStage, Button ma) {
primaryStage.iconifiedProperty().addListener((obs, old, iconified) -> {
if (!iconified && primaryStage.isMaximized()) {
primaryStage.setWidth(screenBounds.getWidth());
primaryStage.setHeight(screenBounds.getHeight());
}
});
ma.setOnAction(e -> {
if (primaryStage.isMaximized()) {
primaryStage.setX(originalBounds.getMinX());
primaryStage.setY(originalBounds.getMinY());
primaryStage.setWidth(originalBounds.getWidth());
primaryStage.setHeight(originalBounds.getHeight());
primaryStage.setMaximized(false);
ma.setText("Ma");
} else {
originalBounds = new Rectangle2D(primaryStage.getX(), primaryStage.getY(), primaryStage.getWidth(), primaryStage.getHeight());
primaryStage.setX(screenBounds.getMinX());
primaryStage.setY(screenBounds.getMinY());
primaryStage.setWidth(screenBounds.getWidth());
primaryStage.setHeight(screenBounds.getHeight());
primaryStage.setMaximized(true);
ma.setText("Re");
}
});
}
private void approach2(Stage primaryStage, Button ma) {
ma.setOnAction(e -> {
if (maximized) {
primaryStage.setX(originalBounds.getMinX());
primaryStage.setY(originalBounds.getMinY());
primaryStage.setWidth(originalBounds.getWidth());
primaryStage.setHeight(originalBounds.getHeight());
maximized = false;
ma.setText("Ma");
} else {
originalBounds = new Rectangle2D(primaryStage.getX(), primaryStage.getY(), primaryStage.getWidth(), primaryStage.getHeight());
primaryStage.setX(screenBounds.getMinX());
primaryStage.setY(screenBounds.getMinY());
primaryStage.setWidth(screenBounds.getWidth());
primaryStage.setHeight(screenBounds.getHeight());
maximized = true;
ma.setText("Re");
}
});
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句