是否有“自动换行”? JLabel 的属性?

发布于 2024-12-11 03:53:07 字数 201 浏览 0 评论 0原文

我正在 JLabel 中显示一些文本。基本上,我动态生成该文本,然后应用一些 HTML 标记(例如 BRB)来格式化文本。最后,我将此格式化文本分配给我的 JLabel。

现在,我希望 Jlabel 在文本到达屏幕末尾时自动换行到下一行,就像记事本中的“自动换行”功能一样。

我怎样才能做到这一点?

I am displaying some text in a JLabel. Basically I am generating that text dynamically, and then I apply some HTML tags (e.g., BR and B) to format the text. Finally I assign this formatted text to my JLabel.

Now I want my Jlabel to automatically wrap the text to the next line when it reaches the end of screen, like the "Word Wrap" feature in Note Pad.

How can I do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

孤星 2024-12-18 03:53:08

可以使用 HTML 样式 (CSS) 设置 body 的宽度。这反过来将确定要渲染的行数,并据此确定标签的首选高度。

在 CSS 中设置宽度可以避免计算标签中应出现换行的位置(或最佳尺寸)。

import javax.swing.*;

public class FixedWidthLabel {

    public static void main(String[] srgs) {
        final String s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean eu nulla urna. Donec sit amet risus nisl, a porta enim. Quisque luctus, ligula eu scelerisque gravida, tellus quam vestibulum urna, ut aliquet sapien purus sed erat. Pellentesque consequat vehicula magna, eu aliquam magna interdum porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed sollicitudin sapien non leo tempus lobortis. Morbi semper auctor ipsum, a semper quam elementum a. Aliquam eget sem metus.";
        final String html = "<html><body style='width: %1spx'>%1s";

        Runnable r = () -> {
            JOptionPane.showMessageDialog(
                    null, String.format(html, 200, s));
            JOptionPane.showMessageDialog(
                    null, String.format(html, 300, s));
        };
        SwingUtilities.invokeLater(r);
    }
}

在此处输入图像描述 在此输入图像描述

A width can be set for the body using HTML styles (CSS). This in turn will determine the number of lines to render and, from that, the preferred height of the label.

Setting the width in CSS avoids the need to compute where line breaks should occur in (or the best size of) the label.

import javax.swing.*;

public class FixedWidthLabel {

    public static void main(String[] srgs) {
        final String s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean eu nulla urna. Donec sit amet risus nisl, a porta enim. Quisque luctus, ligula eu scelerisque gravida, tellus quam vestibulum urna, ut aliquet sapien purus sed erat. Pellentesque consequat vehicula magna, eu aliquam magna interdum porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed sollicitudin sapien non leo tempus lobortis. Morbi semper auctor ipsum, a semper quam elementum a. Aliquam eget sem metus.";
        final String html = "<html><body style='width: %1spx'>%1s";

        Runnable r = () -> {
            JOptionPane.showMessageDialog(
                    null, String.format(html, 200, s));
            JOptionPane.showMessageDialog(
                    null, String.format(html, 300, s));
        };
        SwingUtilities.invokeLater(r);
    }
}

enter image description here enter image description here

赠我空喜 2024-12-18 03:53:08

如果您将文本包装在 ...

更新: 中, 应该可以工作
那么您可能也应该设置最大尺寸。

Should work if you wrap the text in <html>...</html>

UPDATE:
You should probably set maximum size, too, then.

梦晓ヶ微光ヅ倾城 2024-12-18 03:53:08

一种方法是使用 JTextArea 而不是 JLabel,并将 setWrapStyleWordsetLineWrap 设置为 true 并设置使其外观和行为类似于 JLabel(删除边框、使其不透明、不可编辑且不可聚焦)。

否则,如果您绝对需要使用 JLabel,您将被迫使用 FontMetrics 来测量文本,检查空白,然后自己在适当的位置添加 HTML 硬中断。

One way would be to use a JTextArea instead of a JLabel with setWrapStyleWord and setLineWrap set to true and with settings to make it look and behave like a JLabel (remove the border, make it non-opaque, make it non-editable and non-focusable).

Otherwise if you absolutely need to use a JLabel, you'd be forced to use FontMetrics to measure your text, check for white-space, and then add the HTML hard-breaks in the appropriate positions yourself.

两人的回忆 2024-12-18 03:53:08

我发现这个解决方案是最简单的,并且在调整大小时也能正常工作。除了将文本包装在 标记中之外,您还必须将标签放入遵循首选高度并将宽度设置为最大值的容器中。例如,您可以将标签放在 BorderLayout 的北部。

这是一个简单但完整的工作程序来说明这一点。您可以按照您想要的任何方式调整框架大小;标签将占据整个宽度,高度将相应调整以包裹文本。请注意,我所做的只是使用 标签并将标签放在 BorderLayout 的北部。

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.Dimension;

public class LabelWrap {

