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) {}
则会出现错误。如果你按下一个键,它会更新所有内容,那么效果很好,但否则就会很奇怪。有什么想法吗?
顺便说一句,这段代码将帮助我找到一份工作,所以如果你们中有人发现任何问题,请随时指出。
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();
}
}
So I have this code, and it works fine. However, if you comment out
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) {}
you get an error. Works fine if you press a key, which updates everything, but otherwise it is weird. Any ideas why?
On an unrelated note, this code is going to help get me a job, so if any of you see anything wrong, please feel free to speak up.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
所有绘图都应在 AWT 线程下执行,如下所示此处 和在这里您可能想要获取您的绘画dots() 方法下的代码在
invokeLater()
下运行,因此它将在查询高度或宽度之前完成绘制。All drawing should be executed under the AWT thread as shown here and here you might want to get your painting code under dots() method to run under
invokeLater()
so it will manage to finish painting before querying for height or width.