javaswingjscrollpanenull-layout-manager

JScrollPane scroll bar won't show up?


package me.an.ugm;

import java.awt.EventQueue;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;

public class Application
{
    private JFrame frame;

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    Application window = new Application();
                    window.frame.setVisible(true);
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
            }

        });
    }

    public Application()
    {
        initialize();
    }

    private void initialize()
    {
        frame = new JFrame();
        frame.setTitle("Application");
        frame.setBounds(100, 100, 401, 450);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);
        //frame.setResizable(false);
        frame.setLocationRelativeTo(null);

        JPanel panel = new JPanel();
        panel.setBounds(0, 0, 296, 710);
        panel.setLayout(null);

        JScrollPane scrollPane = new JScrollPane(panel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setBounds(0, 0, 296, 399);
        frame.getContentPane().add(scrollPane);

        for (int i = 0, j = 10; i < 20; i++, j += 35)
        {
            JButton button1 = new JButton();
            button1.setBounds(10, j, 25, 25);
            panel.add(button1);

            JComboBox<String> selectorBox = new JComboBox<>();
            selectorBox.setBounds(40, j, 200, 25);
            panel.add(selectorBox);

            JButton button2 = new JButton();
            button2.setBounds(245, j, 25, 25);
            panel.add(button2);
        }
    }
}

I don't know why the scroll bar won't show up. The JPanel is bigger than the JScrollPane so I thought it should show up. Also when I try using setPreferredSize for the scroll pane instead of setBounds or setSize then just nothing shows up at all. My end goal for the program is to have a button off to the right to add another set of buttons (the ones in the loop), that would be used to select another item. I wanted the program to start with 10 rows of the buttons, but I set it to 20 to test the scroll bar. Is it a problem with there not being a layout or did I mess something up with the scroll pane?


Solution

  • The problem was not using the correct Swing layouts.

    Here's the GUI I created.

    Application GUI

    I added text to the buttons and combo box, so the GUI would look more realistic. I commented out the look and feel to focus on the GUI. I changed the name of the class because I have one test package for all of the code I write for Stack Overflow.

    I created the button JPanel in a separate method. I used a GridLayout. This allowed me to create 20 rows of 3 Swing components. This also allowed me to space out the components a bit.

    I created the scroll JPanel in another separate method. The key was to use a BorderLayout for the scroll JPanel. I made the scroll JPanel half the size of the button JPanel so it would scroll. You can adjust this calculation however you wish.

    Here's the complete runnable code.

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.GridLayout;
    
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    
    public class JButtonScrollGUI {
        private JFrame frame;
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
    //                  UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                        new JButtonScrollGUI();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
    
            });
        }
        
        private String[] greekAlphabet;
    
        public JButtonScrollGUI() {
            this.greekAlphabet = new String[] { "alpha", "beta", "gamma", "epsilon", "zeta" };
            initialize();
        }
    
        private void initialize() {
            frame = new JFrame();
            frame.setTitle("Application");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            frame.add(createScrollPanel(), BorderLayout.CENTER);
            
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
        
        private JPanel createScrollPanel() {
            JPanel panel = new JPanel(new BorderLayout());
            
            JPanel innerPanel = createButtonPanel();
            Dimension d = innerPanel.getPreferredSize();
            d.width += 50;
            d.height /= 2;
            panel.setPreferredSize(d);
            
            JScrollPane scrollPane = new JScrollPane(innerPanel);
            
            panel.add(scrollPane, BorderLayout.CENTER);
            return panel;
        }
        
        private JPanel createButtonPanel() {
            JPanel panel = new JPanel(new GridLayout(0, 3, 10, 10));
            panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
            
            for (int i = 0; i < 20; i++) {
                JButton button1 = new JButton("Previous " + i);
                panel.add(button1);
    
                JComboBox<String> selectorBox = new JComboBox<>(greekAlphabet);
                panel.add(selectorBox);
    
                JButton button2 = new JButton("Next " + i);
                button2.setPreferredSize(button1.getPreferredSize());
                panel.add(button2);
            }
            
            return panel;
        }
        
    }