Search code examples
javaswingjframejpanelpong

How to scale a JFrame around a JPanel?


I try to programm the game PONG.

My Problem: I use the JPanel as the "matchfield" with size (1000;600). But when I add the JPanel to the JFrame with setSize(dimension of the matchfield) i have a problem with the right and the lower border. It seems like the the JFrame gets the size (1000;600) and the JPanel gets smaller. How can I fix it?


Solution

  • The JPanel's size should be determined by its preferred size, not its size. The easiest way to do this is by calling setPreferredSize(...) on it, but that allows other code to change its preferred size, and so the safest way is to override its public Dimension getPreferredSize() method. The JFrame will then naturally size itself correctly if the JPanel is added to the JFrame's BorderLayout-using contentPane, and then you call pack() on the JFrame after adding the JPanel and before displaying it.

    For example:

    public class MyJPanel extends JPanel {
    
        private static final int PREF_W = 1000;
        private static final int PREF_H = 600;
    
        public MyJPanel() {
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
    
            // to make smooth graphics
            Graphics2D g2 = (Graphics2D) g; 
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    
            // do your drawing here
        }
    
        // size the JPanel correctly
        @Override
        public Dimension getPreferredSize() {
            if (isPreferredSizeSet()) {
                return super.getPreferredSize();
            }
            return new Dimension(PREF_W, PREF_H);
        }
    
        private static void createAndShowGui() {
            JFrame frame = new JFrame("My GUI");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(new MyJPanel());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> createAndShowGui());
        }
    }