添加元素后JList调整大小

时间:2014-08-26 23:42:48

标签: java swing jlist grouplayout

我对JList的大小有点问题:

有一个JFrame有三个JLists(每个都在JScrollPane中)。您可以通过单击将项目添加到列表中。程序启动后,所有JLists都具有相同的宽度。但填充任何列表后,他的宽度减少,创建的空间被平均添加到空列表中。

我想停止调整大小。我希望下面的代码能更好地描述我的问题。

package test;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class Test extends JFrame {

    public Test() {
        GroupLayout layout = new GroupLayout(this.getContentPane());
        this.setLayout(layout);

        JList listA = new JList(new DefaultListModel<String>());
        JList listB = new JList(new DefaultListModel<String>());
        JList listC = new JList(new DefaultListModel<String>());

        MouseListener listener = new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                ((DefaultListModel) ((JList) e.getSource()).getModel()).addElement("some text");
                revalidate();
            }
        };

        listA.addMouseListener(listener);
        JScrollPane paneA = new JScrollPane(listA);
        listB.addMouseListener(listener);
        JScrollPane paneB = new JScrollPane(listB);
        listC.addMouseListener(listener);
        JScrollPane paneC = new JScrollPane(listC);

        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        layout.setHorizontalGroup(layout.createSequentialGroup().addComponent(paneA).addComponent(paneB).addComponent(paneC));
        layout.setVerticalGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER).addComponent(paneA).addComponent(paneB).addComponent(paneC)));

        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.pack();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                Test test = new Test();
                test.setVisible(true);
            }
        });

    }
}

3 个答案:

答案 0 :(得分:0)

要使您的组件具有恒定大小,您需要使用addComponent(Component component, int min, int pref, int max)。所以只需用这个

替换你的代码
layout.setHorizontalGroup(layout.createSequentialGroup()
    .addComponent(paneA, GroupLayout.PREFERRED_SIZE, 200, GroupLayout.PREFERRED_SIZE)
    .addComponent(paneB, GroupLayout.PREFERRED_SIZE, 200, GroupLayout.PREFERRED_SIZE)
    .addComponent(paneC, GroupLayout.PREFERRED_SIZE, 200, GroupLayout.PREFERRED_SIZE));

而不是

layout.setHorizontalGroup(layout.createSequentialGroup().addComponent(paneA).addComponent(paneB).addComponent(paneC));

我在这里使用GroupLayout属性和常量宽度200来保持稳定。

答案 1 :(得分:0)

JList可能已调整大小,因为渲染值的大小小于首次创建时的大小。然后由布局管理员重新布置它们以满足这些新要求。

{} {}},JScrollPaneJViewportJList JList之间的工作量很复杂我想参与进来。

相反,您希望向ListCellRenderer提供有关您希望如何调整大小的“提示”。

例如......

您可以使用JList#setPrototypeCellValueJList提供有关将来添加到列表中的值的最大大小的信息。当您要添加大量值时,这尤其方便,因为JList不需要检查每个值来确定每行的高度以及容纳值所需的宽度。

缺点是,您需要知道可能添加的任何值的最大宽度......

或者,您可以使用JList来更好地控制应如何定位和更改组件,例如LayoutManager甚至GridBagLayout

您还应该查看Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?

答案 2 :(得分:-1)

以下是解决此问题的一种方法。

JScrollPane paneA = new JScrollPane(listA);
paneA.setPreferredSize(new Dimension(paneA.getPreferredSize().height, 300));
listB.addMouseListener(listener);
JScrollPane paneB = new JScrollPane(listB);
paneB.setPreferredSize(new Dimension(paneB.getPreferredSize().height, 300));
listC.addMouseListener(listener);
JScrollPane paneC = new JScrollPane(listC);
paneC.setPreferredSize(new Dimension(paneC.getPreferredSize().height, 300));

我不熟悉GroupLayout经理。以下文档可能提供进一步控制布局的方法。 http://docs.oracle.com/javase/tutorial/uiswing/layout/group.html(请参阅组件大小和可调整性)