在 Gnome 顶部栏中设置我的 Java Swing 应用程序标题的正确方法是啥?
Posted
技术标签:
【中文标题】在 Gnome 顶部栏中设置我的 Java Swing 应用程序标题的正确方法是啥?【英文标题】:What is the proper way to set my Java Swing application's title in the Gnome top bar?在 Gnome 顶部栏中设置我的 Java Swing 应用程序标题的正确方法是什么? 【发布时间】:2018-05-03 03:18:34 【问题描述】:我正在使用以下代码在 Gnome 3 的顶部栏中设置我的 Java Swing 应用程序的标题。但是,当我运行它时,我会收到代码下方显示的警告。有没有更好的方法在代码中设置应用程序标题?请注意,这不是关于设置窗口本身标题的问题。
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
【问题讨论】:
它不起作用?给你的 JFrame 一个标题就够了吗? 当我使用我提供的代码时它可以工作。不过,它给了我这些警告。我的问题是,是否有一种方法可以设置应用程序标题,而无需求助于未来版本的 Java 可能不支持的黑客攻击。不,在 JFrame 上设置标题是不够的。 这些警告从 JDK9 开始。甲骨文不再允许自定义应用程序名称,而是追随他们的开发人员。 Java 已死。 @mariusm 似乎只是警告它不受支持的界面,可能是因为不能保证所有环境在其桌面环境中都显示“应用程序标题”。由于这是一个警告,并且 Project jigsaw (Java 9) 现在可以通过其模块系统强制执行 API 合同,因此该应用程序启动时可能没有允许非法模块访问的标志。 【参考方案1】:这是我用来确定使用 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);
【讨论】:
【参考方案2】:假设应用程序是使用 .desktop 文件启动的,则可以通过将 StartupWMClass
键添加到 .desktop 文件来解决此问题,例如:
StartupWMClass=com-example-Application
该值是应用程序主类的完全限定名称,其中的点由连字符代替。
如果您更喜欢破解 sun.awt.X11.XToolkit
类,您只需添加:
--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED
到命令行避免非法反射访问警告。
【讨论】:
【参考方案3】:这是两种不同事物的副作用,通过反射使用非 API 接口,以及使用正在使用模块加载系统的新 JVM(在 Java 9 中引入)
使用 Java 模块,JAR 文件现在包含更多元数据,说明其他 JAR 文件应访问所包含代码的哪些部分。这允许许多以前只能通过 OSGI 或自定义类加载器才能实现的事情。
奇怪的是您正在使用的代码和您正在使用的库尚未更新以正确工作/与默认情况下强制执行的模块系统交互。要让遗留反射代码以向后兼容的方式访问非 API 入口点,您需要将命令行标志 --illegal-access=permit
添加到您的 java 启动命令中。
请注意,运行时启动和编译器启动可能都需要此操作,如果您同时执行这两项操作。
出于好奇,在这个平台上,jframe.setTitle("title")
不起作用,还是setTitle
之前的代码库可用?
【讨论】:
我也发现了同样的问题。并回答您的问题:我使用 JFrame.setTitle("A"),仍然在 Ubuntu 中,我可以看到一个以完全限定类名命名的顶部菜单。所以一个 setTitle() 是不够的。对于 OS X,有一个 JVM 开关 ***.com/questions/4007512/…以上是关于在 Gnome 顶部栏中设置我的 Java Swing 应用程序标题的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android Kitkat 中设置我的短信应用默认值?
在 node.js 中设置我的 babel-watch 时遇到问题
如何在我的 winforms 应用程序中设置我的 datagrid 滚动条的位置?
如何在 Google App Engine 中设置我的默认版本