Java CardLayout在完成无关循环之前不会更改Panel

时间:2015-02-25 20:54:24

标签: java panel cardlayout

我创建了使用多个面板的应用程序,所以我选择了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;}

}

1 个答案:

答案 0 :(得分:1)

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

我强烈猜测方法singlePlayer()是在Event Dispatching线程中执行的。包含while方法的Thread.sleep(..)循环阻止更新GUI,冻结GUI(或将其绘制为黑色)。

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