为什么必须在 paintComponent() 内部初始化 x 和 y 坐标?
Why must x and y coordinates be initialized inside paintComponent()?
练习 1609:编写一个使用箭头键绘制线段的程序。当按下右箭头键、上箭头键、左箭头键或下箭头键时,该线从框架的中心开始向东、北、西或南绘制。简而言之,画一个迷宫。有关我的问题的描述,请参阅下面的评论。
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...这就是我想要的。
getWidth()
和 getHeight()
在 UI 元素通过布局通道之前未正确设置。这保证在调用 paintComponent()
之前发生,但可能不会在您尝试调用它们的其他点发生。
参见:getWidth() and getHeight() are 0 after calling setPreferredSize()
如果需要在组件宽高为set/changed时得到通知,查看ComponentListener
:http://docs.oracle.com/javase/7/docs/api/java/awt/event/ComponentListener.html
练习 1609:编写一个使用箭头键绘制线段的程序。当按下右箭头键、上箭头键、左箭头键或下箭头键时,该线从框架的中心开始向东、北、西或南绘制。简而言之,画一个迷宫。有关我的问题的描述,请参阅下面的评论。
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...这就是我想要的。
getWidth()
和 getHeight()
在 UI 元素通过布局通道之前未正确设置。这保证在调用 paintComponent()
之前发生,但可能不会在您尝试调用它们的其他点发生。
参见:getWidth() and getHeight() are 0 after calling setPreferredSize()
如果需要在组件宽高为set/changed时得到通知,查看ComponentListener
:http://docs.oracle.com/javase/7/docs/api/java/awt/event/ComponentListener.html