我正在JavaFX项目stage.initStyle(StageStyle.UNDECORATED);
中使用Undecorated阶段。这是一个模块化的Gradle项目。它也是一个multi-project build,尽管因为我正在IntelliJ中进行开发,所以将其称为多模块构建可能更合适。
我希望能够在此Undecorated阶段中添加常规功能。我已经能够添加通常的最小化,还原和关闭按钮,但是如果用户单击Windows任务栏中的程序图标,我也希望它也最小化和还原。
[我在this older StackOverflow post中发现了可能做到这一点的代码,但遇到一个我不太想知道的错误。
布莱恩(发帖人)代码:
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinUser;
import static com.sun.jna.platform.win32.WinUser.GWL_STYLE;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class JNATest extends Application {
public static void main(String[] args) { launch(args); }
@Override
public void start(Stage stage) {
TextArea ta = new TextArea("output\n");
VBox root = new VBox(5,ta);
Scene scene = new Scene(root,800,200);
stage.setTitle("Find this window");
stage.setScene(scene);
stage.show();
//gets this window (stage)
long lhwnd = com.sun.glass.ui.Window.getWindows().get(0).getNativeWindow();
Pointer lpVoid = new Pointer(lhwnd);
//gets the foreground (focused) window
final User32 user32 = User32.INSTANCE;
char[] windowText = new char[512];
HWND hwnd = user32.GetForegroundWindow();
//see what the title is
user32.GetWindowText(hwnd, windowText, 512);
//user32.GetWindowText(new HWND(lpVoid), windowText, 512);//to use the hwnd from stage
String text=(Native.toString(windowText));
//see if it's the same pointer
ta.appendText("HWND java:" + lpVoid + " HWND user32:"+hwnd+" text:"+text+"\n");
//change the window style if it's the right title
if (text.equals(stage.getTitle())){
//the style to change
int WS_DLGFRAME = 0x00400000;//s/b long I think
//not the same constant here??
ta.appendText("windows api:"+WS_DLGFRAME+" JNA: "+WinUser.SM_CXDLGFRAME);
int oldStyle = user32.GetWindowLong(hwnd, GWL_STYLE);
int newStyle = oldStyle & ~0x00400000; //bitwise not WS_DLGFRAME means remove the style
newStyle = newStyle & ~0x00040000;//WS_THICKFRAME
user32.SetWindowLong(hwnd, GWL_STYLE, newStyle);
}
}
}
导致我出错的部分是com.sun.glass.ui.Window.getWindows().get(0).getNativeWindow();
错误:
package com.sun.glass.ui is not visible
(package com.sun.glass.ui is declared in module javafx.graphics, which does not export it to module apple.orange.main)
我不太清楚这个错误。是因为我尝试在代码中使用sun.glass.ui软件包而在javafx.graphics中声明了该软件包,还是因为它位于javafx.graphics模块内部却无法访问?我最好的猜测是,该软件包属于某个模块,我不知道该模块的名称需要作为Gradle中的依赖项,还是作为我的module-info.java文件中的要求包含在内。这是我的能力,但是我的Google搜索结果很少,这说明了此软件包的来源。 this SO question下的注释表明,完全不应使用此类com.sun软件包,并且似乎暗示可能有一些等效的更好的使用方法。
我在Windows 10中遇到了同样的问题。所幸,@ Slaw的建议是正确的。
您需要转到IDE中的VM选项(在IntelliJ中运行->编辑配置...,然后添加以下内容:
--add-exports
javafx.graphics/com.sun.glass.ui=ALL-UNNAMED
它应该在那之后工作。