Java Swing对象静态初始化的首选惯用语?

时间:2013-01-22 20:24:20

标签: java swing concurrency initialization constants

我希望有一个应用程序可以在明确定义/中央/应用程序范围的位置创建一组固定的Swing对象,例如FontColor的实例,例如{{1分别和GuiFonts.java

通过这种方式,我的应用程序可以引用诸如GuiColors.javaGuiFonts.SMALL_FONT之类的内容,如果我稍后决定“小字体”表示8点,而不是我可以在一个地方进行更改10点,或背景应为GuiColors.BACKGROUND,而不是#FFEF88,例如。

那么,我应该如何编写这些默认值?特别是,我应该如何编写它们以确保它们在Swing Event Dispatch Thread(EDT)可见性方面正确初始化?

我认为在EDT上创建和引用Swing GUI对象是正确的,只有在EDT上 - 是吗?

那么,这样的东西是否足够,或者它是否足够,因为代码将在类加载器线程上运行,而不是EDT?或者只要引用是#AAAAFFF

就足以在非EDT线程上运行
static final

或者,我应该确保在EDT上创建对象,也许是这样的:

import java.awt.Font;

public class GuiFonts {
    // not running on EDT, but is it correct anyhow?
    public static final Font = new Font(Font.SANS_SERIF, Font.PLAIN, 16);
}

当然,这很冗长,但很多可以打包成一个接受import java.awt.*; import java.util.concurrent.*; import javax.swing.*; public class GuiFonts { // intended to run on EDT, but is EDT running yet? In all cases? public static final Font MEDIUM_FONT = new Callable<Font>() { @Override public Font call() { final RunnableFuture<Font> future = new FutureTask<Font>(new Callable<Font>() { @Override public Font call() { return new Font(Font.SANS_SERIF, Font.PLAIN, 16); } }); try { SwingUtilities.invokeAndWait(future); // Could be invokeLater() because of the Future... return future.get(); } catch (final Exception e) { throw new RuntimeException(e); } } }.call(); } 并提交给EDT的例程:

Callable

除了Swing EDT发布问题之外,如果常量在几个文件中相互引用,则此方法具有容易出错的初始化排序方面:未使用 public static final Font MEDIUM_FONT = runOnEDT(new Callable<Font>() { @Override public Font call() { return new Font(Font.SANS_SERIF, Font.PLAIN, 16); } }); 初始化的常量。

请注意,像null这样的例程应该捕获并记录所有异常,特别是,日志记录应该在runOnEDT子句中发生, NOT 在{{1} {{1}因为catch通常已安装在EDT上。

或者,最好是UncaughtExceptionHandler初始化一起放弃。支持一些延迟加载方案,其中对象由UncaughtExceptionHandler常量表示,并且一些访问者在第一次引用时在Swing EDT上创建GUI对象?

2 个答案:

答案 0 :(得分:1)

字体和颜色是AWT的一部分,而不是Swing。

话虽如此,我已经完成了你用字体概述的内容。

public class GuiFonts {
    // not running on EDT, but is it correct anyhow?
    public static final Font = new Font(Font.SANS_SERIF, Font.PLAIN, 16);
}

只要你在EDT上使用这个变量,你就可以了。您正在EDT上执行方法代码。

您可以将字体代码放入方法中。

public static Font getNormalFont() {
    return new Font(Font.SANS_SERIF, Font.PLAIN, 12);
}

这样,当你从EDT调用时,你确定代码在EDT上执行。

答案 1 :(得分:1)

对于这些事情,Swing已经有一个“明确定义/中央/应用程序范围的位置”:UIManager

使用它的好处是字体,颜色等将由Swing自动设置,您不必设置它们。

另见:Setting the Default Font of Swing Program

编辑:如果你需要创建Swing组件,他们肯定会在EDT上创建必须。请注意,一些较旧的文档说如果它们尚未“实现”,在其他线程上创建组件是安全的,但这是过时的建议。