Java 如何获得具有多行功能的JLabel?HTML真的是唯一的方法吗?

Java 如何获得具有多行功能的JLabel?HTML真的是唯一的方法吗?,java,swing,jlabel,Java,Swing,Jlabel,我想答案是“你不能”,但我对Swing有很多不了解。因此: 我需要显示只读多行文本,一个字符一个字符,没有神奇的解释,在一个矩形中,刚好可以容纳它。能够选择一个区域(并从中复制)是一个优势 迄今为止失败的方法: JLabel(“a\nb”)根本不起作用,我无法想象为什么,因为这应该是唯一正确的答案。JLabel被记录为显示它所传递的文本。但显然不是newline JLabel还有另一个可怕的问题:如果文本恰好以开头,它也不会显示它所传递的文本-它会将其重新解释为HTML。不仅文档中没有提到这一点

我想答案是“你不能”,但我对Swing有很多不了解。因此:

我需要显示只读多行文本,一个字符一个字符,没有神奇的解释,在一个矩形中,刚好可以容纳它。能够选择一个区域(并从中复制)是一个优势

迄今为止失败的方法:

JLabel(“a\nb”)根本不起作用,我无法想象为什么,因为这应该是唯一正确的答案。JLabel被记录为显示它所传递的文本。但显然不是newline

JLabel还有另一个可怕的问题:如果文本恰好以
开头,它也不会显示它所传递的文本-它会将其重新解释为HTML。不仅文档中没有提到这一点,而且现在我遇到了一个问题,即如果允许用户输入显示在JLabel中的文本(事实上是这样),他们可能会插入格式化标记并导致各种各样的欺骗(他们会这样做)

我看不出有什么办法可以关掉它;因此,为了准确显示给定的文本,我必须对文本进行预处理,以进行完整的HTML引用,并将\n更改为

,然后将其全部包装在
..
中。我在核心Java中找不到任何引用的东西——显然,您必须编写自己的或依赖其他库,如apache?这里给出了很多不依赖第三方库的理由。现在我的java代码将包含一个HTML布局引擎,这样我就可以可靠地显示文本了?我非常希望避免这种未经记录且脆弱的黑客行为

JTextArea将处理多行文本,并且可以设置为只读。但我不知道如何告诉它缩小到只容纳文本所需的大小。(JLabel至少做到了这一点。[编辑:或否-我恢复为JLabel,现在标签在其行中居中或扩展到全尺寸-我明显缺少某个设置])我想一定有办法告诉它停止扩展以填充行,但我该怎么做<代码>设置大小(1,1)
不起作用。我觉得正确的答案就在这条路上,但我需要一个指针来让它自动调整到最小尺寸

还是有更好的组件?有没有办法将文本字符串呈现为最小尺寸的图像?我可以在JLabel中显示它

我还试图避免扫描所有文本和组成一个垂直的左对齐jlabel框,每行一个,这可能是可能的,但肯定比我想要的更复杂,因为(可能?)有一个更简单的解决方案

请注意,我不能硬编码任何组件的大小。组件描述由服务器生成并发送到应用程序,应用程序根据动态描述生成小部件,并将它们添加到Box容器中。服务器无法以像素为单位进行计算;我需要依靠Swing来简单地根据盒子中事物的顺序进行布局。在大多数情况下,这意味着小部件必须占据其可能的最小尺寸

我该怎么办

按照指示,我试过这个。只有一个窗格出现,而且没有边框,所以我看不出它会占用多少空间

import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.BorderFactory; 
import javax.swing.border.Border;

public class MainTextPane {
    public static void main(final String[] args) {
        Border loweredbevel = BorderFactory.createLoweredBevelBorder();

        final JTextPane pane = new JTextPane();
        pane.setText("Hello, this is a\ntwo lined string!");
        final JTextPane pane2 = new JTextPane();
        pane2.setText("Next!");
        pane.setBorder(loweredbevel); //no effect
        pane2.setBorder(loweredbevel); //no effect


        final JFrame frame = new JFrame("TextPane with new lines.");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(pane);
        frame.getContentPane().add(pane2); //clobbered previous pane
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
只需使用一个a,它是一个。如果您想要首选大小,只需随时(在设置文本后)调用即可。您可以将其设置为“可编辑”或“不可编辑”,并从中轻松复制粘贴,它将处理新行。如果您以简单的方式使用它,则不需要复杂:

import javax.swing.JFrame;
import javax.swing.JTextPane;

public class MainTextPane {
    public static void main(final String[] args) {
        final JTextPane pane = new JTextPane();
        pane.setText("Hello, this is a\nnew lined string! Hope JTextPane is what we are looking for here.");

        final JFrame frame = new JFrame("TextPane with new lines.");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(pane);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
但是,如果您要用任意文本加载它,我建议您在中使用它,并根据您的需要设置
JScrollPane
的首选大小

还测试了
JEditorPane
,它不会像
JTextPane
那么简单

如果您有更多要求,请在评论中告知我们或更新您的问题

编辑1 关于您提供的代码,您会看到第一个窗格与第二个窗格相形见绌,因为您将它们都添加到了内容窗格中,而没有设置。例如,尝试将
LayoutManager
设置为(这将使两个窗格彼此相邻)

根据斜角边框,我可以清楚地看到它,但它确实有点薄,所以这可能就是你没有看到它的原因。我还运行了您提供的代码,它是可见的,但并不容易。无论如何,请尝试以下代码:

import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.BorderFactory; 
import javax.swing.border.Border;

public class MainTextPane {
    public static void main(final String[] args) {
        Border loweredbevel = BorderFactory.createLoweredBevelBorder();

        final JTextPane pane = new JTextPane();
        pane.setText("Hello, this is a\ntwo lined string!");
        final JTextPane pane2 = new JTextPane();
        pane2.setText("Next!");
        pane.setBorder(loweredbevel);
        pane2.setBorder(loweredbevel);


        final JFrame frame = new JFrame("TextPane with new lines.");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new FlowLayout()); //Added this line of code...
        frame.getContentPane().add(pane);
        frame.getContentPane().add(pane2);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

一辆汽车怎么样?还是一个?我不知道你是否能从他们那里复制粘贴。我会尝试一下,然后再给你回复。看起来。。。至少可以说是复杂的。即使你无法复制,我也希望你能用源代码创建小部件,加载文本,缩小到只容纳文本的大小。基本上,是的,如果你想要不可选择的文本,垂直框中每行一个JLabel就是你想要的。代码很短。至于您的“可怕问题”,请在
前面放一个零宽度的空格:
新的JLabel(“\u2060Title”)
尝试了这个方法(使用两个窗格)。看更新的问题。是的,这会得到我需要的。谢谢