1

I have a little problem with size of a JList:

There is a JFrame with three JLists(each in JScrollPane). You can add an item to list by click on it. After program start all JLists have the same width. 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);
            }
        });

    }
}
afzalex
  • 8,598
  • 2
  • 34
  • 61
BrooksWasHere
  • 67
  • 3
  • 10
  • Why are you using `grouplayout`? **GroupLayout is a layout manager that was developed for GUI builders such as Matisse**. You must not use it yourself. – afzalex Aug 27 '14 at 00:07
  • @afzalex Although the layout manager was originally designed to suit the GUI builder needs, it also works well for manual coding :) Is a little bit longer (in compare by character count) then other layouts but i think that use this is not big mistake. Or is there any good reason why dont use groupLayout? – BrooksWasHere Aug 27 '14 at 00:21
  • No, but it will be really difficult to use it manually and therefore will be errorprone too. You must use GridBagLayout instead. And I have given answer to do it with GroupLayout. – afzalex Aug 27 '14 at 00:31

3 Answers3

0

To make your components to be of constant size you will need to use 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.

afzalex
  • 8,598
  • 2
  • 34
  • 61
0

The JLists are likely been resized because of the size of the values been rendered are smaller than they were when they were first created. 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 JLists ListCellRenderer in which you don't want to get involved.

Instead, you want to provide "hints" to the JLists about how you want them to be sized.

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. 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.

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

You should also check out Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
-1

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

terrywb
  • 3,740
  • 3
  • 25
  • 50
  • I already read this tutorial, but didnt help me. There is a way to use linkSize() method, but this prevent all resizing :( But you solution works fine :) Thanks – BrooksWasHere Aug 27 '14 at 00:12
  • Take a look at [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi) and be prepared for the scroll panes not work work properly. – MadProgrammer Aug 27 '14 at 00:27
  • 1
    Should be `new Dimension(width, height)` – user3735633 Jun 30 '15 at 16:52