JPanel更新它的高度需要多长时间?

时间:2010-09-05 07:59:17

标签: java swing jpanel

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;

public class dots extends JPanel implements KeyListener, ComponentListener{ //JPanel extended so that we can overwrite paintComponent and draw the dots, KeyListener so that we can capture keypresses
 Random rand = new Random(); 
 JFrame frame;
 boolean haveSize = false; //this is used to tell paintComponent whether or not we have the size of the drawable area
 int[] x = new int[18],y = new int[18]; //used to store x and y coordinates of the dots so that they don't change position every time paintComponent is called, which is unpredictable
 final int OVALDIAM = 40;

 public dots() {
  frame = new JFrame("Dots");
  frame.setSize(new Dimension(800,600)); //So that when we minimize, we don't get a little bar
  frame.setExtendedState(Frame.MAXIMIZED_BOTH); //Maximize the window
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Hiding the window is a dumb default close behavior. Oh well.
  frame.getContentPane().add(this); //put the JPanel in the JFrame
  frame.addComponentListener(this);
  addKeyListener(this); //The next three lines allow the JPanel to capture key presses and subsequently move the dots when a key is pressed
  setFocusable(true); 
  requestFocusInWindow();
  frame.setVisible(true);
  try { //for whatever reason, the JPanel (this) doesn't know it's height, which we need to accuratly place dots, immediately after calling setVisible, so we wait for a bit to let it figure things out
   Thread.sleep(50);
  }
  catch (Exception e) {}
  newPos();
  System.out.println("Press any button to rearrange the dots");
 }

 public void paintComponent(Graphics g) { 
  super.paintComponent(g); //draw background using the supers method
  if (haveSize) { //if we have the size of the window, then newPos has run and we can paint the dots
   for (int i = 0; i < 18; i++) { //loop to draw the dots
    g.setColor(i < 12 ? Color.YELLOW : Color.BLUE); //if we have drawn fewer than 12 dots, color them yellow, else, color them blue
    g.fillOval(x[i],y[i],OVALDIAM,OVALDIAM);
    //System.out.println((i < 12 ? "Yellow":"Blue") + " oval drawn at " + x[i] + "," + y[i]); //Debugging that gave location of dots (some where getting lost)
   }
  }
 }

 public void newPos() { //this method generates new and random locations for the dots
  for (int i = 0; i < 18; i++) {
   x[i] = rand.nextInt(getSize().getWidth() > OVALDIAM ? (int)getSize().getWidth() - OVALDIAM : (int)getSize().getWidth()); // we subtract OVALDIAM so that the entire dot fits in the screen. We also check to make sure that the area is >OVALDIAM
   y[i] = rand.nextInt(getSize().getHeight() > OVALDIAM ? (int)getSize().getHeight() - OVALDIAM : (int)getSize().getHeight());
  }
  if (!haveSize) { //if this method has run, then we can run paintComponent
   haveSize = true; //we have locations for dots so we can start drawing dots
   frame.repaint(); //ensure dots get painted
  }
 }

 public void componentResized(ComponentEvent e){
   newPos();
   frame.repaint();
 }

 public void keyPressed(KeyEvent e) { //when a button is pressed, move the dots
  newPos();
  frame.repaint();
 }

 //interface methods we don't need
 public void componentMoved(ComponentEvent e) {}
 public void componentShown(ComponentEvent e) {}
 public void componentHidden(ComponentEvent e) {}
 public void keyReleased(KeyEvent e){}
 public void keyTyped(KeyEvent e) {}

 public static void main(String[] args) {
  new dots();
 }
}

所以我有这个代码,它工作正常。但是,如果你注释掉

try { //for whatever reason, the JPanel (this) doesn't know it's height, which we need to accuratly place dots, immediately after calling setVisible, so we wait for a bit to let it figure things out
            Thread.sleep(50);
        }
        catch (Exception e) {}
你得到一个错误。如果按一个键可以正常工作,这会更新所有内容,但除此之外它很奇怪。有什么想法吗?

在一个不相关的说明中,这段代码将帮助我找到一份工作,所以如果你们中有任何人看错了,请随时说出来。

1 个答案:

答案 0 :(得分:1)

所有绘图都应该在AWT主题下执行,如herehere所示,你可能想让你的绘画代码在dots()方法下运行invokeLater()以便它管理在查询高度或宽度之前完成绘画。