我正在编写一个简单的程序来测试基本的GUI。程序在屏幕中间打印一个字母,允许用户使用箭头键移动它。一切正常,但是当我尝试在程序开头处将字母居中时,似乎getWidth
和getHeight
函数没有返回正确的数字。
这是包含我的Panel类
的代码段static class LinePanel extends JPanel{
int xCenter = getWidth() /2;
int yCenter = getHeight() /2;
private int x = xCenter;
private int y = yCenter;
private char keyChar = 'A';
public LinePanel(){
addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_DOWN: y += 10; break;
case KeyEvent.VK_UP: y -= 10; break;
case KeyEvent.VK_LEFT: x -= 10; break;
case KeyEvent.VK_RIGHT: x += 10; break;
default: keyChar = e.getKeyChar();
}
repaint();
}
});
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.setFont(new Font("TimesRoman", Font.PLAIN, 24));
g.drawString(String.valueOf(keyChar), x, y);
}
}
为什么我的getWidth
和getHeight
函数返回'0'?
感谢您的帮助
答案 0 :(得分:9)
摆动组件在渲染之前没有宽度或高度。如果您在根容器上调用pack()
或setVisible(true)
,则会发生这种情况。考虑将x y int初始化代码放在添加到JPanel的ComponentListener的componentResized
方法中。
如,
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class TestLinePanel {
private static void createAndShowGui() {
LinePanel mainPanel = new LinePanel();
JFrame frame = new JFrame("TestLinePanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
static class LinePanel extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private char keyChar = 'A';
private int x;
private int y;
private boolean xySet = false;
public LinePanel() {
setFocusable(true);
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_DOWN:
y += 10;
break;
case KeyEvent.VK_UP:
y -= 10;
break;
case KeyEvent.VK_LEFT:
x -= 10;
break;
case KeyEvent.VK_RIGHT:
x += 10;
break;
default:
keyChar = e.getKeyChar();
}
repaint();
}
});
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
if (!xySet) {
int xCenter = getWidth() / 2;
int yCenter = getHeight() / 2;
x = xCenter;
y = yCenter;
requestFocusInWindow();
xySet = true;
}
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(new Font("TimesRoman", Font.PLAIN, 24));
g.drawString(String.valueOf(keyChar), x, y);
}
}
}
您还需要使用key bindings而不是KeyListener来捕获您的击键。
答案 1 :(得分:7)
我不能说出原因,但是:
避免这种情况的一种方法是覆盖getPreferredSize()
功能并返回首选尺寸。
答案 2 :(得分:3)
成员变量在创建对象时被初始化(在任何父类的构造函数之后和当前类的构造函数体之前。当首次创建对象时,Swing不会执行任何大小调整工作。因此,当您调用{时{1}}和getWidth()
,尚未设置任何值。