gpt4 book ai didi

java - 如何知道窗口大小的调整是从左侧还是从右侧完成?

转载 作者:行者123 更新时间:2023-12-01 13:04:52 25 4
gpt4 key购买 nike

我正在使用 JavaFX 构建 GUI,但在调整大小时了解鼠标位置时遇到问题。这个想法是,如果鼠标到达 GUI 的最边缘,它会变为双向箭头,指示您现在可以按下鼠标并调整窗口大小。

我需要鼠标指针在此边缘上的位置,但我不知道该怎么做。我需要知道窗口大小调整的方向。

最佳答案

更新添加了新选项并讨论了优缺点。

这很棘手。问题在于窗口会跟踪其顶部、左侧、宽度和高度。当从右侧或底部调整大小时,事情很简单:宽度或高度发生变化。但是当它从左侧调整大小时,x 和宽度都必须改变。这两个更改不会自动发生,因为 x 和 width 存储为两个独立的属性。

第一种方法是跟踪鼠标坐标,然后查看它是在左半部分还是右半部分。 (显然,您可以对高度执行相同的操作。)此方法独立于任何实现细节,但用户如果对鼠标非常小心,可能会导致它失败。如果将鼠标移动到窗口的右边缘,精确到窗口边界的像素,然后调整大小,您会看到不正确的输出。

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;

public class Main extends Application {
@Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);

class MouseLocation {
double x,y ;
}

MouseLocation mouseLocation = new MouseLocation();
scene.setOnMouseMoved(event -> {
mouseLocation.x = event.getX();
mouseLocation.y = event.getY();
});

primaryStage.widthProperty().addListener((obs, oldWidth, newWidth) -> {
if (mouseLocation.x < primaryStage.getWidth() / 2) {
System.out.println("Resized from left");
} else {
System.out.println("Resized from right");
}
});

primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {
launch(args);
}
}

第二种方法是跟踪窗口最后已知的水平范围(minX 和 maxX),并在宽度变化时更新该范围。然后您可以检查 minX 或 maxX 是否已更改。这种方法的问题在于它依赖于未记录的实现细节。看来(在我的系统上,使用当前版本等),当从左侧调整窗口大小时,首先更改 x,然后更改宽度。如果在后续版本中改变这一点,则以下内容将被破坏:

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;

public class Main extends Application {
@Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);

class MutableDouble {
double value ;
}

MutableDouble windowLeftEdge = new MutableDouble();
primaryStage.widthProperty().addListener((obs, oldWidth, newWidth) -> {
if (primaryStage.getX() == windowLeftEdge.value) {
System.out.println("Resized from right");
} else {
System.out.println("Resized from left");
}
windowLeftEdge.value = primaryStage.getX() ;
});

primaryStage.setScene(scene);
primaryStage.show();

}

public static void main(String[] args) {
launch(args);
}
}

第三种方法(我能想到的)是将快速发生的更改合并为单个更改。正确编程有点棘手,所以我没有从头开始,而是使用 third party ReactFX framework它对“事件流”进行建模,并具有用于组合快速连续发生的事件的内置机制。这可能是此处介绍的三种解决方案中最强大的,但代价是一定程度的复杂性或包含外部框架。

import java.time.Duration;

import org.reactfx.Change;
import org.reactfx.EventStream;
import org.reactfx.EventStreams;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ObservableValue;
import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class ReactFXVersion extends Application {

@Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);

ObservableValue<Bounds> windowBounds = Bindings.createObjectBinding(() ->
new BoundingBox(primaryStage.getX(), primaryStage.getY(), primaryStage.getWidth(), primaryStage.getHeight()),
primaryStage.xProperty(), primaryStage.yProperty(), primaryStage.widthProperty(), primaryStage.heightProperty());

EventStream<Change<Bounds>> bounds = EventStreams.changesOf(windowBounds)
.reduceSuccessions((previousChange, nextChange) ->
new Change<>(previousChange.getOldValue(), nextChange.getNewValue()),
Duration.ofMillis(10));

bounds.subscribe(boundsChange -> {
Bounds newBounds = boundsChange.getNewValue();
Bounds oldBounds = boundsChange.getOldValue();
if (newBounds.getWidth() != oldBounds.getWidth()) {
if (newBounds.getMinX() != oldBounds.getMinX()) {
System.out.println("Resized from left");
} else if (newBounds.getMaxX() != oldBounds.getMaxX()) {
System.out.println("Resized from right");
}
}
if (newBounds.getHeight() != oldBounds.getHeight()) {
if (newBounds.getMinY() != oldBounds.getMinY()) {
System.out.println("Resized from top");
} else if (newBounds.getMaxY() != oldBounds.getMaxY()) {
System.out.println("Resized from bottom");
}
}
});

primaryStage.setScene(scene);
primaryStage.show();

}

public static void main(String[] args) {
launch(args);
}
}

关于java - 如何知道窗口大小的调整是从左侧还是从右侧完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23343856/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com