【问题标题】:Prevent JLabel with html from breaking line防止带有 html 的 JLabel 换行
【发布时间】: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% 时,它可以工作

标签: java html swing jlabel jtree


【解决方案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 标签

【讨论】:

猜你喜欢
  • 2020-01-05
  • 2014-12-09
  • 2021-03-14
  • 2014-04-20
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多