1

我正在尝试在 JavaFX 项目中使用 Undecorated 阶段,stage.initStyle(StageStyle.UNDECORATED);. 这是一个模块化的 Gradle 项目。它也是一个多项目构建,虽然因为我在 IntelliJ 中工作,所以将它称为多模块构建可能更合适。

我希望能够向这个未装饰阶段添加常规功能。我已经能够添加通常的最小化、恢复和关闭按钮,但是如果用户单击 Windows 任务栏中的程序图标,我希望它也能最小化和恢复。

在此处输入图像描述

我在这个较旧的 StackOverflow 帖子中找到了可能会执行此操作的代码,但我遇到了一个我无法弄清楚的错误。

布赖恩(海报的)代码:

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 文件中的名称。这是我有能力做的事情,但我的谷歌搜索结果很少,这解释了这个包的来源。这个 SO question下的评论表明根本不应该使用这样的 com.sun 包,并且似乎暗示可能有一些等效的更好的使用。

4

1 回答 1

1

我在 Windows 10 中遇到了同样的问题。谢天谢地,@Slaw 的建议是正确的。

您需要转到 IDE 中的 VM 选项(在 IntelliJ 中运行 -> 编辑配置...)并添加以下内容:

--add-exports
javafx.graphics/com.sun.glass.ui=ALL-UNNAMED

它应该在那之后工作。

于 2020-01-15T02:06:53.830 回答