簡體   English   中英

Java中的JPanel會發生什么? 我究竟做錯了什么?

[英]What is happening with JPanel in java? What am I doing wrong?

我的JPanel有問題。 我告訴它在構造函數的末尾重新繪制(),然后獲得動畫(一個精靈在屏幕上移動),但是JPanel不會自行繪制,直到該精靈經過其動畫並到達其新點為止。屏幕。 我在下面粘貼了我的代碼。 我以前從未使用過JPanel用於自定義圖形。 我究竟做錯了什么?

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

class Battle extends JPanel implements KeyListener {

    AllyParty ap;
    boolean showMenu = false;
    BufferedImage image;
    EnemyParty ep;
    Graphics screen;
    Image allyPic[], enemyPic[];
    int enemyCount;
    int mtCount = 0;
    int turn[];
    MediaTracker mt;
    Random rand;

    public Battle(AllyParty allyparty) {

        /*Initial JPanel subclass setup*/
        setSize(800, 600);
        setBackground(Color.black);

        /*Create our ally party*/
        ap = new AllyParty();
        ap = allyparty;
        ap.setCallingObject(this);

        /*Create randomizer and random number variable*/
        long seed = System.currentTimeMillis();
        rand = new Random(seed);

        /*Use rand to select a number of enemies*/
        enemyCount = rand.nextInt(12) + 1;

        enemyCount = 12; //TEMP 
        ep = new EnemyParty(enemyCount);


        /*Create the individual enemies in ep and place them*/
        for (int i = 0; i < enemyCount; i++) {
            ep.enemy[i] = new Enemy(1);
        }

        ep.setCallingObject(this);

        /*Initialize images and set them to their starting values*/
        allyPic = new Image[4];
        enemyPic = new Image[enemyCount];

        /* for (int i = 0; i < 4; i++) 
        { 
        ap.ally[i].setCurrentImage(Ally.STAND) 
        allyPic[i] = ap.ally[i].getCurrentImage(); 
        } 

        for (int i = 0; i < enemyCount; i++) 
        { 
        enemyPic[i] = ep.enemy[i].getImage(); 
         */
        /*Set battle placement*/
        ap.setPos(0);
        ep.setPos(0);

        //Create the Buffered Image 
        image = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);

        //Set up the Media Tracker 
        mt = new MediaTracker(this);
        for (int i = 0; i < 4; i++) {
            mt.addImage(allyPic[i], mtCount++);
        }

        for (int i = 0; i < ep.getEnemyCount(); i++) {
            mt.addImage(enemyPic[i], mtCount++);
        }

        mt.addImage(image, mtCount++);

        try {
            mt.waitForAll();
        } catch (Exception e) {
        }

        /*Temporary Section*/
        findTurns();

        repaint();
        // ap.ally[0].advance(); 
        advance();
    }

    public void findTurns() {
        int total = ep.getEnemyCount() + 4; //Enemies + allies 

        int used[] = new int[total];
        turn = new int[total];

        int next = rand.nextInt(total);

        for (int j = 0; j < total; j++) {
            used[j] = -1;
        }

        for (int j = 0; j < total; j++) {
            for (int k = 0; k < j; k++) {
                if (used[k] == next) {
                    k = -1;
                    next = rand.nextInt(total);
                }
            }
            turn[j] = next;
            used[j] = next;
        }
    }

    public void advance() {
        while (ap.ally[0].getXPos() > 350) {
            ap.ally[0].moveLeft(20);
            ap.ally[0].setCurrentImage(Ally.WALK);
            repaint();
            try {
                Thread.sleep(200);
            } catch (Exception e) {
            }
            ap.ally[0].setCurrentImage(Ally.STAND);
            repaint();
            try {
                Thread.sleep(200);
            } catch (Exception e) {
            }
        }
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        screen = image.getGraphics();

        for (int i = 0; i < 4; i++) {
            allyPic[i] = ap.ally[i].getCurrentImage();
        }

        for (int i = 0; i < ep.getEnemyCount(); i++) {
            enemyPic[i] = ep.enemy[i].getCurrentImage();
        }

        for (int i = 0; i < 4; i++) {
            screen.drawImage(allyPic[i], ap.ally[i].getXPos(),
                ap.ally[i].getYPos(), this);
        }

        for (int i = 0; i < enemyCount; i++) {
            screen.drawImage(enemyPic[i], ep.enemy[i].getXPos(),
                ep.enemy[i].getYPos(), 100, 75, this);
        }

        g.drawImage(image, 0, 0, this);
    }

    public void keyPressed(KeyEvent k) {}
    public void keyReleased(KeyEvent k) {}
    public void keyTyped(KeyEvent k) {}
}
What am I doing wrong? 

1)使用KeyBindings代替KeyListener

2)切勿在EDT期間使用Thread.sleep(int) ,因為會導致Swing GUI凍結

3)對於動畫/延遲事件,請使用Swing Timer

4)您可以在JLabel中使用IconJPanel中顯示BufferedImage

很有可能您正在AWT線程中修改“模型”(子畫面的位置)。 重新繪制是在AWT-EventThread中調度的事件。 因此,只要您的操作在AWT線程內運行,就將阻止AWT重新繪制面板。

兩種選擇:

1)將“操作/模型”移到AWT線程外(在另一個線程中)

2)不時釋放AWT-Thread,允許執行重繪事件(對我來說這不是一個好選擇)

確保如果您在兩個線程之間共享變量,則使用volatilesynchronized (取決於您的工作方式,一個應該更適合您的需求)

據我所知,您的問題是您正在構造函數中調用advance()。 您的代碼可能看起來像這樣:

JFrame frame = new JFrame();
frame.add(new Battle());
frame.setVisible(true);

這是發生了什么:

  1. 創建一個新的JFrame
  2. 創建了新的戰斗
  3. 在Battle構造函數的末尾調用repaint()
  4. 然后調用advance()
  5. advance()本身多次調用重繪
  6. advance()返回
  7. 構造函數返回
  8. 戰斗已添加到框架
  9. 框架變得可見
  10. 戰斗畫

為了解決您的問題,您必須在構造函數中刪除對advance()的調用,並在顯示框架之后進行調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM