Search code examples
javaswingscrollbarjscrollpanejsplitpane

JScrollPane not showing the scroll bars inside a JSplitPane


I have this piece of code that is basically a JFrame that contains a JSplitPane which contains on the left side a JScrollPane which contains a JPanel. I expected to see the scroll bars since the JPanel inside the JScrollPane is larger that the JScrollPane itself. Why are the scroll bars not displayed? If I replace setSize() with setPreferredSize() then it works, but I want to use setSize(). Is there any way I can use setSize() and have the scroll bars showing?

import java.awt.*;
import javax.swing.*;

public class Test {

    public static void main( String[] args ) {
        JFrame frame = new JFrame();
        frame.setLayout( new BorderLayout() );
        JSplitPane splitPane = new JSplitPane();
        frame.add( splitPane, BorderLayout.CENTER );
        JPanel panel = new JPanel();
        panel.setBackground( Color.red );
        panel.setSize( 1920, 1200 );
        //panel.setPreferredSize( new Dimension( 1920, 1200 ) );
        JScrollPane scrollPane = new JScrollPane( panel );
        splitPane.setLeftComponent( scrollPane );
        splitPane.setRightComponent( new JPanel() );
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible( true );
        frame.setSize( 960, 600 );
    }
}

Edit: I've added a modified version where I use setPreferredSize(). Is there a better solution for dynamically changing the size?

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test {

    public static void main( String[] args ) {
        JFrame frame = new JFrame();
        frame.setLayout( new BorderLayout() );
        JSplitPane splitPane = new JSplitPane();
        frame.add( splitPane, BorderLayout.CENTER );
        final JPanel panel = new JPanel();
        panel.setBackground( Color.red );
        panel.setPreferredSize( new Dimension( 1920, 1200 ) );
        JScrollPane scrollPane = new JScrollPane( panel );
        splitPane.setLeftComponent( scrollPane );
        JButton button = new JButton();
        button.addActionListener( new ActionListener() {

            @Override
            public void actionPerformed( ActionEvent e ) {
                panel.setPreferredSize( new Dimension( 3840, 2400 ) );
                panel.revalidate();
            }
        });
        splitPane.setRightComponent( button );
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible( true );
        frame.setSize( 960, 600 );
    }
}

Solution

  • Your setSize will be ignored by the JSplitPane because the layout of the left/right components is not null, and it tries to fit the internal components in the available space.

    The layout manager for the JSplitPane's left/right components honors the preferredSize property(and not the size property) and if it hasn't been set, it just tries to fit the internal component inside the available space of left/right area in JSplitPane.

    Use setPreferredSize instead or override the getPreferredSize method for your panel as camickr described in the comment.