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

发布于 2024-09-18 11:16:06 字数 3974 浏览 5 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

活雷疯 2024-09-25 11:16:06

所有绘图都应在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文