防止带有 html 的 JLabel 换行
Posted
技术标签:
【中文标题】防止带有 html 的 JLabel 换行【英文标题】:Prevent JLabel with html from breaking line 【发布时间】:2022-01-17 17:00:46 【问题描述】:想知道是否有人知道在 JLabel 中使用 html 时如何禁用换行符。
代码如下:
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
import java.awt.GridLayout;
public class Main
private static final int[] TEXT =
0x05D0, 0x05B2, 0x05DC,
0x05B5, 0x05D9, 0x05DB,
0x05B6, 0x05DD
;
public static void main(String[] args)
String text = "";
for(int cp : TEXT)
text += Character.toString(cp);
String html = "<html>" + text + "</html>";
JLabel label = new JLabel(html);
JLabel msg = new JLabel("The text should at least go out to here.");
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(2,1));
panel.add(label);
panel.add(msg);
JOptionPane.showMessageDialog(null, panel);
双向文本分成两行。我正在尝试将 html 写入 JTree 节点,以便它支持多个字体系列。我无法让它与 JLabel 一起使用。我想我可能需要在单元格渲染器中绘制它。我希望让 html 工作。这会让事情变得容易得多。
有什么建议吗?
=== 编辑 === 当我在 Windows 中的显示设置为 125% 时,它会中断;但是,当我将 Windows 中的显示设置更改为 100% 时,它不会断线。运行 1920 x 1080 显示器。谁有想法?或者,有没有人可以重复断线?
=== 编辑 ===
有趣的是,当我使用 1.0 或 2.0 传递 -Dsun.java2d.uiScale= 时,它可以工作。当我使用 3.0、4.0、1.25 或 1.5 或 0.8 时,它不起作用。
【问题讨论】:
我在运行您的程序时没有看到任何换行符。我在一行中看到“אֲלֵיכֶם”和“文本至少应该到这里”。在第二行。顺便说一句,你的循环不是必需的;你可以写private static final String TEXT = "\u05D0\u05B2\u05DC\u05B5\u05D9\u05DB\u05B6\u05DD";
。
果然可以在Oracle JRE 8上运行,在OpenJDK上不行。我尝试了 OpenJDK 11 和 OpenJDK 15。似乎是 OpenJDK 的问题。不幸的是,由于 Oracle 的新许可安排,我坚持使用 OpenJDK。也许使用 OpenJDK 的人可以看看。另外,我注意到 Oracle JRE 8 不支持 Character.toString(codepoint) - 您是否需要更改代码才能使其正常工作?
我使用 JPanel 和网格布局来保证 JLabel 是全宽的
它在我的 OpenJDK 17 机器上不起作用 - 这是一个图像 Image linebreak 不知道为什么不。运行 Windows 10
有趣 - 当我在 Windows 中将显示设置从 125% 更改为 100% 时,它可以工作
【参考方案1】:
好吧,我提交了一份错误报告。我设法找到了一个似乎适用于所有 Windows Display Scale 的解决方法,但它是一个相当老套的解决方法。但是在修复错误之前就足够了。
这里是:
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.GridLayout;
import java.awt.font.FontRenderContext;
public class Main
private static final String TEXT =
"\u05D0\u05B2\u05DC\u05B5\u05D9\u05DB\u05B6\u05DD";
public static void main(String[] args)
JLabel label = new JLabel();
Graphics2D g2 = (Graphics2D)new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB).getGraphics();
FontRenderContext frc = g2.getFontRenderContext();
String[] split = TEXT.split("");
double width = 0;
for(String chr : split)
width += label.getFont().getStringBounds(chr, frc).getWidth();
double scale = Toolkit.getDefaultToolkit().getScreenResolution()/96.0;
String html = "<html><p style=\"width:"+Math.ceil(width/scale)+"px;\">" + TEXT + "</p></html>";
label.setText(html);
JLabel msg = new JLabel("The text should at least go out to here.");
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(2,1));
panel.add(label);
panel.add(msg);
JOptionPane.showMessageDialog(null, panel);
注意:如果我没有得到单个字符的长度,那么宽度不会在 JTree 节点中正确显示。另外,由于某种原因,当我使用双向文本时,节点 JLabel 的结果宽度大约是文本宽度的两倍。任何更短,它都不能正确显示。但是,非双向文本的宽度是正确的。另外,width: 不适用于 span 标签,它只适用于 p 标签
【讨论】:
原来这个错误已经被报告了bugs.java.com/bugdatabase/view_bug.do?bug_id=8269854以上是关于防止带有 html 的 JLabel 换行的主要内容,如果未能解决你的问题,请参考以下文章