为啥我无法访问面板的 getWidth() 和 getHeight() 函数?
Posted
技术标签:
【中文标题】为啥我无法访问面板的 getWidth() 和 getHeight() 函数?【英文标题】:Why can't I access my panel's getWidth() and getHeight() functions?为什么我无法访问面板的 getWidth() 和 getHeight() 函数? 【发布时间】:2012-01-10 07:09:04 【问题描述】:我正在编写一个简单的程序来测试基本的 GUI。该程序在屏幕中间打印一个字母,并允许用户使用箭头键移动它。一切正常,但是当我尝试在程序开始时将字母居中时,getWidth
和 getHeight
函数似乎没有返回正确的数字。
这是包含我的 Panel 类的 sn-p
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”?
感谢您的帮助
【问题讨论】:
【参考方案1】:Swing 组件在渲染之前没有宽度或高度。如果您在根容器上调用 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 来捕获您的击键。
【讨论】:
一些(承认吹毛求疵 :-) cmets:a)不需要监听器,覆盖 getPref 你可以从 getPref 的中间开始 b)如果你使用监听器,不要忘记重绘 c) 如果你使用一个只运行一次的监听器,让它自动删除而不是添加一个标志 d) +1 推荐 keyBindings【参考方案2】:我说不出原因,但是:
避免这种情况的一种方法是覆盖您的 getPreferredSize()
函数并返回您的首选大小。
【讨论】:
【参考方案3】:在创建对象时初始化成员变量(在任何父类的构造函数之后和当前类的构造函数主体之前。Swing 在第一次创建对象时不做任何大小调整工作。因此,当您调用 @987654322 @ 和 getHeight()
,尚未设置任何值。
【讨论】:
不正确。大小仅在渲染时发生,而不是在将东西放入布局管理器时发生。您需要阅读 Guy 和 Haase 的“Filthy Rich Clients”以了解更多信息。 @HovercratFullOfEels:我删掉了那部分。构造函数未设置这些值的观点仍然成立。由于 OP 在开始时只计算一次这些值,因此它们永远不会具有预期的值。以上是关于为啥我无法访问面板的 getWidth() 和 getHeight() 函数?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在 onResume() 中对 View 调用 getWidth() 返回 0?
查看 getHeight() 和 getWidth() 返回值太大