我正在编写一个实用程序来帮助测试更大的系统,如果我在系统中运行它,我的UI根本不显示。我自己运行时工作正常。更多细节:
如果在其他地方已经回答,我道歉。我尽力搜索,但我能找到的所有问题都是关于某些组件无法呈现,而不是整个应用程序无法显示。
谢谢!
编辑: 根据反馈,我换了一个尽可能小的演示程序。这是整个代码:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class AceProbe
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
JFrame frame = new JFrame("Visible?");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(new JLabel("Test"), BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
});
}
}
从命令行运行此命令会按预期显示该窗口。但是,当控制器生成进程时,不会显示任何内容。当由控制器生成时,我可以使用-agentlib:jdwp=transport=dt_socket,suspend=y,server=y,address=8000
远程调试进程,并验证所有线程是否按预期生成,并且不会抛出任何异常。
我从这里的直觉是控制器处于一些奇怪的图形配置中,因为父进程是新的java进程,也许Swing没有使用正确的GraphicsDevice?我尝试添加此代码:
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
for(GraphicsDevice d : ge.getScreenDevices())
{
Log.println(d);
for (GraphicsConfiguration c : d.getConfigurations())
{
Log.println(c);
Log.println(c.getBounds());
}
}
日志包含:
Win32GraphicsDevice[screen=0]
sun.awt.Win32GraphicsConfig@13f459d[dev=Win32GraphicsDevice[screen=0],pixfmt=0]
java.awt.Rectangle[x=0,y=0,width=1920,height=1080]
这似乎表明只有一个配置有一个配置,所以我有点亏。
答案 0 :(得分:5)
Concurency in Swing存在问题。 Swing是单线程的,所有输出到Swing GUI必须在EDT上完成。
基本上你可以通过将输出包装到invokeLater
或invokeAndWait
正确的方法是从SwingWorker
或Runnable#Thread
调用后台任务(在Runnable
中,输出必须包含在invokeLater
或{{1}中}})
修改
invokeAndWait
EDIT2:
功能测试返回
来自HP Elite,WinXp,Java6,低调GPU
答案 1 :(得分:2)
解决方案是将应用程序拆分为2个组件(数据收集和ui /处理),并让它们通过RMI进行通信。
事实证明,Windows服务无法生成GUI。我做了一些sc query
并发现controller.exe是一项服务。由于它是java进程的父进程,java获得相同的服务权限,这意味着没有gui。有some workarounds,但它们是为了向后兼容而存在,在新代码中应该避免使用。
重申java没有引发任何异常是很重要的。似乎这种情况应该抛出一些东西来表明java进程没有创建新窗口的权限,但代码“正常”运行。窗口永远不会出现。
底线:如果另一个进程正在启动您的虚拟机,并且您没有错误但没有ui,请检查以确保您的虚拟机没有作为服务启动。如果是,则需要将ui代码提取到单独的进程中。