    public static JPanel createPanel() {
        JLabel label = new JLabel();
        label.setText("<html>"
            + "<h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h3>"
            + "<p>Duis a tincidunt urna. Phasellus tristique interdum mauris, "
            + "ut vestibulum purus suscipit eget. Aenean massa elit, accumsan "
            + "non faucibus vel, dictum placerat urna. In bibendum est sagittis "
            + "urna iaculis quis sagittis velit commodo. Cum sociis natoque "
            + "penatibus et magnis dis parturient montes, nascetur ridiculus "
            + "mus. Nam quis lacus mauris. Phasellus sem libero, convallis "
            + "mattis sagittis vel, auctor eget ipsum. Vivamus molestie semper "
            + "adipiscing. In ac neque quis elit suscipit pharetra. Nulla at "
            + "orci a tortor consequat consequat vitae sit amet elit. Praesent "
            + "commodo lacus a magna mattis vehicula. Curabitur a hendrerit "
            + "risus. Aliquam accumsan lorem quis orci lobortis malesuada.</p>"
            + "<p>Proin quis viverra ligula. Donec pulvinar, dui id facilisis "
            + "vulputate, purus justo laoreet augue, a feugiat sapien dolor ut "
            + "nisi. Sed semper augue ac felis ultrices a rutrum dui suscipit. "
            + "Praesent et mauris non tellus gravida mollis. In hac habitasse "
            + "platea dictumst. Vestibulum ante ipsum primis in faucibus orci "
            + "luctus et ultrices posuere cubilia Curae; Vestibulum mattis, "
            + "tortor sed scelerisque laoreet, tellus neque consectetur lacus, "
            + "eget ultrices arcu mi sit amet arcu. Nam gravida, nulla interdum "
            + "interdum gravida, elit velit malesuada arcu, nec aliquam lectus "
            + "velit ut turpis. Praesent pretium magna in nibh hendrerit et "
            + "elementum tellus viverra. Praesent eu ante diam. Proin risus "
            + "eros, dapibus at eleifend sit amet, blandit eget purus. "
            + "Pellentesque eu mollis orci. Sed venenatis diam a nisl tempor "
            + "congue.</p>"
            + "</html>");

        JPanel panel = new JPanel(new BorderLayout());
        panel.add(label, BorderLayout.NORTH);
        panel.setPreferredSize(new Dimension(640, 480));
        return panel;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() { 
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setContentPane(createPanel());
                frame.pack();
                frame.setVisible(true);
            }

        });
    }

}

I found that this solution is the simplest and works correctly with resizing as well. Other than wrapping the text in <html> tags, you also have to put the label into a container that respects the preferred height and sets the width to maximum. For example, you can put the label in to the NORTH of a BorderLayout.

Here is a simple but complete working program to illustrate this. You can resize the frame in any way you want; the label will occupy the whole width and the height will adjust accordingly to wrap the text. Notice that all that I'm doing is using <html> tags and putting the label in the NORTH of the BorderLayout.

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.Dimension;

public class LabelWrap {

    public static JPanel createPanel() {
        JLabel label = new JLabel();
        label.setText("<html>"
            + "<h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h3>"
            + "<p>Duis a tincidunt urna. Phasellus tristique interdum mauris, "
            + "ut vestibulum purus suscipit eget. Aenean massa elit, accumsan "
            + "non faucibus vel, dictum placerat urna. In bibendum est sagittis "
            + "urna iaculis quis sagittis velit commodo. Cum sociis natoque "
            + "penatibus et magnis dis parturient montes, nascetur ridiculus "
            + "mus. Nam quis lacus mauris. Phasellus sem libero, convallis "
            + "mattis sagittis vel, auctor eget ipsum. Vivamus molestie semper "
            + "adipiscing. In ac neque quis elit suscipit pharetra. Nulla at "
            + "orci a tortor consequat consequat vitae sit amet elit. Praesent "
            + "commodo lacus a magna mattis vehicula. Curabitur a hendrerit "
            + "risus. Aliquam accumsan lorem quis orci lobortis malesuada.</p>"
            + "<p>Proin quis viverra ligula. Donec pulvinar, dui id facilisis "
            + "vulputate, purus justo laoreet augue, a feugiat sapien dolor ut "
            + "nisi. Sed semper augue ac felis ultrices a rutrum dui suscipit. "
            + "Praesent et mauris non tellus gravida mollis. In hac habitasse "
            + "platea dictumst. Vestibulum ante ipsum primis in faucibus orci "
            + "luctus et ultrices posuere cubilia Curae; Vestibulum mattis, "
            + "tortor sed scelerisque laoreet, tellus neque consectetur lacus, "
            + "eget ultrices arcu mi sit amet arcu. Nam gravida, nulla interdum "
            + "interdum gravida, elit velit malesuada arcu, nec aliquam lectus "
            + "velit ut turpis. Praesent pretium magna in nibh hendrerit et "
            + "elementum tellus viverra. Praesent eu ante diam. Proin risus "
            + "eros, dapibus at eleifend sit amet, blandit eget purus. "
            + "Pellentesque eu mollis orci. Sed venenatis diam a nisl tempor "
            + "congue.</p>"
            + "</html>");

        JPanel panel = new JPanel(new BorderLayout());
        panel.add(label, BorderLayout.NORTH);
        panel.setPreferredSize(new Dimension(640, 480));
        return panel;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() { 
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setContentPane(createPanel());
                frame.pack();
                frame.setVisible(true);
            }

        });
    }

}
冰火雁神 2024-12-18 03:53:08

