为什么我的Java应用程序在启动后随机冻结?

问题描述 投票:0回答:1

所以出于某种原因,我的应用程序在启动时随机冻结。在GamePanel类的run()方法中添加sleep函数确实消除了问题,但我不明白为什么。

我查找了类似问题的其他帖子,但它们似乎有不同的起源。

应用类

import javax.swing.*;
import java.awt.*;

public class Application {
    private Application() {
        //create a JFrame window
        JFrame frame = new JFrame("Moving Squares");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //add a JPanel
        GamePanel gamePanel = new GamePanel();
        frame.add(gamePanel);
        //pack the window around the content
        frame.pack();
        //center
        frame.setLocationRelativeTo(null);
        //set minimum size
        frame.setMinimumSize(new Dimension(40, 80));
        frame.setVisible(true);
    }

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

的GamePanel

import java.awt.*;
import java.util.ArrayList;
import javax.swing.*;

public class GamePanel extends JPanel implements Runnable{

    //set JPanel size
    private static final Dimension DESIRED_SIZE = new Dimension(600,600);
    @Override
    public Dimension getPreferredSize(){
        return DESIRED_SIZE;
    }

    //constructor
    GamePanel(){
        Thread t = new Thread(this);
        t.start();
    }

    private ArrayList <Rect> rect=new ArrayList<>();
    public void run(){
        for(int i=0; i<15; i++){
            rect.add(new Rect());
        }
        //load time
        //to avoid freezing on start
        try{Thread.sleep(250);}
        catch(InterruptedException e){}

        while(true){
            for(Rect rect:rect){
                rect.move(this);
            }
            repaint();
            try{Thread.sleep(30);}
            catch(InterruptedException e){/**/};
        }
    }

    public void paint(Graphics g){
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(Color.white);
        g2d.fillRect(0,0,getWidth(),getHeight());
        for(Rect rect:rect) {
            g2d.setColor(Color.black);
            g2d.fillRect(rect.getXcord()-1, rect.getYcord()-1, rect.getWidth()+2, rect.getHeight()+2);
            g2d.setColor(rect.getRGB());
            g2d.fillRect(rect.getXcord(), rect.getYcord(), rect.getWidth(), rect.getHeight());
        }
    }
}

矩形

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

public class Rect{
    //properties
    private int width=30, height=30;
    private int R, G, B;
    private Color rgb;
    //movement
    private int xCord, yCord;
    private int xVector, yVector;
    private int xSlope, ySlope;

    public Rect(){
        Random rand = new Random();
        //random color
        int R, G, B;
        R=rand.nextInt(256);
        G=rand.nextInt(256);
        B=rand.nextInt(256);
        rgb= new Color(R, G, B);

        //random spawn position
        xCord=rand.nextInt(600-width);
        yCord=rand.nextInt(600-height);

        //direction
        do{
            xVector=rand.nextInt(3) - 1;
            yVector=rand.nextInt(3) - 1;
        }while(xVector==0 || yVector==0);

        //slope
        do{
            xSlope=rand.nextInt(3);
            ySlope=rand.nextInt(3);
        }while(xSlope==0 || ySlope==0);
        xVector*=xSlope;
        yVector*=ySlope;
    }


    public void move(JPanel parent){
        int jpWidth=parent.getWidth();
        int jpHeight=parent.getHeight();

        //if stuck outside because of resize
        if ( (xCord>=(jpWidth-width+2)) || (yCord>+(jpHeight-height+2)) ){
            Random rand = new Random();
            xCord=rand.nextInt(jpWidth-width-2)+1;
            yCord=rand.nextInt(jpHeight-height-2)+1;
            return;
        }

        //bounce
        if((xCord>=jpWidth-width) || (xCord<=0)){
            bounceX();
        }
        if((yCord>=jpHeight-height) || (yCord<=0)) {
            bounceY();
        }
        //move
        xCord+=xVector;
        yCord+=yVector;
    }

    public void bounceX(){
        xVector*=-1;
    }

    public void bounceY(){
        yVector*=-1;
    }

    public Color getRGB() {
        return rgb;
    }

    public int getXcord() {
        return xCord;
    }

    public int getYcord() {
        return yCord;
    }

    public int getWidth(){
        return width;
    }

    public int getHeight(){
        return height;
    }
}
java swing awt
1个回答
0
投票

在框架可见之前,您不应尝试绘制/重新绘制内容。

您可以做的是删除GamePanel的构造函数的内容并将其放在一个单独的方法中,例如:

public void startThread() {

    Thread t = new Thread(this);
    t.start();
}

然后在框架可见后启动线程:

frame.setVisible(true);

gamePanel.startThread();

更好的是,摆脱面板内的线程,并在您的主要创建它:

frame.setVisible(true);

new Thread(gamePanel).start();
© www.soinside.com 2019 - 2024. All rights reserved.