使用自定义标题栏管理 Windows Aero 抖动功能
Manage Windows Aero shake feature with custom title bar
有很多与使用 JavaFX 自定义标题栏相关的教程或问题
我创建了一个这样的自定义标题栏:
我可以移动 windows 但现在(因为 windows 是 UNDECORATED
我不能应用任何 Windows 像 Aero shake
这样的原生功能(如果你摇一摇window,其他的app都减少了)
是否有任何解决方案可以使用自定义标题栏来管理此类功能?
这是我的代码:
start.java:
@Override
public void start(Stage primaryStage) throws Exception{
setPrimaryStage(primaryStage);
prStage = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("../gui/main.fxml"));
prStage.initStyle(StageStyle.UNDECORATED);
//prStage.setOpacity(0.75);
Scene scene = new Scene(root, 640, 360);
prStage.setScene(scene);
prStage.getIcons().add(new Image("/resource/Images/icon.png"));
scene.getStylesheets().add(getClass().getResource("..//gui/css/NewUICSS.css").toExternalForm());
prStage.show();
}
主控制器:
public class NewUIController {
private static double xOffset = 0;
private static double yOffset = 0;
public void initialize() {
moveBar.setOnMousePressed(this::mousePressed);
moveBar.setOnMouseDragged(this::mouseDrag);
moveBar.setOnMouseReleased(this::mouseRealease);
mnuBar.setOnMousePressed(this::mousePressed);
mnuBar.setOnMouseDragged(this::mouseDrag);
mnuBar.setOnMouseReleased(this::mouseRealease);
}
private void mouseDrag(MouseEvent event){
MainJavaFx.getPrimaryStage().setX(event.getScreenX() - xOffset);
MainJavaFx.getPrimaryStage().setY(event.getScreenY() - yOffset);
}
private void mouseRealease(MouseEvent event){
if(event.getSceneY() == 0){
MainJavaFx.getPrimaryStage().setY(0);
}else if(MainJavaFx.getPrimaryStage().getY() < 0){
MainJavaFx.getPrimaryStage().setY(0);
}
}
private void mousePressed(MouseEvent event){
xOffset = event.getSceneX();
yOffset = event.getSceneY();
}
public void close(){
((Stage)pnPrincipal.getScene().getWindow()).close();
}
}
所有这些问题仅在 windows 上存在,因此我们需要使用不同于未修饰样式的其他 "style" 来管理所有 windows 功能。
您需要使用两个库:
- jna : 点你 windows
- jna-platform : 创建合适的样式
public void start(Stage primaryStage) throws Exception{
setPrimaryStage(primaryStage);
prStage = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("../gui/NewUI2.fxml"));
primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.setScene(new Scene(root, 1280, 720));
Main.getPrimaryStage().getScene().getStylesheets().add(getClass().getResource("..//gui/css/main-black.css").toExternalForm());
primaryStage.show();
// verify if it is windows
if(System.getProperty("os.name").indexOf("win") >= 0)
long lhwnd = com.sun.glass.ui.Window.getWindows().get(0).getNativeWindow();
Pointer lpVoid = new Pointer(lhwnd);
WinDef.HWND hwnd = new WinDef.HWND(lpVoid);
final User32 user32 = User32.INSTANCE;
int oldStyle = user32.GetWindowLong(hwnd, WinUser.GWL_STYLE);
int newStyle = oldStyle | 0x00020000;//WS_MINIMIZEBOX
user32.SetWindowLong(hwnd, WinUser.GWL_STYLE, newStyle);
}
}
但我不知道这是否是最好的方法。
有很多与使用 JavaFX 自定义标题栏相关的教程或问题
我创建了一个这样的自定义标题栏:
我可以移动 windows 但现在(因为 windows 是 UNDECORATED
我不能应用任何 Windows 像 Aero shake
这样的原生功能(如果你摇一摇window,其他的app都减少了)
是否有任何解决方案可以使用自定义标题栏来管理此类功能?
这是我的代码:
start.java:
@Override
public void start(Stage primaryStage) throws Exception{
setPrimaryStage(primaryStage);
prStage = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("../gui/main.fxml"));
prStage.initStyle(StageStyle.UNDECORATED);
//prStage.setOpacity(0.75);
Scene scene = new Scene(root, 640, 360);
prStage.setScene(scene);
prStage.getIcons().add(new Image("/resource/Images/icon.png"));
scene.getStylesheets().add(getClass().getResource("..//gui/css/NewUICSS.css").toExternalForm());
prStage.show();
}
主控制器:
public class NewUIController {
private static double xOffset = 0;
private static double yOffset = 0;
public void initialize() {
moveBar.setOnMousePressed(this::mousePressed);
moveBar.setOnMouseDragged(this::mouseDrag);
moveBar.setOnMouseReleased(this::mouseRealease);
mnuBar.setOnMousePressed(this::mousePressed);
mnuBar.setOnMouseDragged(this::mouseDrag);
mnuBar.setOnMouseReleased(this::mouseRealease);
}
private void mouseDrag(MouseEvent event){
MainJavaFx.getPrimaryStage().setX(event.getScreenX() - xOffset);
MainJavaFx.getPrimaryStage().setY(event.getScreenY() - yOffset);
}
private void mouseRealease(MouseEvent event){
if(event.getSceneY() == 0){
MainJavaFx.getPrimaryStage().setY(0);
}else if(MainJavaFx.getPrimaryStage().getY() < 0){
MainJavaFx.getPrimaryStage().setY(0);
}
}
private void mousePressed(MouseEvent event){
xOffset = event.getSceneX();
yOffset = event.getSceneY();
}
public void close(){
((Stage)pnPrincipal.getScene().getWindow()).close();
}
}
所有这些问题仅在 windows 上存在,因此我们需要使用不同于未修饰样式的其他 "style" 来管理所有 windows 功能。
您需要使用两个库:
- jna : 点你 windows
- jna-platform : 创建合适的样式
public void start(Stage primaryStage) throws Exception{
setPrimaryStage(primaryStage);
prStage = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("../gui/NewUI2.fxml"));
primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.setScene(new Scene(root, 1280, 720));
Main.getPrimaryStage().getScene().getStylesheets().add(getClass().getResource("..//gui/css/main-black.css").toExternalForm());
primaryStage.show();
// verify if it is windows
if(System.getProperty("os.name").indexOf("win") >= 0)
long lhwnd = com.sun.glass.ui.Window.getWindows().get(0).getNativeWindow();
Pointer lpVoid = new Pointer(lhwnd);
WinDef.HWND hwnd = new WinDef.HWND(lpVoid);
final User32 user32 = User32.INSTANCE;
int oldStyle = user32.GetWindowLong(hwnd, WinUser.GWL_STYLE);
int newStyle = oldStyle | 0x00020000;//WS_MINIMIZEBOX
user32.SetWindowLong(hwnd, WinUser.GWL_STYLE, newStyle);
}
}
但我不知道这是否是最好的方法。