控制长文本 JEditorPane 的首选大小

发布于 2024-08-20 19:39:33 字数 2269 浏览 1 评论 0 原文

我有一个 JEditorPane,它显示在弹出窗口内,通过按钮触发。该窗格包含长文本,因此它嵌套在 JScrollPane 内,并且弹出窗口的最大尺寸限制为 300 x 100:

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            String text = "Potentially looooooong text. " + 
                "Lorem ipsum dolor sit amet, consectetuer" +
                "adipiscing elit, sed diam nonummy nibh euismod " +
                "tincidunt ut laoreet dolore magna aliquam" + 
                "adipiscing elit, sed diam nonummy nibh euismod" + 
                "erat volutpat. Ut wisi enim ad minim veniam, " + 
                "quis nostrud exerci tation.";

            final JEditorPane editorPane = new JEditorPane("text/html", text);
            editorPane.setEditable(false);

            final JButton button = new JButton("Trigger Popup");
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JPopupMenu popup = new JPopupMenu();
                    popup.setLayout(new BorderLayout());
                    popup.add(new JScrollPane(editorPane));
                    Dimension d = popup.getPreferredSize();
                    int w = Math.min(300, d.width);
                    int h = Math.min(100, d.height);
                    popup.setPopupSize(w, h);
                    Dimension s = button.getSize();
                    popup.show(button, s.width / 2, s.height / 2);
                }
            });

            JFrame f = new JFrame("Layout Demo");
            f.setSize(200, 200);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setLocationRelativeTo(null);
            f.getContentPane().add(button);
            f.setVisible(true);
        }
    });
}

当第一次显示 JEditorPane 实例时时间(即单击按钮一次)它似乎以某种方式报告太小的首选高度(1)

第一次调用

单击后续按钮后,布局正如人们所期望的(2)

后续调用

我如何强制/施加适当的首选大小,以便它始终像 (2) 一样初始化?

I have a JEditorPane which is displayed inside a popup, triggered through a button. The pane contains long text, therefore it's nested inside a JScrollPane, and the popup is constrained to a maximal size of 300 x 100:

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            String text = "Potentially looooooong text. " + 
                "Lorem ipsum dolor sit amet, consectetuer" +
                "adipiscing elit, sed diam nonummy nibh euismod " +
                "tincidunt ut laoreet dolore magna aliquam" + 
                "adipiscing elit, sed diam nonummy nibh euismod" + 
                "erat volutpat. Ut wisi enim ad minim veniam, " + 
                "quis nostrud exerci tation.";

            final JEditorPane editorPane = new JEditorPane("text/html", text);
            editorPane.setEditable(false);

            final JButton button = new JButton("Trigger Popup");
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JPopupMenu popup = new JPopupMenu();
                    popup.setLayout(new BorderLayout());
                    popup.add(new JScrollPane(editorPane));
                    Dimension d = popup.getPreferredSize();
                    int w = Math.min(300, d.width);
                    int h = Math.min(100, d.height);
                    popup.setPopupSize(w, h);
                    Dimension s = button.getSize();
                    popup.show(button, s.width / 2, s.height / 2);
                }
            });

            JFrame f = new JFrame("Layout Demo");
            f.setSize(200, 200);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setLocationRelativeTo(null);
            f.getContentPane().add(button);
            f.setVisible(true);
        }
    });
}

When the JEditorPane instance is shown for the first time (i.e. when the button is clicked once) it somehow seems to report a preferred height which is too small (1):

first invocation

After subsequent button clicks, the layout is just how one would expect it (2):

subsequent invocations

How can I enforce/impose a proper preferred size so it would always initialize like (2)?

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

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

发布评论

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

评论(1

黯然#的苍凉 2024-08-27 19:39:33

JEditorPane 无法同时计算其最终首选宽度和高度,它必须先知道其中一个,然后才能计算另一个。

第一遍中,JEditorPane 基于其宽度不受限制的假设来计算其首选高度,因此它返回单行的高度(因为文本不包含换行符)。

在 第二遍,宽度已经设置(受第一个 JPopupMenu 的大小限制),现在它知道最大宽度,可以计算它需要多高。

因此,最简单的解决方案就是在设置文本时将宽度设置为最大值。

String text = "Potentially looooooong text. " + 
    "Lorem ipsum dolor sit amet, consectetuer" +
    "adipiscing elit, sed diam nonummy nibh euismod " +
    "tincidunt ut laoreet dolore magna aliquam" + 
    "adipiscing elit, sed diam nonummy nibh euismod" + 
    "erat volutpat. Ut wisi enim ad minim veniam, " + 
    "quis nostrud exerci tation.";

final JEditorPane editorPane = new JEditorPane("text/html", text);
editorPane.setSize(300, Integer.MAX_VALUE);
editorPane.setEditable(false);

不要担心它太大,它仍然会缩小以适应内容(正如您将文本更改为 “Hello, World!” 所看到的。

The JEditorPane cannot compute its final preferred width and height simultaneously, it has to know one before it can compute the other.

On the first pass, the JEditorPane computes its preferred height based on the assumption that its width will be unlimited, so it returns the height of a single line (since the text contains no line breaks.)

On the second pass, the width has already been set (constrained by the size of the first JPopupMenu), and now that it knows the maximum width it can compute how tall it needs to be.

So the simplest solution is just to set the width to the maximum whenever you set the text.

String text = "Potentially looooooong text. " + 
    "Lorem ipsum dolor sit amet, consectetuer" +
    "adipiscing elit, sed diam nonummy nibh euismod " +
    "tincidunt ut laoreet dolore magna aliquam" + 
    "adipiscing elit, sed diam nonummy nibh euismod" + 
    "erat volutpat. Ut wisi enim ad minim veniam, " + 
    "quis nostrud exerci tation.";

final JEditorPane editorPane = new JEditorPane("text/html", text);
editorPane.setSize(300, Integer.MAX_VALUE);
editorPane.setEditable(false);

Don't worry about making it too large, it will still shrink to fit the content (as you will see if you change the text to "Hello, World!".

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