-1

I was messing with some code and came across the pack method which is suppose to find the "optimum" size for a window. But when I tried to out it simply made a window as small as possible even though I drew a circle before calling pack(). Why is that? What elements does pack() look for? I also frequently have found code that uses both pack() and setSize() which Oracle explicitly says not to do. What is the point since they both set size?

Here is that part of the code incase it was me who did something wrong:

    public void paint(Graphics g) {
        super.paint(g);
        g.fillOval(x, y, 30, 30);
    }

    public static void main(String[] args) throws InterruptedException {
        JFrame frame = new JFrame("Extreme Pong");
        Game game = new Game();
        frame.add(game);
        frame.pack();
}

Edit: Apparently I either was not clear to most of you since the linked answer to the "duplicate" did not answer my question. The mad programmer did answer my question, so thank you to you.

LegoNinja39
  • 5
  • 1
  • 5
  • 4
    pack() relies on the preferred size of the components. If you use a JPanel subclass to draw, you should override paintComponent() and not paint(), and you should override getPreferredSize(). – JB Nizet Feb 21 '16 at 00:32
  • Oracle says not to override paintComponent and to use paint instead since it calls all the paints (including paintComponent). Also why would I override a getter? Also how would I use it to make pack work properly? – LegoNinja39 Feb 21 '16 at 00:55
  • 2
    *"Oracle says not to override paintComponent and to use paint instead.."* Where exactly does Oracle advise that? Link please.. – Andrew Thompson Feb 21 '16 at 05:30
  • @LegoNinja39 Where does it say that? – MadProgrammer Feb 21 '16 at 06:23
  • Take a look at this [Stack Overflow answer](http://stackoverflow.com/a/35002727/300257) to see pack in action. The code creates a simple Swing GUI that you can use as a basis for further Swing development. – Gilbert Le Blanc Feb 21 '16 at 07:10
  • http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html I think I chose my words wrong. It is not a good idea to override it since it may cause problems later on. Also there is no point since .paint calls it anyway. – LegoNinja39 Feb 22 '16 at 22:38

2 Answers2

2

pack makes use of the layout manager API and "asks" the frame's contentPane for it's preferredSize, this allows pack to "pack" the windows decorations around the content. You have to remember, a windows size includes the windows decorations, so a window of 800x600 will have a viewable area which is noticeably smaller

If you add a component to the frame whose size is undefined (in the case of JComponent and JPanel which return a preferredSize of 0x0, the frame will be packed to its smallest possible size, not really what you want.

So, for example, something like...

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
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);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.fillOval(10, 10, 30, 30);
            g2d.dispose();
        }

    }

}

generates a window of 200x222 on my Mac, but the TestPane will be 200x200

You might also like to have a look at Laying Out Components Within a Container, Painting in AWT and Swing and Performing Custom Painting for some more details

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Ok I thought that the pack method was looking for actual elements and then sizing it accordingly. Thanks for the answer! – LegoNinja39 Feb 23 '16 at 20:27
-2

Using .pack() and .setSize() no make sense, all depend which one is last one in the code but i recommendable use:

 frame.setMinimumSize(new Dimension(x,y));

And please do not forget to add :

frame.setVisible(true);