为什么我不能访问我的面板的getWidth()和getHeight()函数?

我正在编写一个简单的程序来测试基本的GUI。 程序在屏幕中间打印一个字母,允许用户使用箭头键移动它。 一切正常,但是当我尝试在程序开头处将字母居中时,似乎getWidthgetHeight函数没有返回正确的数字。

这是包含我的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); } } 

为什么我的getWidthgetHeight函数返回’0’?

谢谢你的帮助

我不能说出原因,但是:

避免这种情况的一种方法是覆盖你的getPreferredSize()函数并返回你的首选大小。

摆动组件在渲染之前没有宽度或高度。 如果在根容器上调用pack()setVisible(true) ,则会发生这种情况。 考虑将xy 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); } } } 

您还需要使用键绑定而不是KeyListener来捕获键击。

成员变量在创建对象时初始化(在任何父类的构造函数之后和当前类的构造函数体之前。当首次创建对象时,Swing不执行任何大小调整工作。因此,当您调用getWidth()getHeight() ,尚未设置任何值。