为什么必须在paintComponent()中初始化x和y坐标?

时间:2015-01-27 18:15:27

标签: java paintcomponent

Exercise1609 编写一个使用箭头键绘制线段的程序。当按下右箭头键,上箭头键,左箭头键或下箭头键时,该线从框架的中心开始向东,北,西或南方向绘制。简而言之,画一个迷宫。有关我的问题的说明,请参阅下面的评论。

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.JFrame;
    import javax.swing.JPanel;

    public class Exercise1609 extends JFrame {

        private KeyboardPanel panel = new KeyboardPanel();

        public Exercise1609() {
            add(panel);
            panel.setFocusable(true);
        }

        public static void main(String[] args) {
            Exercise1609 frame = new Exercise1609();
            frame.setTitle("Tegn med piltaster");
            frame.setSize(600, 300);
            frame.setLocationRelativeTo(null);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }

       //The panel that listens for key and responds by drawing             
       public static class KeyboardPanel extends JPanel {

            private int x,y,previousX,previousY;
            private boolean firstTime = true;

            public KeyboardPanel() {

                /**
                 * why must x and y be initialized inside paintComponent? 
                 * if I want to start drawing from the middle of the panel?
                 * If I remove the if-block inside paintComponent and instead
                 * place the initialization here, as shown with the two lines below:
                 * x = previousX = getWidth() / 2;
                 * y = previousY = getHeight() / 2;
                 * ...then the program will not start to draw from the middle,
                 * but upper left corner of the screen
                 */
                addKeyListener(new KeyAdapter() {
                    @Override
                    public void keyPressed(KeyEvent e) {
                        previousY = y;
                        previousX = x;          
                        switch (e.getKeyCode()) {
                        case KeyEvent.VK_DOWN:
                            y++;
                            break;
                        case KeyEvent.VK_UP:        
                            y--;
                            break;
                        case KeyEvent.VK_RIGHT:
                            x++;
                            break;
                        case KeyEvent.VK_LEFT:
                            x--;
                            break;
                        }
                        repaint();
                    }
                });
            }//end constructor

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponents(g);

                if(firstTime) {
                 //Why can't x and y be initialized outiside paintComponent?
                 //Why can't they be initialized inside the constructor of this class?
                 x = previousX = getWidth() / 2;
                 y = previousY = getHeight() / 2;
                 firstTime = false;
                }
                g.drawLine(previousX, previousY, x, y);
                System.out.println(x + " " + y);

            }
        }

    }

如果我尝试在其他地方初始化x和y,则最后一行System.out.println(x + " " + y);输出0,0 但是paintComponent()。当在paintcomponent()中初始化时,输出为292,131 ......这就是我想要的。

1 个答案:

答案 0 :(得分:2)

在UI元素经过布局传递之前,

getWidth()getHeight()未正确设置。这可以保证在调用paintComponent()之前发生,但可能不会在您尝试调用它们的其他位置发生。

请参阅:getWidth() and getHeight() are 0 after calling setPreferredSize()

如果您需要在设置/更改组件的宽度和高度时收到通知,请查看ComponentListenerhttp://docs.oracle.com/javase/7/docs/api/java/awt/event/ComponentListener.html