我创建了使用多个面板的应用程序,所以我选择了cardLayout。问题是,当执行以下代码时,在UserInterface方法SinglePlayer()中发生了一些奇怪的事情。我使用命令 frame.add(fieldPanel," card2"); 和 cardLayout.show(frame," card2"); 但是当代码执行时,我的整个窗口变黑,而不是显示fieldPanel。只有当while循环(位于这些行下面)完成时,才会显示fieldPanel。 可能是什么问题?
以下是代码:
UserInterface类:
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;}
}
答案 0 :(得分:1)
请阅读有关Swing中并发性的更多信息:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html
我强烈猜测方法singlePlayer()
是在Event Dispatching线程中执行的。包含while
方法的Thread.sleep(..)
循环阻止更新GUI,冻结GUI(或将其绘制为黑色)。
您必须确保在EDT中执行的所有方法都快速返回。