How can I set in the midst?

Without any evidence otherwise, I’d guess you’ve overriden the paint method of something like a JFrame and are painting directly to it.

The problem is, frames have decoration (a border and title bar for example), which takes up space inside the frame…

enter image description here

Technically, this is correct. The rectangle is painted in the center of frame, but the because of the frame’s decorations, it looks like it’s slightly high…

Instead, you should be painting onto the frame’s content area instead.

enter image description here

Here the rectangle now looks correctly centered. In my tests, I set the first frame (bad) to 800×400, I made the second frame’s content pane’s preferred size 800×400, which made the frame size actually 816×438, as the frame’s decorations are now outside of the paint area.

public class CenterOfFrame {

    public static void main(String[] args) {
        new CenterOfFrame();
    }

    public CenterOfFrame() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                new BadFrame().setVisible(true);

                JFrame goodFrame = new JFrame();
                goodFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                goodFrame.setContentPane(new PaintablePane());
                goodFrame.pack();
                goodFrame.setLocationRelativeTo(null);
                goodFrame.setVisible(true);

            }
        });
    }

    public class BadFrame extends JFrame {

        public BadFrame() {
            setSize(800, 400);
            setDefaultCloseOperation(EXIT_ON_CLOSE);
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            paintTest(g, getWidth() - 1, getHeight() - 1);
        }
    }

    public void paintTest(Graphics g, int width, int height) {
        g.setColor(Color.RED);
        g.drawLine(0, 0, width, height);
        g.drawLine(width, 0, 0, height);
        g.drawRect(50, 50, width - 100, height - 100);
    }

    public class PaintablePane extends JPanel {

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
            paintTest(g, getWidth() - 1, getHeight() - 1);
        }
    }
}

This is, one of many reasons, why you should not override the paint method of top level containers 😉

Leave a Comment