gpt4 book ai didi

Java CardLayout 在不相关的循环完成之前不会更改面板

转载 作者:行者123 更新时间:2023-12-01 11:51:59 28 4
gpt4 key购买 nike

我创建了使用多个面板的应用程序,所以我选择了cardLayout。问题是,当执行以下代码时,在 UserInterface 方法 SinglePlayer() 中会发生一些奇怪的事情。我使用命令 frame.add(fieldPanel, "card2");cardLayout.show(frame, "card2"); 但是当执行该代码时,我的整个窗口变为黑色而不是显示 fieldPanel。仅当 while 循环(位于这些行的正下方)完成时,才会显示 fieldPanel。可能是什么问题?

这是代码:

用户界面类:

    package view;

import java.awt.CardLayout;
import java.awt.Container;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import model.Field;
import model.Food;
import model.Snake;
import model.Snake.SnakePoint;
import net.miginfocom.swing.MigLayout;


public class UserInterface extends JFrame{
private JLabel singlePlayer,multiPlayer,quit;
private Container menu;
public JPanel introPanel,fieldPanel;
public CardLayout cardLayout;

private Field field;
private Snake snake1,snake2;
private Food food;

JPanel frame;

Thread mainThread;


public UserInterface(){

cardLayout=new CardLayout();
frame=new JPanel(cardLayout);

// Adjust window
introPanel=new JPanel(new MigLayout());
setSize(740, 515);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setResizable(true);
setTitle("Snake");
setVisible(true);

// Instantiate buttons
singlePlayer=new JLabel();
multiPlayer=new JLabel();
quit=new JLabel();
singlePlayer.setIcon(new ImageIcon("files/singleplayer.jpg"));
multiPlayer.setIcon(new ImageIcon("files/multiplayer.jpg"));
quit.setIcon(new ImageIcon("files/quit.jpg"));
quit.addMouseListener(new Mouse());
singlePlayer.addMouseListener(new Mouse());
multiPlayer.addMouseListener(new Mouse());

// Create menu panel
menu=new JPanel(new MigLayout());
menu.add(singlePlayer,"cell 0 0");
menu.add(multiPlayer,"cell 0 1");
menu.add(quit,"cell 0 2");

// Insert menu to the center
introPanel.add(menu,"push, align center");

// Create card layout
frame.add(introPanel,"card1");
add(frame);
}

public void singlePlayer(){
field=new Field(false);
snake1=new Snake();
food=new Food();



fieldPanel=field.getFieldPanel();
frame.add(fieldPanel, "card2");
cardLayout.show(frame, "card2");

revalidate();
repaint();

for(int i=0; i<field.FIELD_WIDTH;i++){
for(int j=0; j<field.FIELD_HEIGHT;j++){
this.addKeyListener(new KListener());

}
}

while(!snake1.isBodyHit()){
revalidate();
repaint();
redrawField();
redrawFood();
redrawSnake();

try {
Thread.sleep(200);
} catch (InterruptedException e) {
System.out.println("Error in UserInterface run method");
}

if(snake1.head.positionX==field.foodX && snake1.head.positionY==field.foodY){
snake1.increaseSnake();
field.resetFood();
}

snake1.moveSnake();
System.out.println(snake1.direction);
}
}



private class Mouse implements MouseListener {

@Override
public void mouseClicked(MouseEvent e) {
if(e.getSource()==quit){
System.exit(0);;
} else if(e.getSource()==singlePlayer){
singlePlayer();
} else if(e.getSource()==multiPlayer){

}
}

@Override
public void mousePressed(MouseEvent e) {


}

@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub

}

@Override
public void mouseEntered(MouseEvent e) {
if(e.getSource()==singlePlayer){
singlePlayer.setIcon(new ImageIcon("files/singlePlayer2.jpg"));
} else if(e.getSource()==multiPlayer){
multiPlayer.setIcon(new ImageIcon("files/multiPlayer2.jpg"));
} else if(e.getSource()==quit){
quit.setIcon(new ImageIcon("files/quit2.jpg"));
}

}

@Override
public void mouseExited(MouseEvent e) {
if(e.getSource()==singlePlayer){
singlePlayer.setIcon(new ImageIcon("files/singlePlayer.jpg"));
} else if(e.getSource()==multiPlayer){
multiPlayer.setIcon(new ImageIcon("files/multiPlayer.jpg"));
} else if(e.getSource()==quit){
quit.setIcon(new ImageIcon("files/quit.jpg"));
}

}

}


public void redrawSnake(){
SnakePoint temp=snake1.head;
while(temp!=null){
field.fieldLabels[temp.positionX][temp.positionY].setIcon(new ImageIcon("files/snake.jpg"));
temp=temp.next;
}
}

public void redrawField(){
for(int i=0;i<field.FIELD_WIDTH;i++)
for(int j=0;j<field.FIELD_HEIGHT;j++)
field.fieldLabels[i][j].setIcon(new ImageIcon("files/field_gray.jpg"));
}

