GridBagLayout中的JTextPane不会按预期方式运行

时间:2015-03-24 18:20:54

标签: java swing jtextarea jtextpane gridbaglayout

我的程序遇到了以下问题。我在JScrollPanel中有一个带有GridBagLayout的JPanel。它应该具有以下行为:

  1. 只能垂直滚动。
  2. 在JPanel中动态添加行。这些行有两列。两列都应该平均分配空间。
  3. 此表的每个字段(列/行)都是JTextPane,因为文本可以编辑并可以显示HTML。如果文本太长,它将被包裹效果,该字段的高度增长。
  4. 调整窗口大小时,列也会调整大小。
  5. 问题是,当文本很长时:

    • 在没有PreferredSize的情况下使用JTextPane时,包装不起作用且列未平均分配。设置首选大小,JTextPane会剪切第二行中的文本。 JEdi​​torPane也不起作用。
    • 当使用带有激活包装的JTextArea时,它比它有效!但是,我无法显示HTML。此外,第四点未得到满足。在扩展窗口时,该字段也会调整大小。但是当再次使窗口变小时,它不会重新调整大小。

    如何获得所需的行为并避免出现这些问题?我已经筋疲力尽了所有可能的想法。

    以下是使用JTextPanes(但没有HTML)所需行为的图片:

    Here is a picture of the desired behavior using <code>JTextPanes</code> (but without HTML)

    使用JTextPanes

    的行为是错误的

    Here is the wrong behavior using JTextPanes:

    这里是SSCCE的代码:

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import javax.swing.BorderFactory;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextPane;
    import javax.swing.ScrollPaneConstants;
    import javax.swing.WindowConstants;
    
    public class EditorTest extends JFrame {
        private JPanel jPanel1;
        private JPanel jPanel2;
        private JScrollPane jScrollPane1;
        private JTextPane jTextPane1;
        private JTextPane jTextPane2;
    
        public EditorTest() {
            initComponents();
        }
    
        private void initComponents() {
            GridBagConstraints gridBagConstraints;
    
            jScrollPane1 = new JScrollPane();
            jPanel2 = new JPanel();
            jPanel1 = new JPanel();
            jTextPane2 = new JTextPane();
            jTextPane1 = new JTextPane();
    
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            setPreferredSize(new Dimension(500, 500));
            getContentPane().setLayout(new GridBagLayout());
    
            jScrollPane1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
            jScrollPane1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    
            jPanel2.setBorder(BorderFactory.createEmptyBorder());
            jPanel2.setLayout(new BorderLayout());
    
            jPanel1.setLayout(new GridBagLayout());
    
            jTextPane2.setContentType("text/html"); 
    
            gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.gridx = 1;
            gridBagConstraints.gridy = 0;
            gridBagConstraints.fill = GridBagConstraints.BOTH;
            gridBagConstraints.weightx = 0.5;
            gridBagConstraints.insets = new Insets(0, 0, 3, 3);
            jPanel1.add(jTextPane2, gridBagConstraints);
    
            jTextPane1.setContentType("text/html");
            jTextPane1.setText("This is a very long text that also sometimes is "
                    + "<span style=\"color:blue\">blue</span> and so on and so on.");
            gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.gridx = 0;
            gridBagConstraints.gridy = 0;
            gridBagConstraints.fill = GridBagConstraints.BOTH;
            gridBagConstraints.weightx = 0.5;
            gridBagConstraints.insets = new Insets(0, 0, 3, 3);
            jPanel1.add(jTextPane1, gridBagConstraints);
    
            jPanel2.add(jPanel1, BorderLayout.NORTH);
    
    
            jScrollPane1.setViewportView(jPanel2);
    
            gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.gridx = 0;
            gridBagConstraints.gridy = 0;
            gridBagConstraints.fill = GridBagConstraints.BOTH;
            gridBagConstraints.weightx = 1.0;
            gridBagConstraints.weighty = 1.0;
            getContentPane().add(jScrollPane1, gridBagConstraints);
    
            pack();
        }                     
    
        public static void main(String args[]) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new EditorTest().setVisible(true);
                }
            });
        }            
    }
    

    非常感谢你的帮助!

    UPDATE1

    为了使所需的行为更加清晰,我创建了一个带有JTextArea的其他屏幕截图,就像在第一张图片中一样。 TextPanes应位于顶部,并且仅在需要时(即文本)。为了说明这种行为,还更改了文本字段的背景。

    enter image description here

2 个答案:

答案 0 :(得分:2)

我想我已经编码了你想要的东西。

我必须在滚动窗格中为JPanel设置首选大小。宽度可以是你想要的任何东西。必须根据JTextPanes的大小调整高度。

这是GUI的图像。

Editor Test

这是代码。

package com.ggl.testing;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.WindowConstants;

public class EditorTest extends JFrame {
    private static final long serialVersionUID = 8019172274009058078L;

    private JPanel jPanel1;
    private JScrollPane jScrollPane1;
    private JTextPane jTextPane1;
    private JTextPane jTextPane2;

    public EditorTest() {
        initComponents();
    }

    private void initComponents() {
        GridBagConstraints gridBagConstraints;

        jScrollPane1 = new JScrollPane();
        jPanel1 = new JPanel();
        jTextPane2 = new JTextPane();
        jTextPane1 = new JTextPane();

        setTitle("Editor Test");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new GridBagLayout());

        jScrollPane1
                .setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jScrollPane1
                .setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

        jPanel1.setLayout(new GridLayout(0, 2));
        jPanel1.setPreferredSize(new Dimension(400, 400));

        jTextPane2.setContentType("text/html");
        jTextPane2
                .setText("<html>This is a very long text that also sometimes is "
                        + "<span style=\"color:green\">green</span> and so on and so on.");

        jTextPane1.setContentType("text/html");
        jTextPane1
                .setText("<html>This is a very long text that also sometimes is "
                        + "<span style=\"color:blue\">blue</span> and so on and so on.");

        jPanel1.add(jTextPane1);
        jPanel1.add(jTextPane2);

        jScrollPane1.setViewportView(jPanel1);

        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        getContentPane().add(jScrollPane1, gridBagConstraints);

        pack();
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new EditorTest().setVisible(true);
            }
        });
    }
}

答案 1 :(得分:1)

我认为你误解了我,所以这里有一个课程可以更清楚地向你展示:

private class MyJTextPane extends JTextPane {
    public Dimension getPreferredSize() {
        return new Dimension(245,super.getPreferredSize().height);
    }
    public Dimension getMaximumSize() {
        return getPreferredSize();
    }
}

您可以在SSCCE中使用此类来查看其行为。

这只是为了让您了解如何使用getMaximumSize和getPreferredSize来实现目标。您必须了解的是,对于给定的宽度,默认的getPreferredSize方法返回显示JTextPane内容所需的高度。

在您的情况下,您只需要用您期望的最终宽度替换245。如果宽度取决于其他元素,也可以使用函数。

告诉我您是否需要更多详细信息。