简体   繁体   English

添加元素后调整JList的大小

[英]JList resize after add element

I have a little problem with size of a JList: 我对JList的大小有一点问题:

There is a JFrame with three JLists(each in JScrollPane). 有一个带有三个JList的JFrame(每个JScrollPane中)。 You can add an item to list by click on it. 您可以通过单击将项目添加到列表。 After program start all JLists have the same width. 程序启动后,所有JList都具有相同的宽度。 But after populate any list is his width reduced and created space is added to empty list equally. 但是在填充任何列表后,他的宽度都会减小,并且创建的空间会平均添加到空列表中。

I want to stop this resizing. 我要停止调整大小。 I hope that the code below will describe my problem better. 我希望下面的代码能更好地描述我的问题。

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);
            }
        });

    }
}

To make your components to be of constant size you will need to use addComponent(Component component, int min, int pref, int max) . 为了使组件具有恒定的大小,您将需要使用addComponent(Component component, int min, int pref, int max) So just replace your code with this 所以只用这个替换你的代码

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));

instead of this 代替这个

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

Here I have used properties of GroupLayout and a constant width 200 to make it stable. 在这里,我使用了GroupLayout属性和200的恒定宽度来使其稳定。

The JList s are likely been resized because of the size of the values been rendered are smaller than they were when they were first created. JList可能会被调整大小,因为呈现的值的大小小于首次创建时的大小。 They are then be re-laid out by the layout manager to meet these new requirements. 然后,布局管理器将它们重新布局,以满足这些新要求。

There is a complicated amount of work going on between the JScrollPane , the JViewport , the JList and the JList s ListCellRenderer in which you don't want to get involved. JScrollPaneJViewportJListJListListCellRenderer之间,需要进行很多复杂的工作,而您不想参与其中。

Instead, you want to provide "hints" to the JList s about how you want them to be sized. 相反,您想向JList提供有关如何调整大小的“提示”。

For example... 例如...

You could use JList#setPrototypeCellValue to provide the JList with informaiton about the maximum size of the value that would be added to the list in the future. 您可以使用JList#setPrototypeCellValueJList提供有关将来将添加到列表的值的最大大小的信息。 This is especially handy when you have a large number of values to add, as the JList won't need to check each one to determine the height of each row and the width required to accommodate the values. 当您要添加大量值时,这特别方便,因为JList无需检查每个值即可确定每一行的高度和容纳这些值所需的宽度。

The drawback is, you will need to know the maximum width of any of the values are likely to add... 缺点是,您将需要知道任何可能增加的值的最大宽度...

Alternatively, you could use a LayoutManager which gives you more control over how components should be positioned and changed, such as GridBagLayout or even MigLayout 另外,您可以使用LayoutManager ,它使您可以更好地控制组件的放置和更改方式,例如GridBagLayout甚至MigLayout

You should also check out Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? 您还应该检查一下是否应该避免在Java Swing中使用set(Preferred | Maximum | Minimum)Size方法?

Here is one way to fix the issue. 这是解决问题的一种方法。

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));

I am not familiar with the GroupLayout manager. 我对GroupLayout管理器不熟悉。 The following document might provide a way to control the layout further. 以下文档可能提供了一种进一步控制布局的方法。 http://docs.oracle.com/javase/tutorial/uiswing/layout/group.html (See Component Size and Resizability) http://docs.oracle.com/javase/tutorial/uiswing/layout/group.html (请参阅组件大小和可缩放性)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM