繁体   English   中英

在 Gnome 顶部栏中设置我的 Java Swing 应用程序标题的正确方法是什么?

[英]What is the proper way to set my Java Swing application's title in the Gnome top bar?

我正在使用以下代码在 Gnome 3 的顶部栏中设置我的 Java Swing 应用程序的标题。 但是,当我运行它时,我收到代码下方显示的警告。 有没有更好的方法在代码中设置应用程序标题? 请注意,这不是关于设置 window 本身标题的问题。

try
{
    Toolkit toolkit = Toolkit.getDefaultToolkit();
    Field awtAppClassNameField = toolkit.getClass().getDeclaredField("awtAppClassName");
    awtAppClassNameField.setAccessible(true);
    awtAppClassNameField.set(toolkit, "FNDice");
}
catch (NoSuchFieldException | IllegalAccessException e)
{
    e.printStackTrace();
}

以下是我在运行应用程序时看到的警告。

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.gmail.fishnet37222.fndice.App (file:/home/dave/IdeaProjects/fndice/target/classes/) to field sun.awt.X11.XToolkit.awtAppClassName
WARNING: Please consider reporting this to the maintainers of com.gmail.fishnet37222.fndice.App
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

这是两种不同事物的副作用,通过反射使用非 API 接口,以及使用使用模块加载系统的新 JVM(在 Java 9 中引入)

使用 Java 模块,JAR 文件现在包含更多关于其他 JAR 文件应该访问所包含代码的哪些部分的元数据。 这允许许多以前只能使用 OSGI 或自定义类加载器才能实现的功能。

赔率是您正在使用的代码,您正在使用的库尚未更新以正确工作/与模块系统接口,默认情况下执行。 要让遗留反射代码以向后兼容的方式访问非 API 入口点,您需要将命令行标志--illegal-access=permit到您的 java 启动命令。

请注意,如果您同时执行这两项操作,则运行时启动和编译器启动可能都需要这样做。

出于好奇,在这个平台上,是jframe.setTitle("title")不起作用,还是setTitle可用之前的代码库?

假设应用程序是使用 .desktop 文件启动的,则可以通过将StartupWMClass键添加到 .desktop 文件来解决此问题,例如:

StartupWMClass=com-example-Application

该值是应用程序主类的完全限定名称,其中的点由连字符代替。

如果您更喜欢破解sun.awt.X11.XToolkit类,您只需添加:

--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED

到命令行来避免非法反射访问警告。

这是我使用 Oracle 的 JDK 来确定在 Ubuntu 上运行的 KDE 的应用程序名称。 我知道没有方法可以覆盖该值,该值是从包含您的 main() 方法的 java 类中计算出来的。 我没有在其他窗口管理器或 OpenJDK 上测试过。 如果您的 main() 方法在 com.foo.MyApp 中,那么您的应用名称将是“com-foo-MyApp”。

    /**
     * For Java 17, we can no longer access private fields, which means we can't override the "awtAppClassName" setting to control the
     * app name that the Linux window manager uses for window rules in Settings/Window Management/Window Rules.
     *
     * This code was copied from sun.awt.X11.XToolkit. It displays Window class (application) name needed to configure window rules
     */
    public static void displayMainClassName() {
        String mainClassName = null;
        StackTraceElement[] trace = (new Throwable()).getStackTrace();
        int bottom = trace.length - 1;
        if (bottom >= 0) {
            mainClassName = trace[bottom].getClassName();
        }
        if (mainClassName == null || mainClassName.isEmpty()) {
            mainClassName = "AWT";
        }
        mainClassName = mainClassName.replace('.', '-');
        System.out.println("mainClassName = " + mainClassName);
    }

我没有找到适合我的建议。 而且我也找不到自然的方法。 注意我正在使用 Ubuntu。

我决定创建一个不同的主 class 作为我的入口点。 例如,我没有让com-my-specific-domain-GameName出现在任务栏和鼠标 hover 上的停靠栏中,而是通过单独的 package 和 class 名称来模仿我想要的名称来显示Game-Name

package Game;

import com.my.specific.domain.GameName;

public class Name {
    public static void main(String[] args) {
        GameName.main(args);
    }
}

不幸的是,我认为这不适用于单个单词应用程序名称,因为 class 必须有一个 package,结果中至少需要一个“-”分隔符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM