Dee*_*pan 6 javafx kotlin tornadofx
我一直在尝试 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)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下工作没有问题
但是当最大化的窗口最小化到任务栏,然后从任务栏打开时,它会全屏显示(任务栏被隐藏)
我如何解决此行为,我的代码是否有任何部分错误、需要更改或需要包含任何内容?
我的配置是 Windows 10 64 位、Java 11.0.2、Kotlin 1.4.21、JavaFx 11.0.2、TornadoFx 1.7.20
我认为这是 JavaFX 中的普遍问题(我的意思不是 TornadoFX 特有的问题)。
造成这种情况的根本原因是因为将stage的maximized属性设置为true。不确定 JavaFX 内部做了什么,但是当您从任务栏打开窗口时,如果最大值为 true,则它将以全屏模式呈现。
您可以通过两种方式解决此问题。
方法#1:
当从任务栏打开窗口时, iconfied 属性将关闭,如果最大化为 true,则将舞台尺寸再次设置为屏幕边界。
primaryStage.iconifiedProperty().addListener((obs,old,iconified)->{
if(!iconified && primaryStage.isMaximized()){
primaryStage.setWidth(screenBounds.getWidth());
primaryStage.setHeight(screenBounds.getHeight());
}
});
Run Code Online (Sandbox Code Playgroud)
方法#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");
}
});
Run Code Online (Sandbox Code Playgroud)
下面是这两种方法的完整工作演示。您可以根据您的其他要求决定走哪条路。
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");
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
175 次 |
| 最近记录: |