2010-09-05 52 views
1
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(); 
} 
} 

所以我有这个代码,它工作正常。但是,如果你评论出JPanel需要多长时间来更新它的高度?

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

所有绘制应该在AWT线程下,如图here执行,here你可能会想下点你的绘图代码()方法来invokeLater()下运行,因此将管理查询高度或宽度之前完成绘画。

+0

即使使用AWT的全部组件(这在某种意义上被认为是线程安全的,只是有成千上万的线程错误),这将是一个问题。该框架将自己放在不同的线程(美国东部时间),所以有一场比赛。 – 2010-09-05 12:42:13

+0

那么,我在操作中忽略的那个更奇怪的部分就是你可以获得JPanel的宽度。这只是仍然设置为0的高度。这使我认为它仍然在计算任务栏和其他所有事物的高度。 – 2010-09-05 17:58:20