我喜欢上面提到的 JTextArea 方法,因为它在 BorderLayout 面板中的 SOUTH 处可以很好地调整大小(只要 CENTER 组件可以在 JTextArea 中的行数发生变化时弥补松弛部分)。

然而,在 Nimbus L&F 中,设置 JTextArea 的背景颜色有一个问题。 Nimbus 似乎使用了在 JTextArea 中透明的幻色(java.awt.Color 的扩展类)。因此,如果要将背景颜色从 JPanel 复制到 JText 区域,则需要将颜色转换为 ARGB,然后再转换回颜色。以下代码适用于我的 JRE(Nimbus、CDE Motif、Metal、Mac OS X)中的所有 L&F:

    JTextArea ta = new JTextArea(text);
    ta.setEditable(false);
    ta.setLineWrap(true);
    ta.setWrapStyleWord(true);
    JLabel lb = new JLabel();
    Font f = lb.getFont();
    ta.setFont(f.deriveFont(f.getSize2D() * 0.9f));
    ta.setBorder(lb.getBorder());
    ta.setBackground(new Color(lb.getBackground().getRGB(), true));
    ta.setForeground(new Color(lb.getForeground().getRGB(), true));
    ta.setOpaque(lb.isOpaque());

我将字体弄小了一点。当然,如果您愿意,您可以保留 JLabel 的字体大小。

I like the JTextArea approach mentioned above, because it resizes nicely at SOUTH in a BorderLayout panel (as long as the CENTER component can take up the slack if the number of lines in the JTextArea changes).

However, in Nimbus L&F there is a catch in setting the JTextArea's background colour. It seems that Nimbus uses magic colours (extended class of java.awt.Color) that go transparent in JTextArea. So if you are copying the background colour from a JPanel to the JText area you need to convert the Color to ARGB and back to Color. The following code works for me in all the L&Fs in my JRE (Nimbus, CDE Motif, Metal, Mac OS X):

    JTextArea ta = new JTextArea(text);
    ta.setEditable(false);
    ta.setLineWrap(true);
    ta.setWrapStyleWord(true);
    JLabel lb = new JLabel();
    Font f = lb.getFont();
    ta.setFont(f.deriveFont(f.getSize2D() * 0.9f));
    ta.setBorder(lb.getBorder());
    ta.setBackground(new Color(lb.getBackground().getRGB(), true));
    ta.setForeground(new Color(lb.getForeground().getRGB(), true));
    ta.setOpaque(lb.isOpaque());

I made the font a bit smaller. Of course you can keep JLabel's font size if you want.

绾颜 2024-12-18 03:53:08

混合纯文本和 HTML 将关闭 HTML 中的自动换行:

    jLabel_01.setText("<html>Lorem ipsum long paragraph</html>"); // work good
...
    jLabel_01.setText(""); // will switch off HTML words wrap!!!
...
    jLabel_01.setText("<html>Lorem ipsum long paragraph</html>"); // will not work properly

因此您不能在一个 JLabel 中混合不同类型(HTML 和纯文本)的文本

Mix plain text and HTML will switch off auto words wrap in HTML:

    jLabel_01.setText("<html>Lorem ipsum long paragraph</html>"); // work good
...
    jLabel_01.setText(""); // will switch off HTML words wrap!!!
...
    jLabel_01.setText("<html>Lorem ipsum long paragraph</html>"); // will not work properly

So you can not mix different types (HTML and plain text) of text in one JLabel

酒与心事 2024-12-18 03:53:08

我只是想我应该将这篇文章发布给任何在互联网上搜索的人,因为这个小错误让我花了 30 分钟,但请确保您实际上已经将文本封装在 HTML 中。您可能以为自己做到了,但实际上并没有做到。检查一下,我忘记了,当我将它们包装在 HTML 中时,它为我修复了它。

JLabel label = new JLabel("Lorem ipsum long paragraph"); 错误。

JLabel label = new JLabel("Lorem ipsum long paragraph"); 正确!

Just thought I should post this for anyone searching the internet, as it was the tiny little mistake that cost me 30 minutes, but make sure you've actually wrapped the text in HTML. You may have thought you did and yet didn't. Check it, I forgot, and when I wrapped them in HTML it fixed it for me.

JLabel label = new JLabel("Lorem ipsum long paragraph"); wrong.

JLabel label = new JLabel("<html>Lorem ipsum long paragraph</html>"); correct!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文