我需要从基于 Java servlet 的应用程序中动态生成一些图像。我想让布局比仅使用硬编码位置和 Graphics2D.drawString 更易于维护,所以我想我会为此使用 AWT/Swing 布局。
这在我的 Windows 开发机器上运行良好(创建 JFrame、添加组件、.pack() 框架、通过将 BufferedImage 传递给 component.paint() 进行渲染;请注意,我没有调用 .setVisible(true))。(注意 - 我使用 JFrame 的唯一原因是有一些东西可以调用 .pack() ,否则我可能会使用更轻量级的东西。)
但是,它在我的 Elastic Beanstalk 托管 AWS EC2 Tomcat7 机器上失败,出现 java.awt.HeadlessException。
java.awt.HeadlessException
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:173)
at java.awt.Window.<init>(Window.java:477)
at java.awt.Frame.<init>(Frame.java:419)
at javax.swing.JFrame.<init>(JFrame.java:218)
第一个问题(已过时):这是否有机会在不安装 X11 的情况下工作?如果是,我应该将“java.awt.headless”设置为什么?如果我使用“true”,那么它将在当前失败的地方失败。如果我使用“false”,它现在会在本机代码实际尝试使用窗口系统的其他地方失败吗?
第二个问题:如何设置这个“java.awt.headless”属性(对于 EBS 环境)?
因为到目前为止我已经:
在我的 .ebextensions / .config 中添加了以下内容:
option_settings:
- namespace: aws:elasticbeanstalk:container:tomcat:jvmoptions
option_name: Djava.awt.headless
value: false
编辑 /etc/tomcat7/tomcat7.conf 并将以下内容放在那里:
JAVA_OPTS="-Djava.awt.headless=false"
尽管在重新部署/ Tomcat 重新启动后,传递给 tomcat 的 JVM 选项似乎是“java.awt.headless = true”:
[ec2-user@ip-address ~]$ sudo ps aux | grep headless
tomcat 7200 12.6 45.4 1406724 276604 ? Sl 23:02 0:47 /usr/lib/jvm/jre/bin/java -DPARAM3= -DPARAM4= -DPARAM1=production_worker.properties -DPARAM2= -DJDBC_CONNECTION_STRING= -DPARAM5= -DAWS_SECRET_KEY= -DAWS_ACCESS_KEY_ID= -XX:MaxPermSize=64m -Xmx512m -Xms512m -classpath :/usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar:/usr/share/java/commons-daemon.jar -Dcatalina.base=/usr/share/tomcat7 -Dcatalina.home=/usr/share/tomcat7 -Djava.awt.headless=true -Djava.endorsed.dirs= -Djava.io.tmpdir=/var/cache/tomcat7/temp -Djava.util.logging.config.file=/usr/share/tomcat7/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager org.apache.catalina.startup.Bootstrap start
此外,尽管我的代码仍然根本找不到该属性:
log.error("java.awt.headless=", System.getProperty("java.awt.headless"));
这输出:
2013-01-14 22:13:17,421 +0000 [http-bio-8080-exec-4] ERROR ServiceImpl:45 - java.awt.headless=
编辑 - 我也有
System.setProperty("java.awt.headless", "false");
但这似乎也没有帮助。
Edit2 - 我取消了 JFrame,只是实例化了一个 JPanel。这使它现在可以在无头环境中渲染。
但是,我无法弄清楚如何正确地进行布局。我一直在我的不同布局上调用 doLayout,在我的组件上调用 something.setSize(something.getPreferredSize()),但结果是重叠或不可见的标签。这一切都是因为我不再调用 JFrame.pack() (因为没有 JFrame 可以调用它)。
所以第三个问题 - 我如何确保我的 JPanel 布局正确而没有 JFrame 来调用 .pack() ?
Edit3 - 第三个问题的答案是调用 panel.addNotify(); panel.setSize(panel.getPreferredSize()); 面板.验证();这要感谢 Andrew Thomson: