我有一个使用JXLayer和pbjar-Framework具有可缩放UI的Java swing项目。 JTextComponents出现问题,该问题已通过TransformUI.java中的以下方法修复:
/**
* {@link JTextComponent} and its descendants have some caret position
* problems when used inside a transformed {@link JXLayer}. When you plan to
* use {@link JTextComponent}(s) inside the hierarchy of a transformed
* {@link JXLayer}, call this method in an early stage, before instantiating
* any {@link JTextComponent} .
* <p>
* It executes the following method:
*
* <pre>
* System.setProperty("i18n", Boolean.TRUE.toString());
* </pre>
*
* As a result, a {@link GlyphPainter} will be selected that uses floating
* point instead of fixed point calculations.
* </p>
*/
public static void prepareForJTextComponent() {
System.setProperty("i18n", Boolean.TRUE.toString());
}
所有JAR均使用有效证书签名,并且jnlp看起来像
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="7.0+" codebase="https://__HOST_IP____HOST_HTTPS_PORT__/test"
href="client/1024.jnlp">
<information>
<offline-allowed />
</information>
<security>
<all-permissions />
</security>
<resources>
<j2se version="1.8+" java-vm-args="-Xmx512M" />
<jar href="client.jar" />
... more JARs
</resources>
<application-desc main-class="de.test.Frame">
<argument>__HOST_IP__</argument>
</application-desc>
</jnlp>
client.jar MANIFEST.MF包含以下内容
...
Permissions: all-permissions
Codebase: *
Trusted-Only: false
Trusted-Library: false
...
因为javaws只接受安全属性,所以我在主类中调用了
static
{
TransformUI.prepareForJTextComponent();
}
问题是,如果我在每个浏览器中使用Java webstart,则JTextComponent的修复程序将无法正常工作。
对于Java Webstart,我测试了4种情况:
爪哇
javaws [url]
javaws [本地文件]
浏览器
使用oracle java 8u141、32或64位,Windows 7 64bit,Linux debian 7 64位,firefox进行测试
爪哇
如果我将客户端称为Java应用程序,则修复效果很好
javaws [url]
此调用在linux和Windows中均能正常运行。
但是在旧版本的jnlp文件中,我们使用扩展名来包含3rd-party JAR,在Windows中,此调用只能运行一次,直到删除缓存的文件为止
javaws [本地文件]
不起作用
浏览器
不起作用
有什么建议为什么系统属性不起作用?
最佳答案
在javax.swing.text.AbstractDocument.AbstractDocument(Content,AttributeContext)中,读取SystemProperty“ i18n”:
...
if (defaultI18NProperty == null) {
// determine default setting for i18n support
String o = java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<String>() {
public String run() {
return System.getProperty(I18NProperty);
}
}
);
if (o != null) {
defaultI18NProperty = Boolean.valueOf(o);
} else {
defaultI18NProperty = Boolean.FALSE;
}
}
putProperty( I18NProperty, defaultI18NProperty);
....
就我而言,该属性应始终设置为“ true”,因此我使用自己的JTextField-class:
class MyTextField extends JTextField {
MyTextField() {
super();
Document doc = new PlainDocument();
doc.putProperty("i18n", Boolean.TRUE);
this.setDocument(doc);
}
}