[英]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
很有可能您正在AWT線程中修改“模型”(子畫面的位置)。 重新繪制是在AWT-EventThread中調度的事件。 因此,只要您的操作在AWT線程內運行,就將阻止AWT重新繪制面板。
兩種選擇:
1)將“操作/模型”移到AWT線程外(在另一個線程中)
2)不時釋放AWT-Thread,允許執行重繪事件(對我來說這不是一個好選擇)
確保如果您在兩個線程之間共享變量,則使用volatile
或synchronized
(取決於您的工作方式,一個應該更適合您的需求)
據我所知,您的問題是您正在構造函數中調用advance()。 您的代碼可能看起來像這樣:
JFrame frame = new JFrame();
frame.add(new Battle());
frame.setVisible(true);
這是發生了什么:
為了解決您的問題,您必須在構造函數中刪除對advance()的調用,並在顯示框架之后進行調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.