2

In my code, currently each card is the size of my frame. How do I set different sizes of each of my panels in the layout. I tried making the frame different sizes by calling the run() method and changing the size of the frame, but it does not work. I'm hoping there is another way. This is my code:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class GameManager
{
    JFrame frame;
    JPanel cards,Title;
    public GameManager()
    {
        cards = new JPanel(new CardLayout());
        Title title = new Title();
        cards.add(title,"title");
        CardLayout cl = (CardLayout)(cards.getLayout());
        cl.show(cards, "title");
    }
    public static void main(String [] args)
    {
        GameManager gm = new GameManager();
        gm.run();
    }
    public void run()
    {
        frame = new JFrame("Greek Olympics");
        frame.setSize(1000,1000);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(cards);
        frame.setVisible(true);
        CardLayout cl = (CardLayout)(cards.getLayout());
        cl.show(cards, "title");
    }
    public class Title extends JPanel
    {
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            g.fillRect(100,100,100,100);
        }
    }
}

How would I change the code so that if I wanted to add another panel with a different size?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Anushka
  • 35
  • 4

1 Answers1

4

How do I set different sizes of each of my panels in the layout

First, understand that CardLayout will use the preferredSize property of all the view's it's managing to determine the best resulting size that the container it's managing should use. This means that if you call pack on the frame (instead of setSize), it will be sized (automatically) to the largest component been managed (by the CardLayout)

How would I change the code so that if I wanted to add another panel with a different size?

Each component you add to the CardLayout should either be calculating it's size through one or more appropriate layout managers, or, in the case of custom components, be providing a sizing hint through the getPreferredSize method

public class Title extends JPanel
{
    @Override 
    public Dimension getPreferredSize() {
        return new Dimension(200, 200);
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.fillRect(100,100,100,100);
    }
}

Then, instead of using setSize, use pack

public void run()
{
    frame = new JFrame("Greek Olympics");
    //frame.setSize(1000,1000);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(cards);
    frame.pack();
    CardLayout cl = (CardLayout)(cards.getLayout());
    cl.show(cards, "title");
    frame.setVisible(true);
}

Example...

This is a basic example which sets up two panels, one with preferredSize of 200x200 and one with 400x400

When you run it, you will find the window will be at least 400x400 and both panels will be the same size

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
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);

                CardLayout cardLayout = new CardLayout();
                JPanel base = new JPanel(cardLayout);
                base.add(makePanel(200, 200, Color.RED), "red");
                base.add(makePanel(400, 400, Color.BLUE), "blue");

                frame.add(base);

                JButton blue = new JButton("Blue");
                blue.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        cardLayout.show(base, "blue");
                    }
                });
                JButton red = new JButton("red");
                red.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        cardLayout.show(base, "red");
                    }
                });

                JPanel buttons = new JPanel();
                buttons.add(red);
                buttons.add(blue);

                frame.add(buttons, BorderLayout.SOUTH);

                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public TestPane makePanel(int width, int height, Color background) {
        TestPane pane = new TestPane(new Dimension(width, height));
        pane.setBackground(background);
        return pane;
    }

    public class TestPane extends JPanel {

        private JLabel label;
        private Dimension preferredSize;

        public TestPane(Dimension size) {
            label = new JLabel("...");
            setLayout(new GridBagLayout());
            add(label);
            this.preferredSize = size;
        }

        @Override
        public Dimension getPreferredSize() {
            return preferredSize;
        }

        @Override
        public void invalidate() {
            super.invalidate();
            label.setText(getWidth() + "x" + getHeight());
        }

    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • It does not seem to change anything. Luckily, it compiles but the frame size does not change. – Anushka May 06 '18 at 00:22
  • Based on the example, the frame should be sized to wrap about the component, which should be sized to 200x200 - additional components will affect the ultimate size of the frame, allowing for the maximum width/height (based on their preferred sizes) of all the components managed - the frame won’t change size for each view and I’d avoid doing thus as it’s annoying – MadProgrammer May 06 '18 at 00:45
  • I did your code and the actual frame is not visible. I added but the frame is never shown. Did I implement it incorrectly? – Anushka May 06 '18 at 01:08
  • import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; public class GameManager { JFrame frame; JPanel cards, TitleScreen, EventsScreen, Running; public GameManager() { cards = new JPanel(new CardLayout()); TitleScreen title = new TitleScreen(); cards.add(title,"title"); EventsScreen events = new EventsScreen(); cards.add(events,"events"); Running run = new Running(); cards.add(run, "running"); } public static void main(String [] args) { GameManager gm = new GameManager(); gm.run(); } – Anushka May 06 '18 at 01:09
  • public void run() { frame = new JFrame("Greek Olympics"); //frame.setSize(1000,750); frame.pack(); frame.setLocation(0,0); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //frame.getContentPane().add(cards); frame.add(cards); frame.setVisible(true); CardLayout cl = (CardLayout)(cards.getLayout()); cl.show(cards, "title"); } – Anushka May 06 '18 at 01:09
  • public class TitleScreen extends JPanel implements MouseListener, MouseMotionListener { boolean playButtonClicked, howButtonClicked, play; int mouseX, mouseY; public TitleScreen() { playButtonClicked = howButtonClicked = play = false; mouseX = mouseY = 0; addMouseListener(this); addMouseMotionListener(this); } public Dimension getPreferredSize() { return new Dimension(400,400); } – Anushka May 06 '18 at 01:09
  • That is all my code, what am I doing wrong that the frame is no longer visible? – Anushka May 06 '18 at 01:10
  • @Anushka Comments don't make a good place to put code - I've update the answer with a runnable example – MadProgrammer May 06 '18 at 05:18