如何禁用JLabel的自动HTML支持?
Swing JLabel 会自动将任何以 开头的文本解释为 HTML 内容。如果此 HTML 的内容是具有无效 URL 的图像,这将导致整个 GUI 挂起,因为应加载此图像的 ImageFetche 将因 NPE 退出。
要重现此问题,只需创建一个 JLabel,如下所示
new JLabel("<html><img src='http:\\\\invalid\\url'>")
我知道有一个客户端属性可以阻止 JLabel 解释 HTML。但 JLabel 是许多 Swing 组件(如 JTree、JTable 等)的默认呈现器实现,这使得这对于几乎所有允许用户输入的 Swing 应用程序来说都是一个问题。因此,我没有实现大量的自定义渲染器,而是寻找一个全局解决方案来禁用 HTML 解释。
A Swing JLabel automatically interprets any text as HTML content, if it starts with <html>. If the content of this HTML is an image with invalid URL this will cause the whole GUI to hang since the ImageFetche which should load this image will quit by an NPE.
To reproduce this problem simply create a JLabel as follows
new JLabel("<html><img src='http:\\\\invalid\\url'>")
I know there is a client property to prevent the JLabel from interpreting HTML. But JLabel is the default renderer implementation for many Swing components(like JTree, JTable and so on) which makes this a problem for nearly any Swing application which allows user input. So instead of implementing tons of custom renderer I'm searching for a global solution to disable the HTML interpretation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您创建自己的外观和感觉,就有办法。
我不确定它的性能如何,但它确实有效。假设您将扩展“Classic Windows”L&F。您至少需要 2 个类
一是 Look&Feel 本身,我们将其称为 WindowsClassicLookAndFeelExt。您只需要重写方法 initClassDefaults 即可。
您还需要一个 WindowsLabelExtUI 类来管理所有 JLabels 并设置属性:
最后一个测试类,当您将主题设置为 WindowsClassicLookAndFeelExt 时
,您将看到类似
There is a way if you create your own look and feel.
I'm not sure how well this performs is this, but it works. Lets assume you will extend the "Classic Windows" L&F.You need at leas 2 classes
One is the Look&Feel itself, lets call it WindowsClassicLookAndFeelExt. You only need to override method initClassDefaults.
You also need a WindowsLabelExtUI class to manage all JLabels and set the property:
And finally a test class when you set the theme as WindowsClassicLookAndFeelExt
And you will see something like
对于简单的 JLabel,您可以
在要禁用 HTML 渲染的标签上调用 JComponent 方法。
参考:无法在 JLabel 中禁用 HTML 渲染
对于像 JTable 这样的东西, JTree 或 JList 您需要创建一个自定义单元格渲染器来设置此属性。下面是一个创建自定义单元格的示例(修改自此示例) JList 的渲染器。
我使用了 ListCellRenderer 文档作为自定义列表单元格渲染器的起点。
当我运行该示例时,您可以看到第一个列表条目中的 HTML 被渲染而不是被解释。
For a simple JLabel, you can call the JComponent method
on the label where you want to disable HTML rendering.
Reference: Impossible to disable HTML Rendering in a JLabel
For something like a JTable, JTree, or JList you'll need to create a custom cell renderer that sets this property. Here's an example (modified from this example) that creates a custom cell renderer for a JList.
I used the example code from the ListCellRenderer documentation as a starting point for the custom list cell renderer.
When I run the example, you can see that the HTML in the first list entry is rendered instead of being interpreted.
由于无法将每个创建的
JLabel
的html.disable
属性全局设置为 true,因此这是一种 hacky 方法(我说 hacky 是因为我不确定影响性能,或者这样的解决方案是否可以投入生产)的方法是对每个创建的 JLabel 实例进行一些字节码拦截。像 ByteBuddy 这样的库可以做到这一点。我对 ByteBuddy 进行了一些实验,找到了一种设置 Java 代理,拦截对JLabel
的setText()
方法的调用。使用提供的文本创建JLabel
时会调用此方法。代理
拦截
器示例
运行示例
编译 Java 代理,然后运行示例:
注意: 当使用 Maven 构建代理 Jar 时,我必须将以下配置放入 POM 中设置清单:
Since there is no way of globally setting the
html.disable
property to true for each createdJLabel
, one hacky way (I say hacky because I'm not sure of the impact on performance, or whether such a solution could be placed on production) is to do some bytecode interception for every createdJLabel
instance. A library like ByteBuddy can do this. I've experimented a bit with ByteBuddy and found a way to set a Java agent that intercepts calls to thesetText()
method for aJLabel
. This method is called when creating aJLabel
with the provided text.Agent
Interceptor
Example
Running the example
Compile the Java agent then run the example:
Note: When using Maven to build the agent Jar, I had to put the following configuration in the POM to setup the manifest:
上吊可能是最不令人不快的行为。这就是为什么数据验证如此重要。只是不允许用户输入类似的内容。
Hanging is probably the least unpleasant behavior. This is why Data Validation is so very important. Just do not allow the users to enter something like that.