Is there a better way to set an initial position for a JPanel graphic?)

前端 未结 1 1163
一向
一向 2021-01-22 15:38

In Chapter 15 of Liang\'s Intro to Java Programming (7th ed.), he introduces a program to make a (2-D) ball on a JPanel and enlarge it upon clicking enlarge/shrink butt

相关标签:
1条回答
  • 2021-01-22 16:17

    Several things merit attention:

    • Override getPreferredSize() to establish the panel's initial geometry.

    • Use that geometry to establish the ball's initial position.

    • Invoke pack() and then set the location & visibility.

    • Use Action to encapsulate code shared by menus and controls.

    • Use adapters consistently.

    • Use initial threads correctly.

    • See this Q&A, which examines a related example from several perspectives.

    image

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    
    public class ControlBall extends JFrame {
    
        private JButton jbtRed = new JButton("Red");
        private JButton jbtGreen = new JButton("Green");
        private JButton jbtBlue = new JButton("Blue");
        private JButton jbtBlack = new JButton("Black");
        private BallCanvas canvas = new BallCanvas();
        private JMenuBar menuBar = new JMenuBar();
        private JMenu menu = new JMenu("Edit");
        private JMenuItem miEnlarge = new JMenuItem("Enlarge");
        private JMenuItem miShrink = new JMenuItem("Shrink");
    
        public ControlBall() {
    
            menuBar.add(menu);
            menu.add(miEnlarge);
            menu.add(miShrink);
    
            JPanel panel = new JPanel();
            panel.add(jbtRed);
            panel.add(jbtGreen);
            panel.add(jbtBlue);
            panel.add(jbtBlack);
    
            this.add(canvas, BorderLayout.CENTER);
            this.add(panel, BorderLayout.SOUTH);
            this.add(menuBar, BorderLayout.NORTH);
    
            jbtRed.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    canvas.setColor(Color.RED);
                }
            });
    
            jbtGreen.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    canvas.setColor(Color.GREEN);
                }
            });
    
            jbtBlue.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    canvas.setColor(Color.BLUE);
                }
            });
    
            jbtBlack.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    canvas.setColor(Color.BLACK);
                }
            });
    
            miEnlarge.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    canvas.enlarge();
                }
            });
    
            miShrink.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    canvas.shrink();
                }
            });
    
            canvas.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    canvas.changeSize(e);
                }
    
                @Override
                public void mouseDragged(MouseEvent e) {
                    canvas.move(e);
                }
            });
        }
    
        public static void main(String[] args) {
    
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new ControlBall();
                    frame.setTitle("ControlBall");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
    
        }
    
        public static class BallCanvas extends JPanel {
    
            private static final int SIZE = 400;
            private int radius = 20;
            private Color color = Color.BLACK;
            private int ballX = SIZE / 2 - radius;
            private int ballY = SIZE / 2 - radius;
    
            public BallCanvas() {
                System.out.println(getWidth() + " " + getHeight());
            }
    
            public BallCanvas(int initialRadius) {
                radius = initialRadius;
            }
    
            public void setColor(Color color) {
                this.color = color;
                repaint();
            }
    
            public void changeSize(MouseEvent e) {
    
                int numClicks = e.getClickCount();
    
                if (e.isAltDown()) {
                    if (radius >= 6) {
                        this.radius -= 5 * numClicks;
                    } else {
                        // do nothing
                    }
                } else {
    
                    this.radius += 5 * numClicks;
                }
    
                repaint();
    
            }
    
            public void enlarge() {
    
                this.radius += 5;
                repaint();
    
            }
    
            public void shrink() {
    
                if (radius >= 10) {
                    this.radius -= 5;
                }
                repaint();
            }
    
            public void move(MouseEvent e) {
    
                ballX = e.getX() - radius;
                ballY = e.getY() - radius;
                repaint();
    
            }
    
            @Override
            protected void paintComponent(Graphics g) {
    
                super.paintComponent(g);
                g.setColor(color);
                g.fillOval(ballX, ballY, 2 * radius, 2 * radius);
    
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(SIZE, SIZE);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题