Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't get JPanel to size properly in Swing

I'm just learning Swing, and built a sample GUI for myself as practice. Very basic, it has three panels on the West, Center, and East sides of the JFrame. In the last panel, there is another panel and a button. The panel is my extension of JPanel, DrawPanel. It draws a random Rectangle every time the button beneath it Repaint is clicked. This is my code:

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

public class Tester
{
    public static DrawPanel panelEastDrawPanelCenter;

    public static void main()
    {
        Tester gui = new Tester();
        gui.go();
    }
    public void go()
    {
        JFrame frame = new JFrame("This is the title");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create all the Western Panel components
        JPanel panelWest = new JPanel();
        //    panelWest.setLayout(new BorderLayout());
        JButton panelWestButtonWest = new JButton("Western-most West Button");
        JButton panelWestButtonCenter = new JButton("Western-most Center Button");
        JButton panelWestButtonEast = new JButton("Western-most East Button");

        // Create all Center Panel components
        JPanel panelCenter = new JPanel();
            panelCenter.setBackground(Color.darkGray);
        JButton panelCenterButtonCenter = new JButton("Center Button");

        // Create all East Panel components
        JPanel panelEast = new JPanel();
        panelEastDrawPanelCenter = new DrawPanel();
            panelEastDrawPanelCenter.setSize(50,50);
        JButton panelEastButtonSouth = new JButton("Repaint");
            panelEastButtonSouth.addActionListener(new panelEastButtonSouthListener());

        // Add everything to the GUI
        // West Panel
        frame.getContentPane().add(BorderLayout.WEST, panelWest);
        panelWest.add(BorderLayout.WEST, panelWestButtonWest);
        panelWest.add(BorderLayout.CENTER, panelWestButtonCenter);     
        panelWest.add(BorderLayout.EAST, panelWestButtonEast);

        // Center Panel
        frame.getContentPane().add(BorderLayout.CENTER, panelCenter);
        panelCenter.add(BorderLayout.CENTER, panelCenterButtonCenter);

        // East Panel
        frame.getContentPane().add(BorderLayout.EAST, panelEast);
        panelEast.add(panelEastDrawPanelCenter);
        panelEast.add(panelEastButtonSouth);

        frame.pack();
        //frame.setSize(frame.getWidth(), 500);
        frame.setVisible(true);
    }
    class panelEastButtonSouthListener implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            panelEastDrawPanelCenter.repaint();
        }
    }
    class DrawPanel extends JPanel // JPanel that displays a rectangle upon clicking the button "Repaint"
    {
        public void paintComponent(Graphics g)
        {
            g.setColor(Color.WHITE); // Removes previous rectangle
            g.fillRect(0,0, this.getWidth(),this.getHeight());

            g.setColor(randColor()); // Puts a new rectangle on screen, rand size and color
            int height = (int)(Math.random() * this.getHeight());
            int width = (int)(Math.random() * this.getHeight());
            int x = (int)(Math.random() * 20);
            int y = (int)(Math.random() * 20);
            g.fillRect(x,y, height,width);
        }
        public Color randColor()
        {
            int r = (int)(Math.random() * 255);
            int g = (int)(Math.random() * 255);
            int b = (int)(Math.random() * 255);
            return new Color(r, g, b);
        }
    }
}

The problem I am encountering is that although I explicitly setSize() for the DrawPanel object (panelEastDrawPanelCenter) to 50×50, when I run the program it (DrawPanel) is still a small panel next to the button, and panelEast (the container for DrawPanel and the button) is still the same width (and will never get wider). I realize that I can say

frame.pack();
frame.setSize(frame.getWidth(), 500);

if I set the east panel to use a layout of either BorderLayout or BoxLayout, and this will make the DrawPanel display bigger.

  1. But I do not understand why setting the size of the DrawPanel object does not actually change its size, and why it remains small regardless of me doing setSize(50,50);
  2. How would I get the middle panel to stop resizing so huge, so that the East panel can resize to be wider? Or how do I resize the East panel?
like image 978
Alex G Avatar asked Dec 15 '22 22:12

Alex G


2 Answers

The BorderLayout respects the preferred width of its west and east components. And it respects the preferred width and height of its center component. So, your DrawPanel should override getPreferredSize() and return the appropriate preferred size.

Since it's placed at the center of a BorderLayout which also has a south component, the preferred width of the east panel will be the max of the preferred width of the draw panel and of the button.

like image 185
JB Nizet Avatar answered Jan 02 '23 20:01

JB Nizet


Have you tried using panel.setPerferredSize(Dimension size);

like image 35
David Kroukamp Avatar answered Jan 02 '23 21:01

David Kroukamp