防止带有 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 换行的主要内容,如果未能解决你的问题,请参考以下文章

Safari 中的 Flexbox 行换行问题

c语言中 将数组列换行 行换列

如何在不使用 HTML 的情况下向 JLabel 添加换行符

python给word添加换行换页符

用于打印输出的明智的 python 源代码行换行

如何使JLabel自动换行到下一行