public void redrawFood(){
for(int i=0;i<field.FIELD_WIDTH;i++)
for(int j=0;j<field.FIELD_HEIGHT;j++)
if( i== field.foodX && j==field.foodY)
field.fieldLabels[i][j].setIcon(new ImageIcon("files/food.jpg"));
}

private class KListener implements KeyListener
{

@Override
public void keyTyped(KeyEvent e) {

}

@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
snake1.direction='s';
} else if(e.getKeyCode()==KeyEvent.VK_LEFT){
snake1.direction='n';
} else if(e.getKeyCode()==KeyEvent.VK_DOWN){
snake1.direction='e';
} else if(e.getKeyCode()==KeyEvent.VK_UP){
snake1.direction='w';
}

}

@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub

}
}

}

蛇类: 封装模型;

public class Snake implements Runnable {
public SnakePoint head,tail;
private int length=0;
private static int numberOfSnakes=0;
private static final int initialLength=5;
public char direction;

public int foodX,foodY;
private int score;

@Override
public void run() {
numberOfSnakes++;

}

public SnakePoint getHead(){return head;}


public Snake(){

head=new SnakePoint();
int x=25,y=30;
head.positionX=x;
head.positionY=y;

SnakePoint temp1=new SnakePoint();
head.next=temp1;
temp1.positionX=24;
temp1.positionY=y;

SnakePoint temp2=new SnakePoint();
temp1.next=temp2;
temp2.positionX=23;
temp2.positionY=y;

temp1=temp2;
temp2=new SnakePoint();
temp1.next=temp2;
temp2.positionX=22;
temp2.positionY=y;
temp1=temp2;
temp2=new SnakePoint();
temp1.next=temp2;
temp2.positionX=21;
temp2.positionY=y;
temp2.next=null;

tail=temp2;
direction='e';
length=5;
}

public SnakePoint getPointAt(int position){
SnakePoint temp=head;
for(int i=0; ; i++)
{
if(position==i)
break;
temp=temp.next;
}
return temp;
}

public void moveSnake(){

if(!(direction=='w' && head.positionX==0) &&
!(direction=='e' && head.positionX==44) &&
!(direction=='n' && head.positionY==0) &&
!(direction=='s' && head.positionY==49)){
if(direction=='e'){
SnakePoint newHead=tail;
SnakePoint oneBeforeTail=getPointAt(length-2);
oneBeforeTail.next=null;
tail=oneBeforeTail;
newHead.positionX=head.positionX+1;
newHead.positionY=head.positionY;
newHead.next=head;
head=newHead;
} else if(direction=='w'){
SnakePoint newHead=tail;
SnakePoint oneBeforeTail=getPointAt(length-2);
oneBeforeTail.next=null;
tail=oneBeforeTail;
newHead.positionX=head.positionX-1;
newHead.positionY=head.positionY;
newHead.next=head;
head=newHead;

} else if(direction=='s'){
SnakePoint newHead=tail;
SnakePoint oneBeforeTail=getPointAt(length-2);
oneBeforeTail.next=null;
tail=oneBeforeTail;
newHead.positionX=head.positionX;
newHead.positionY=head.positionY+1;
newHead.next=head;
head=newHead;
} else if(direction=='n'){
SnakePoint newHead=tail;
SnakePoint oneBeforeTail=getPointAt(length-2);
oneBeforeTail.next=null;
tail=oneBeforeTail;
newHead.positionX=head.positionX;
newHead.positionY=head.positionY-1;
newHead.next=head;
head=newHead;
}
} else if(direction=='w' && head.positionX==0){
SnakePoint newHead=tail;
SnakePoint oneBeforeTail=getPointAt(length-2);
oneBeforeTail.next=null;
tail=oneBeforeTail;
newHead.positionX=44;
newHead.positionY=head.positionY;
newHead.next=head;
head=newHead;
} else if(direction=='e' && head.positionX==44){
SnakePoint newHead=tail;
SnakePoint oneBeforeTail=getPointAt(length-2);
oneBeforeTail.next=null;
tail=oneBeforeTail;
newHead.positionX=0;
newHead.positionY=head.positionY;
newHead.next=head;
head=newHead;
} else if(direction=='n' && head.positionY==0){
SnakePoint newHead=tail;
SnakePoint oneBeforeTail=getPointAt(length-2);
oneBeforeTail.next=null;
tail=oneBeforeTail;
newHead.positionX=head.positionX;
newHead.positionY=49;
newHead.next=head;
head=newHead;
} else if(direction=='s' && head.positionY==49){
SnakePoint newHead=tail;
SnakePoint oneBeforeTail=getPointAt(length-2);
oneBeforeTail.next=null;
tail=oneBeforeTail;
newHead.positionX=head.positionX;
newHead.positionY=0;
newHead.next=head;
head=newHead;
}
}

public boolean isBodyHit(){
SnakePoint temp=head.next;
while(temp != null){
if(head.positionX==temp.positionX && head.positionY==temp.positionY){
System.out.println("here");
return true;
}

temp=temp.next;
}
return false;
}

public void increaseSnake(){
length++;
SnakePoint newPoint=new SnakePoint();
if(!(direction=='w' && head.positionX==0) &&
!(direction=='e' && head.positionX==44) &&
!(direction=='n' && head.positionY==0) &&
!(direction=='s' && head.positionY==49)){
if(direction=='w'){
newPoint.positionX=head.positionX+1;
newPoint.positionY=head.positionY;
newPoint.next=head;
head=newPoint;
} else if(direction=='e'){
newPoint.positionX=head.positionX-1;
newPoint.positionY=head.positionY;
newPoint.next=head;
head=newPoint;
} else if(direction=='s'){
newPoint.positionX=head.positionX;
newPoint.positionY=head.positionY+1;
newPoint.next=head;
head=newPoint;
}else if(direction=='n'){
newPoint.positionX=head.positionX;
newPoint.positionY=head.positionY-1;
newPoint.next=head;
head=newPoint;
}
} else if(direction=='w' && head.positionX==0){
newPoint.positionX=44;
newPoint.positionY=head.positionY;
newPoint.next=head;
head=newPoint;
} else if(direction=='e' && head.positionX==44){
newPoint.positionX=0;
newPoint.positionY=head.positionY;
newPoint.next=head;
head=newPoint;
} else if(direction=='n' && head.positionY==0){
newPoint.positionX=head.positionX;
newPoint.positionY=49;
newPoint.next=head;
head=newPoint;
} else if(direction=='s' && head.positionY==49){
newPoint.positionX=head.positionX;
newPoint.positionY=0;
newPoint.next=head;
head=newPoint;
}
}

public int getLength(){ return length;}

public class SnakePoint{
public int positionX,positionY;
public SnakePoint next;

public SnakePoint(){
positionX=0;
positionY=0;
next=null;
}

public void addPoint(SnakePoint parent){

}
}

}

