Search code examples
javaswinglayoutjbuttonjscrollpane

Adding JButtons to Scrollpane


JAVA:

I want to add some JButtons to an Scrollpane. The JButtons are the Chats (like in Skype). I want them in a list with 1 column only. The amount of groups / rows should be flexible. The size of the buttons should be the same all the time (300x50 or something like that) and the text inside the buttons should be aligned left. How can I achieve this?

CODE:

class Chat extends JButton {

    private static final long serialVersionUID = 1L;
    public Group group;


    public Chat(Group group) {
        this.group = group;
        setMinimumSize(new Dimension(300, 50));

        setFocusPainted(false);
        setText(group.groupname);
        setFont(new Font("Tahoma", Font.PLAIN, 30));
        setForeground(Manager.dark);
        setBackground(blue);
        setBorder(new MatteBorder(0, 0, 1, 0, Manager.ct.getForeground()));
    }

}


public void initGroups() {
    int count = 0;
    for(Group group : groups) {
        if(group != null) {
            //TODO: ADD CHATS (GROUPS) TO SCROLLPANE
            count ++;
        }
    }

    if(count == 0) {
        System.out.println("No groups");
    }
}

Solution

  • Start by isolating your required functionality. Start with a JPanel, a GridBagLayout and some buttons...

        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.fill = GridBagConstraints.HORIZONTAL;
    
        for (int index = 0; index < 100; index++) {
            add(new JButton("Chat " + (index + 1)), gbc);
        }
    

    Then add this to a JScrollPane and add that to the primary container, perhaps with a using BorderLayout

    frame.add(new JScrollPane(new ChatListPane()), BorderLayout.LINE_START);
    

    You may find that you may also need to implement the Scrollable interface to better control the size of the JScrollPane to better suit your overall needs. While I used it here, you don't always need it...

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Rectangle;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    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);
                    frame.add(new ChatPane());
                    frame.add(new JScrollPane(new ChatListPane()), BorderLayout.LINE_START);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class ChatPane extends JPanel {
    
            public ChatPane() {
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
        }
    
        public class ChatListPane extends JPanel implements Scrollable {
    
            public ChatListPane() {
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridwidth = GridBagConstraints.REMAINDER;
                gbc.fill = GridBagConstraints.HORIZONTAL;
    
                for (int index = 0; index < 100; index++) {
                    add(new JButton("Chat " + (index + 1)), gbc);
                }
            }
    
            @Override
            public Dimension getPreferredScrollableViewportSize() {
                return new Dimension(100, 100);
            }
    
            @Override
            public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
                return 64;
            }
    
            @Override
            public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
                return 64;
            }
    
            @Override
            public boolean getScrollableTracksViewportWidth() {
                return true;
            }
    
            @Override
            public boolean getScrollableTracksViewportHeight() {
                return false;
            }
    
        }
    
    }
    

    Another, and arguably better, solution would be to use a JList and a custom ListCellRenderer.

    See How to Use Lists for more details