Why can't I access my getWidth () and getHeight () functions?

I am writing a simple program to test the main GUI. The program prints a letter in the middle of the screen and allows the user to move it using the arrow keys. Everything works fine, but when I try to center the letter at the beginning of the program, it seems that the getWidth and getHeight do not return the correct numbers.

Here's a snippet containing my Panel class

 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); } } 

Why do my getWidth and getHeight return '0'?

Thanks for any help

+6
source share
3 answers

I can not say the reason, but:

A way to avoid this is to override the getPreferredSize() function and return the desired size.

+7
source

Swing components do not have width and height until they are rendered. This happens if you call pack() or setVisible(true) in the root container. Consider placing the xy int initialization code in the componentResized method of the ComponentListener component that is added to your JPanel.

eg.

 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); } } } 

You will also want to use key bindings rather than KeyListener to capture your strokes.

+9
source

Member elements are initialized when the object is created (after the constructors of any parent classes and before the constructor body of the current class). Swing does not do any dimensional work when the object is first created. Therefore, when you call getWidth() and getHeight() , the values ​​are not set yet.

+3
source

Source: https://habr.com/ru/post/902812/


All Articles