字段类别: 封装模型;

import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import net.miginfocom.swing.MigLayout;

public class Field extends JFrame {

private JPanel myFieldPanel;
private JPanel leftPanel;
private JPanel centralPanel;
private JPanel rightPanel;
private boolean isMultiPlayer;

private JLabel leftScore,rightScore;
private int score;


public int foodX,foodY;
public JLabel [][] fieldLabels;
public final int FIELD_WIDTH=45,FIELD_HEIGHT=50;
private static final long serialVersionUID = 1L;

public JPanel getFieldPanel(){return myFieldPanel;}

public void resetFood(){
// formula: new Random().nextInt(max - min + 1) + min;
foodX=new Random().nextInt(45 - 0 + 1) + 0;
foodY=new Random().nextInt(49 - 0 + 1) + 0;
}


public Field(boolean type){
myFieldPanel=new JPanel();
this.isMultiPlayer=type;

// Adjust playground and score tables
leftPanel=new JPanel(new MigLayout());
centralPanel=new JPanel(new MigLayout("gap 0, wrap 50"));
centralPanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.black));
rightPanel=new JPanel(new MigLayout());

// Set leftPanel
score=0;
leftScore=new JLabel("Player 1 score:\n"+score);
leftPanel.add(leftScore, "dock north");

// Adjust field and central panel
fieldLabels=new JLabel[FIELD_WIDTH][FIELD_HEIGHT];
for(int i=0;i<FIELD_WIDTH;i++){
for(int j=0;j<FIELD_HEIGHT;j++){
// Create each label
fieldLabels[i][j]=new JLabel();

// Paint each label
fieldLabels[i][j].setIcon(new ImageIcon("files/field_gray.jpg"));

// Add each label into layout
centralPanel.add(fieldLabels[i][j]);

}
}

// Adjust rightPanel
rightPanel.add(new JLabel("Player 2 score: "),"dock north");

// Final preparations
myFieldPanel.setLayout(new MigLayout());
myFieldPanel.add(leftPanel, "cell 0 0");
myFieldPanel.add(centralPanel, "cell 1 0");
myFieldPanel.add(rightPanel, "cell 2 0");
resetFood();
}

public boolean IsMultiPlayer(){ return isMultiPlayer;}

}

最佳答案

请阅读有关 Swing 并发性的更多信息:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

我强烈猜测 singlePlayer() 方法是在事件调度线程中执行的。包含 Thread.sleep(..) 方法的 while 循环会阻止更新 GUI,从而卡住 GUI(或将其绘制为黑色)。

您必须确保 EDT 中执行的所有方法都能快速返回。

关于Java CardLayout 在不相关的循环完成之前不会更改面板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28729365/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com