stage/scene 和屏幕之间需要清晰
need clarity between stage/scene and screen
以下基本代码可以完美运行。它确定可用屏幕列表,然后识别最大的屏幕,然后将舞台的大小设置为等于最大监视器的尺寸。
public class MaximizedStage extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) {
ObservableList<Screen> monitors = Screen.getScreens();
//determine the larger monitor
Rectangle2D bounds = monitors.get(0).getVisualBounds(); //get the bounds of the default monitor
int preferred_mon = 0;
var x = bounds.getMinX();
var y = bounds.getMinY();
var w = bounds.getWidth();
var h = bounds.getHeight();
System.out.println("Count of monitors : "+monitors.size()+" default monitor size : w: "+w+" h: "+h);
for (int mon = 1; mon < monitors.size(); mon++) { // for each of the other monitors
Rectangle2D next_monitor_bounds = monitors.get(mon).getVisualBounds(); //get the size
if ((next_monitor_bounds.getHeight() > h) && (next_monitor_bounds.getWidth() > w)) {
//larger monitor, update parameters
preferred_mon = mon;
x = next_monitor_bounds.getMinX();
y = next_monitor_bounds.getMinY();
w = next_monitor_bounds.getWidth();
h = next_monitor_bounds.getHeight();
}
}
System.out.println("Largest monitor : index: "+preferred_mon+" w: "+w+" h: "+h);
stage.setScene(new Scene(new Group()));
stage.setTitle("Full screen");
// Set the position and size of the stage equal to the position and
// size of the screen
stage.setX(x);
stage.setY(y);
stage.setWidth(w);
stage.setHeight(h);
// Show the stage
stage.show();
}
}
我的问题是:在这段代码中,舞台(或场景)在哪里知道要显示的屏幕中的最终选择是哪个?我正在努力理解 stage/scene 和显示器选择之间的联系。最后的 objective 是准备多个不同的阶段,运行 每个阶段在不同的线程上,并将它们的输出定向到不同的监视器。
感谢您的关注。
每个屏幕的边界都是相对于某个虚拟坐标系的。边界描述了每个屏幕的宽度和高度,还描述了屏幕在该坐标系中的位置,从而定义了不同显示设备之间的相对位置。通常,这些是由 OS 级别的用户首选项设置定义的。
在我当前使用的设置中,我将 MacBook Pro 连接到外部显示器(配置为主显示器)。在系统偏好设置中,这看起来像:
这与我所拥有的物理布局非常接近。这意味着我可以将 windows 从主屏幕(如右图所示)拖动到该屏幕的左边缘,然后拖到笔记本电脑屏幕(如左图所示)上。
大屏幕尺寸为 3008x1692,笔记本电脑屏幕尺寸为 1680x1050。边界报告为
Rectangle2D [minX = 0.0, minY=0.0, maxX=3008.0, maxY=1692.0, width=3008.0, height=1692.0]
Rectangle2D [minX = -1680.0, minY=213.0, maxX=0.0, maxY=1263.0, width=1680.0, height=1050.0]
所以主屏幕列在第一位,位置为 (0,0),笔记本电脑屏幕列在第二位,向左偏移 1680 像素,比主屏幕低 213 像素。
在您的代码中,舞台的 x
和 y
坐标设置为在此选择的(最大)屏幕的 x
和 y
坐标坐标系,因此舞台的左上角将位于该屏幕的左上角。通过将舞台的宽度和高度设置为屏幕的宽度和高度,舞台将完全填满该屏幕(尽管您可能会丢失系统任务栏或停靠栏后面的一些舞台)。
这是一个类似的测试示例,它使 window 成为屏幕宽度和高度的一半,并居中:
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Screen;
import javafx.stage.Stage;
import java.io.IOException;
public class ScreenDemo extends Application {
@Override
public void start(Stage stage) throws IOException {
VBox buttons = new VBox(5);
buttons.setFillWidth(true);
buttons.setAlignment(Pos.CENTER);
int index = 1 ;
for (Screen screen : Screen.getScreens()) {
System.out.println(screen.getBounds());
Button button = new Button("Screen "+index);
button.setOnAction(e -> centerInScreen(stage, screen));
button.setMaxWidth(Double.MAX_VALUE);
buttons.getChildren().add(button);
index++;
}
HBox root = new HBox(buttons);
root.setFillHeight(true);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root);
stage.setScene(scene);
centerInScreen(stage, Screen.getPrimary());
stage.show();
}
private void centerInScreen(Stage stage, Screen screen) {
// make window half screen size and center in screen:
Rectangle2D screenBounds = screen.getBounds();
double x = screenBounds.getMinX();
double y = screenBounds.getMinY();
double w = screenBounds.getWidth();
double h = screenBounds.getHeight();
stage.setX(x + w/4);
stage.setY(y + h/4);
stage.setWidth(w/2);
stage.setHeight(h/2);
}
public static void main(String[] args) {
launch();
}
}
这是一个类似的示例,它在每个屏幕中都将舞台居中:
import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Screen;
import javafx.stage.Stage;
import java.io.IOException;
public class ScreenDemo extends Application {
@Override
public void start(Stage stage) throws IOException {
int index = 1 ;
for (Screen screen : Screen.getScreens()) {
if (screen != Screen.getPrimary()) {
Label label = new Label("Window in screen "+index);
BorderPane root = new BorderPane(label);
Scene scene = new Scene(root);
Stage window = new Stage();
window.setScene(scene);
centerInScreen(window, screen);
window.show();
}
index++;
}
Label label = new Label("Window in primary screen");
BorderPane root = new BorderPane(label);
Scene scene = new Scene(root);
stage.setScene(scene);
centerInScreen(stage, Screen.getPrimary());
stage.show();
}
private void centerInScreen(Stage stage, Screen screen) {
// make window half screen size and center in screen:
Rectangle2D screenBounds = screen.getBounds();
double x = screenBounds.getMinX();
double y = screenBounds.getMinY();
double w = screenBounds.getWidth();
double h = screenBounds.getHeight();
stage.setX(x + w/4);
stage.setY(y + h/4);
stage.setWidth(w/2);
stage.setHeight(h/2);
}
public static void main(String[] args) {
launch();
}
}
以下基本代码可以完美运行。它确定可用屏幕列表,然后识别最大的屏幕,然后将舞台的大小设置为等于最大监视器的尺寸。
public class MaximizedStage extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) {
ObservableList<Screen> monitors = Screen.getScreens();
//determine the larger monitor
Rectangle2D bounds = monitors.get(0).getVisualBounds(); //get the bounds of the default monitor
int preferred_mon = 0;
var x = bounds.getMinX();
var y = bounds.getMinY();
var w = bounds.getWidth();
var h = bounds.getHeight();
System.out.println("Count of monitors : "+monitors.size()+" default monitor size : w: "+w+" h: "+h);
for (int mon = 1; mon < monitors.size(); mon++) { // for each of the other monitors
Rectangle2D next_monitor_bounds = monitors.get(mon).getVisualBounds(); //get the size
if ((next_monitor_bounds.getHeight() > h) && (next_monitor_bounds.getWidth() > w)) {
//larger monitor, update parameters
preferred_mon = mon;
x = next_monitor_bounds.getMinX();
y = next_monitor_bounds.getMinY();
w = next_monitor_bounds.getWidth();
h = next_monitor_bounds.getHeight();
}
}
System.out.println("Largest monitor : index: "+preferred_mon+" w: "+w+" h: "+h);
stage.setScene(new Scene(new Group()));
stage.setTitle("Full screen");
// Set the position and size of the stage equal to the position and
// size of the screen
stage.setX(x);
stage.setY(y);
stage.setWidth(w);
stage.setHeight(h);
// Show the stage
stage.show();
}
}
我的问题是:在这段代码中,舞台(或场景)在哪里知道要显示的屏幕中的最终选择是哪个?我正在努力理解 stage/scene 和显示器选择之间的联系。最后的 objective 是准备多个不同的阶段,运行 每个阶段在不同的线程上,并将它们的输出定向到不同的监视器。
感谢您的关注。
每个屏幕的边界都是相对于某个虚拟坐标系的。边界描述了每个屏幕的宽度和高度,还描述了屏幕在该坐标系中的位置,从而定义了不同显示设备之间的相对位置。通常,这些是由 OS 级别的用户首选项设置定义的。
在我当前使用的设置中,我将 MacBook Pro 连接到外部显示器(配置为主显示器)。在系统偏好设置中,这看起来像:
这与我所拥有的物理布局非常接近。这意味着我可以将 windows 从主屏幕(如右图所示)拖动到该屏幕的左边缘,然后拖到笔记本电脑屏幕(如左图所示)上。
大屏幕尺寸为 3008x1692,笔记本电脑屏幕尺寸为 1680x1050。边界报告为
Rectangle2D [minX = 0.0, minY=0.0, maxX=3008.0, maxY=1692.0, width=3008.0, height=1692.0]
Rectangle2D [minX = -1680.0, minY=213.0, maxX=0.0, maxY=1263.0, width=1680.0, height=1050.0]
所以主屏幕列在第一位,位置为 (0,0),笔记本电脑屏幕列在第二位,向左偏移 1680 像素,比主屏幕低 213 像素。
在您的代码中,舞台的 x
和 y
坐标设置为在此选择的(最大)屏幕的 x
和 y
坐标坐标系,因此舞台的左上角将位于该屏幕的左上角。通过将舞台的宽度和高度设置为屏幕的宽度和高度,舞台将完全填满该屏幕(尽管您可能会丢失系统任务栏或停靠栏后面的一些舞台)。
这是一个类似的测试示例,它使 window 成为屏幕宽度和高度的一半,并居中:
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Screen;
import javafx.stage.Stage;
import java.io.IOException;
public class ScreenDemo extends Application {
@Override
public void start(Stage stage) throws IOException {
VBox buttons = new VBox(5);
buttons.setFillWidth(true);
buttons.setAlignment(Pos.CENTER);
int index = 1 ;
for (Screen screen : Screen.getScreens()) {
System.out.println(screen.getBounds());
Button button = new Button("Screen "+index);
button.setOnAction(e -> centerInScreen(stage, screen));
button.setMaxWidth(Double.MAX_VALUE);
buttons.getChildren().add(button);
index++;
}
HBox root = new HBox(buttons);
root.setFillHeight(true);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root);
stage.setScene(scene);
centerInScreen(stage, Screen.getPrimary());
stage.show();
}
private void centerInScreen(Stage stage, Screen screen) {
// make window half screen size and center in screen:
Rectangle2D screenBounds = screen.getBounds();
double x = screenBounds.getMinX();
double y = screenBounds.getMinY();
double w = screenBounds.getWidth();
double h = screenBounds.getHeight();
stage.setX(x + w/4);
stage.setY(y + h/4);
stage.setWidth(w/2);
stage.setHeight(h/2);
}
public static void main(String[] args) {
launch();
}
}
这是一个类似的示例,它在每个屏幕中都将舞台居中:
import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Screen;
import javafx.stage.Stage;
import java.io.IOException;
public class ScreenDemo extends Application {
@Override
public void start(Stage stage) throws IOException {
int index = 1 ;
for (Screen screen : Screen.getScreens()) {
if (screen != Screen.getPrimary()) {
Label label = new Label("Window in screen "+index);
BorderPane root = new BorderPane(label);
Scene scene = new Scene(root);
Stage window = new Stage();
window.setScene(scene);
centerInScreen(window, screen);
window.show();
}
index++;
}
Label label = new Label("Window in primary screen");
BorderPane root = new BorderPane(label);
Scene scene = new Scene(root);
stage.setScene(scene);
centerInScreen(stage, Screen.getPrimary());
stage.show();
}
private void centerInScreen(Stage stage, Screen screen) {
// make window half screen size and center in screen:
Rectangle2D screenBounds = screen.getBounds();
double x = screenBounds.getMinX();
double y = screenBounds.getMinY();
double w = screenBounds.getWidth();
double h = screenBounds.getHeight();
stage.setX(x + w/4);
stage.setY(y + h/4);
stage.setWidth(w/2);
stage.setHeight(h/2);
}
public static void main(String[] args) {
launch();
}
}