Pedro
Pedro

Reputation: 3

JFrame show labels in a scroll panel

I'm making a frame who needs to show labels in a Scroll Panel, but after I add the labels the scroll don't work.

Example

    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    scrollPane.setBounds(1, 1, 210, 259);

    panel.add(scrollPane);

    JPanel roomList = new JPanel();
    scrollPane.setViewportView(roomList);
    roomList.setLayout(null);

    int x=0;
    for(String l : list) {
        JLabel c = new JLabel(l+" "+x);
        c.setBounds(new Rectangle(1, 1+x*11, 191, 14));
        roomList.add(c);
        x++;
    }

I'm sure the list has more than 22.

I don't know how to google it!

Upvotes: 0

Views: 2012

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347184

Your basic problem is, you don't understand how the layout management API works, or how to replace it's functionality when you choose to discard it.

You problem starts here:

roomList.setLayout(null);

There's a lot of work going on in the background which provides a great deal of information to various parts of the API, while on the surface, the layout management API is not complex, the role it plays is.

The JScrollPane will use the component's preferredSize to determine when it should display the scrollbars. Since you've done away with this automated calculation, the JScrollPane has nothing to go on

For more information, have a look at Laying Out Components Within a Container

As a simple example...

Simple Scroll Example

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                JScrollPane scrollPane = new JScrollPane(new TestPane());
                frame.add(scrollPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel implements Scrollable {

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;

            for (int index = 0; index < 100; index++) {
                add(new JLabel("Row " + index), gbc);
                gbc.gridy++;
            }
        }

        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return new Dimension(100, 50);
        }

        @Override
        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 32;
        }

        @Override
        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 32;
        }

        @Override
        public boolean getScrollableTracksViewportWidth() {
            return getPreferredSize().width <= getWidth();
        }

        @Override
        public boolean getScrollableTracksViewportHeight() {
            return false;
        }

    }

}

This example implements the Scrollable interface, this is not always required, but is used, for this example, to provide a hint to the JScrollPane about the preferred size of the viewable area it should use, otherwise it will attempt to use the component's preferredSize.

But, as has already been suggested, there are other, simpler and more optimised solutions available to you.

If your information is simple enough, you can use a JList to list a number of values in a vertical manner, see How to use Lists for more details.

If you information is in a more complex structure, you could use a JTable, which provides a row and column style structure. See How to use tables for more information

Upvotes: 4

Tengu
Tengu

Reputation: 61

Have you tried using jLists instead of JScrollPanes ?

They're very easily implemented, look great and work like a charm.

DefaultListModel model = new DefaultListModel();
for(String l : list) {
    model.addElement(l);
}

yourList.setModel(model);

Where list is the list with the room data and yourList is the jList.

Upvotes: 3

Related Questions