JavaFX:ChangeListener 获取鼠标屏幕的分辨率
JavaFX : ChangeListener to get the resolution of screen on mouse released
如何获得屏幕应用程序的分辨率(在调整大小期间),但只有在释放鼠标后才能获得?
我环顾四周,但一无所获。我已经这样做了:
scene.widthProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
ConfigBusiness.getInstance().setScreenWidth(newValue.intValue());
}
});
scene.heightProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
ConfigBusiness.getInstance().setScreenHeight(newValue.intValue());
}
});
但如您所料,每次宽度/高度更改时,它都会调用函数来保存值(在我的例子中,在注册表中,这会导致多次调用)。
有没有办法只在释放鼠标按钮时获取值?或者也许使用另一种侦听器(setOnMouseDragRelease
或类似的东西)?
编辑:我希望用户能够调整应用程序的大小window,一旦他在调整大小后释放鼠标按钮,我想触发一个事件(而不是在整个调整大小的过程中)。
谢谢
编辑 2:根据@Tomas Bisciak 的一些想法,我想出了这个主意。
scene.widthProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
if(!widthHasChanged()){
setWidthChanged(true);
System.out.println("Width changed");
}
}
});
scene.heightProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
if(!heightHasChanged()){
setHeightChanged(true);
System.out.println("Height changed");
}
}
});
scene.addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if(widthHasChanged()){
ConfigBusiness.getInstance().setScreenWidth(scene.getWidth());
System.out.println("Width changed > release");
setWidthChanged(false);
}
if(heightHasChanged()){
ConfigBusiness.getInstance().setScreenHeight(scene.getHeight());
System.out.println("Height changed > release");
setHeightChanged(false);
}
}
});
我标记了在调整大小过程中所做的更改(在 widthProperty
和 heightProperty
的帮助下)并在更改时将它们设置为 true,然后在释放鼠标时设置值如果他们改变了。
问题是最后一个事件MOUSE_RELEASED
没有被触发。我看到了 changeListener
的输出,但没有看到 eventFilter
的输出。有什么想法吗?
将侦听器挂接到场景 Handle mouse event anywhere with JavaFX(使用 MouseEvent.MOUSE_RELEASED)并在鼠标释放时写入 setScreenHeight/width(在每次鼠标释放时)的值,
如果您只想在发生拖动以调整大小时写入值,请在 change() "flag=true on change" 方法中使用布尔标志来指示更改已经开始,鼠标释放后只需在您想要的任何地方写入值并将标志设置为 (flag=false).
如果你想在每次松开鼠标的时候得到Monitor Screen的分辨率,代码如下:
假设您有 Stage
和 Scene
的代码,您可以像这样为 MouseReleased
Event
添加监听器:
public double screenWidth ;
public double screenHeight;
.......
scene.setOnMouseReleased(m->{
screenWidth = Screen.getPrimary().getBounds().getWidth();
screenHeight = Screen.getPrimary().getBounds().getHeight();
});
......
In case you have an undecorated window that you resize it manually
when the mouse is dragged i recommend you using setOnMouseDragged();
Assuming that you are doing the above this code for moving the window
manually can be useful:
public int initialX;
public int initialY;
public double screenWidth = Screen.getPrimary().getBounds().getWidth() ;
public double screenHeight = Screen.getPrimary().getBounds().getHeight();
setOnMousePressed(m -> {
if (m.getButton() == MouseButton.PRIMARY) {
if (m.getClickCount() == 1) { // one Click
setCursor(Cursor.MOVE);
if (window.getWidth() < screenWidth ) {
initialX = (int) (window.getX() - m.getScreenX());
initialY = (int) (window.getY() - m.getScreenY());
} else
setFullScreen(false);
} else if (m.getClickCount() == 2) // two clicks
setFullScreen(true);
}
});
setOnMouseDragged(m -> {
if (window.getWidth() < screenWidth && m.getButton() == MouseButton.PRIMARY) {
window.setX(m.getScreenX() + initialX);
window.setY(m.getScreenY() + initialY);
}
});
setOnMouseReleased(m -> setCursor(Cursor.DEFAULT));
我终于找到了一种方法来完成 "more or less" 我想要的。这是为正在寻找操作方法的人提供的代码。
ChangeListener<Number> resizeListener = new ChangeListener<Number>() {
Timer timer = null; // used to schedule the saving task
final long delay = 200; // the delay between 2 changes
TimerTask task = null; // the task : saves resolution values
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
// cancels the old task as a new one has been queried
// at every change, we cancel the old task and start a new one
if(task != null) task.cancel();
// reset of the timer
if(timer == null) timer = new Timer();
task = new TimerTask() {
@Override
public void run() {
ConfigBusiness.getInstance().setScreenWidth(scene.getWidth());
ConfigBusiness.getInstance().setScreenHeight(scene.getHeight());
// stopping the timer once values are set
timer.cancel();
timer = null;
// stopping the task once values are set
task.cancel();
task = null;
}
};
timer.schedule(task, delay);
}
};
scene.widthProperty().addListener(resizeListener);
scene.heightProperty().addListener(resizeListener);
我添加了一些评论只是为了帮助理解它的工作方式。在调整大小时,计时器会安排一个任务来检索 window 的宽度/高度并启动。
如果另一个更改收入,则任务是 "reset" 以便仅获取最后一组值。
检索到值后,清除计时器和任务很重要,否则线程将继续运行。
感谢所有给我提示的人,希望这对您有所帮助!
如何获得屏幕应用程序的分辨率(在调整大小期间),但只有在释放鼠标后才能获得?
我环顾四周,但一无所获。我已经这样做了:
scene.widthProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
ConfigBusiness.getInstance().setScreenWidth(newValue.intValue());
}
});
scene.heightProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
ConfigBusiness.getInstance().setScreenHeight(newValue.intValue());
}
});
但如您所料,每次宽度/高度更改时,它都会调用函数来保存值(在我的例子中,在注册表中,这会导致多次调用)。
有没有办法只在释放鼠标按钮时获取值?或者也许使用另一种侦听器(setOnMouseDragRelease
或类似的东西)?
编辑:我希望用户能够调整应用程序的大小window,一旦他在调整大小后释放鼠标按钮,我想触发一个事件(而不是在整个调整大小的过程中)。
谢谢
编辑 2:根据@Tomas Bisciak 的一些想法,我想出了这个主意。
scene.widthProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
if(!widthHasChanged()){
setWidthChanged(true);
System.out.println("Width changed");
}
}
});
scene.heightProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
if(!heightHasChanged()){
setHeightChanged(true);
System.out.println("Height changed");
}
}
});
scene.addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if(widthHasChanged()){
ConfigBusiness.getInstance().setScreenWidth(scene.getWidth());
System.out.println("Width changed > release");
setWidthChanged(false);
}
if(heightHasChanged()){
ConfigBusiness.getInstance().setScreenHeight(scene.getHeight());
System.out.println("Height changed > release");
setHeightChanged(false);
}
}
});
我标记了在调整大小过程中所做的更改(在 widthProperty
和 heightProperty
的帮助下)并在更改时将它们设置为 true,然后在释放鼠标时设置值如果他们改变了。
问题是最后一个事件MOUSE_RELEASED
没有被触发。我看到了 changeListener
的输出,但没有看到 eventFilter
的输出。有什么想法吗?
将侦听器挂接到场景 Handle mouse event anywhere with JavaFX(使用 MouseEvent.MOUSE_RELEASED)并在鼠标释放时写入 setScreenHeight/width(在每次鼠标释放时)的值,
如果您只想在发生拖动以调整大小时写入值,请在 change() "flag=true on change" 方法中使用布尔标志来指示更改已经开始,鼠标释放后只需在您想要的任何地方写入值并将标志设置为 (flag=false).
如果你想在每次松开鼠标的时候得到Monitor Screen的分辨率,代码如下:
假设您有 Stage
和 Scene
的代码,您可以像这样为 MouseReleased
Event
添加监听器:
public double screenWidth ;
public double screenHeight;
.......
scene.setOnMouseReleased(m->{
screenWidth = Screen.getPrimary().getBounds().getWidth();
screenHeight = Screen.getPrimary().getBounds().getHeight();
});
......
In case you have an undecorated window that you resize it manually when the mouse is dragged i recommend you using
setOnMouseDragged();
Assuming that you are doing the above this code for moving the window manually can be useful:
public int initialX;
public int initialY;
public double screenWidth = Screen.getPrimary().getBounds().getWidth() ;
public double screenHeight = Screen.getPrimary().getBounds().getHeight();
setOnMousePressed(m -> {
if (m.getButton() == MouseButton.PRIMARY) {
if (m.getClickCount() == 1) { // one Click
setCursor(Cursor.MOVE);
if (window.getWidth() < screenWidth ) {
initialX = (int) (window.getX() - m.getScreenX());
initialY = (int) (window.getY() - m.getScreenY());
} else
setFullScreen(false);
} else if (m.getClickCount() == 2) // two clicks
setFullScreen(true);
}
});
setOnMouseDragged(m -> {
if (window.getWidth() < screenWidth && m.getButton() == MouseButton.PRIMARY) {
window.setX(m.getScreenX() + initialX);
window.setY(m.getScreenY() + initialY);
}
});
setOnMouseReleased(m -> setCursor(Cursor.DEFAULT));
我终于找到了一种方法来完成 "more or less" 我想要的。这是为正在寻找操作方法的人提供的代码。
ChangeListener<Number> resizeListener = new ChangeListener<Number>() {
Timer timer = null; // used to schedule the saving task
final long delay = 200; // the delay between 2 changes
TimerTask task = null; // the task : saves resolution values
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
// cancels the old task as a new one has been queried
// at every change, we cancel the old task and start a new one
if(task != null) task.cancel();
// reset of the timer
if(timer == null) timer = new Timer();
task = new TimerTask() {
@Override
public void run() {
ConfigBusiness.getInstance().setScreenWidth(scene.getWidth());
ConfigBusiness.getInstance().setScreenHeight(scene.getHeight());
// stopping the timer once values are set
timer.cancel();
timer = null;
// stopping the task once values are set
task.cancel();
task = null;
}
};
timer.schedule(task, delay);
}
};
scene.widthProperty().addListener(resizeListener);
scene.heightProperty().addListener(resizeListener);
我添加了一些评论只是为了帮助理解它的工作方式。在调整大小时,计时器会安排一个任务来检索 window 的宽度/高度并启动。
如果另一个更改收入,则任务是 "reset" 以便仅获取最后一组值。
检索到值后,清除计时器和任务很重要,否则线程将继续运行。
感谢所有给我提示的人,希望这对您有所帮助!