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

后端 未结 3 1215
长情又很酷
长情又很酷 2020-12-03 23:11

I\'m writing a simple program to test out basic GUI. The program prints a letter in the middle of the screen and allows the user to move it with the arrow keys. Everything w

3条回答
  •  一个人的身影
    2020-12-03 23:36

    Swing components have no width or height until they've been rendered. This occurs if you call pack() or setVisible(true) on a root container. Consider placing your x y int initialization code in the componentResized method of a ComponentListener that is added to your JPanel.

    e.g.,

    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'll also want to use key bindings rather than a KeyListener to capture your key strokes.

提交回复
热议问题