【问题标题】:JXTaskPaneContainer grows wrongly when resizing window调整窗口大小时 JXTaskPaneContainer 错误增长
【发布时间】:2014-02-22 14:58:53
【问题描述】:

我的 JFrame 右侧有一个 JXTaskPaneContainer,其中包含超链接和标签。窗口的主要部分应该是:

  • 左侧的一大块区域用于文本
  • 右侧较小的区域显示消息和操作

现在,问题是添加大量新元素会导致容器向左和文本上方增长:

JXTaskPaneContainer 包含在javax.swing.JScrollPane (video/yt) 中时会变得更加奇怪。

问题似乎出在 JXLabel 上。 我怀疑是换行? 任何想法如何解决这个问题?

[示例] 根据要求的独立示例。 Full source on github.

package layoutproblemSSCEC;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import org.jdesktop.swingx.JXButton;
import org.jdesktop.swingx.JXLabel;
import org.jdesktop.swingx.JXTaskPane;
import org.jdesktop.swingx.JXTaskPaneContainer;

public class SwingWindow {

    private JFrame frame;
    String dolorem = "Sed ut perspiciatis unde omnis iste natus error sit "
            + "voluptatem accusantium doloremque laudantium, totam rem aperiam, "
            + "eaque ipsa quae ab illo inventore veritatis et quasi architecto "
            + "beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem "
            + "quia voluptas sit aspernatur aut odit aut fugit, sed quia "
            + "consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. "
            + "Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, "
            + "consectetur, adipisci velit, sed quia non numquam eius modi tempora "
            + "incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut "
            + "enim ad minima veniam, quis nostrum exercitationem ullam corporis "
            + "suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? "
            + "Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse "
            + "quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat "
            + "quo voluptas nulla pariatur?";

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    SwingWindow window = new SwingWindow();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public SwingWindow() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JXTaskPaneContainer panels = new JXTaskPaneContainer();
        JScrollPane scrollpanel = new JScrollPane(panels);

        Container content = frame.getContentPane();
        content.add(new JTextArea(dolorem), BorderLayout.CENTER);
        content.add(scrollpanel, BorderLayout.EAST);
        content.add(new JXButton(new AbstractAction("Click me") {

            public void actionPerformed(ActionEvent arg0) {
                JXTaskPane panel = new JXTaskPane("test");
                JXLabel lbl = new JXLabel(dolorem);
                lbl.setLineWrap(true);
                panel.add(lbl);
                panels.add(panel);
            }
        }), BorderLayout.NORTH);

        panels.add(new JXTaskPane("Click the button, then resize"));
    }

}

【问题讨论】:

  • 检查 layoutManager - taskPane(或容器,忘记细节)需要一个尊重 prefSize 的管理器。如果这没有帮助,请发布 SSCCE 来证明问题
  • 谢谢。我会尝试一下 GridBagLayout。
  • repeating:显示一个 SSCCE 来证明问题 - 我很确定你会得到一个简洁的答案 ;-)
  • 完成。 :) 查看链接后的完整代码。这是我能做到的尽可能简洁。如果你在 Eclipse 中克隆它,我认为 Maven 会处理依赖项(swingx-all-1.6.5-1)。
  • 不,这不是 SSCCE:它既不短也不独立,也不发布 here ;-) 重现一个简单的布局问题不应该花费超过 50 - 80 行代码.不过,很高兴知道您的 swingx 版本,因此我可以针对正确的版本运行您未来的 SSCCE。

标签: java swing swingx


【解决方案1】:

我希望我的问题有一个简洁的答案。恐怕没有。 我通过创建一个基于GridBagLayout 而不是BorderLayout 的新布局解决了这个问题。

还有设置最小首选尺寸的问题。如果不调用setMinimumSize(new Dimension(200, 127)),容器的宽度似乎会无限缩小,尽管广告首选宽度为 600。我仍然不确定这是从哪里来的。这些数字来自组件的初始首选大小。

tutorial on oracle's site 在这里帮助了我。重要的部分是找到有效的权重。大于 0 的权重值允许组件增长和缩小。

这是布局代码现在的样子:

frmvanInput = new JFrame(); // window
// ... captions, titles, etc

frmvanInput.setContentPane(new JPanel(new GridBagLayout()));

// ... more initializing

/** 
 * LAYOUTS
 */
final Container contentPane = frmvanInput.getContentPane();

// the menu bar is on top, stretches all the way right
GridBagConstraints menuBarLayout = new GridBagConstraints();
// top left
menuBarLayout.anchor = GridBagConstraints.FIRST_LINE_START; // push to the top left
menuBarLayout.gridx = 0; 
menuBarLayout.gridy = 0;
// manage width
menuBarLayout.gridwidth = 2; // stretch
menuBarLayout.fill = GridBagConstraints.HORIZONTAL; // fill all x-space
menuBarLayout.weightx = 0.5; // a weight > 0 allows for resizing
//add
contentPane.add(menuBar, menuBarLayout);

// the text field is under the menu on the left and shares a row with the errors panel/scroll pane
GridBagConstraints textfieldLayout = new GridBagConstraints();
// top left
textfieldLayout.anchor = GridBagConstraints.FIRST_LINE_START; // push to the top left
textfieldLayout.gridx = 0; // col left
textfieldLayout.gridy = 1; // row center
// manage stretching
textfieldLayout.weightx = 0.5; // resizable
textfieldLayout.weighty = 0.5; // resizable
textfieldLayout.fill = GridBagConstraints.BOTH;
// add
contentPane.add(txtEditor, textfieldLayout);

errorScrollPane = new JScrollPane(containerTaskPanel);
// prevent indefinate shrinking
errorScrollPane.setMinimumSize(new Dimension(200, 127));

GridBagConstraints scrollpanelLayout = new GridBagConstraints();
// middle, right
scrollpanelLayout.anchor = GridBagConstraints.FIRST_LINE_END;
scrollpanelLayout.gridx = 1; // right row
scrollpanelLayout.gridy = 1; // center column
// stretch to fill
scrollpanelLayout.weightx = 0.5; // resizable
scrollpanelLayout.weighty = 0.5; // resizable
scrollpanelLayout.fill = GridBagConstraints.BOTH;
// add our controls to the visible world
contentPane.add(errorScrollPane, scrollpanelLayout);

// the emitter panel has the bottom row to itself
GridBagConstraints emitterpanelLayout = new GridBagConstraints();
// bottom left
emitterpanelLayout.anchor = GridBagConstraints.LAST_LINE_START;
emitterpanelLayout.gridx = 0; // col left
emitterpanelLayout.gridy = 2; // row bottom
// stretch width
emitterpanelLayout.weightx = 0.5;
emitterpanelLayout.gridwidth = 2;
// manage height:
emitterpanelLayout.weighty = 0.1;
emitterpanelLayout.fill = GridBagConstraints.BOTH;
// add
contentPane.add(emitterScrollPane, emitterpanelLayout);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 1970-01-01
    • 1970-01-01
    • 2019-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多