2015-02-25 3 views
0

Я создал приложение, которое использует несколько панелей, поэтому я выбрал cardLayout. Дело в том, что при выполнении следующего кода в методе UserInterface SinglePlayer() происходит что-то странное. Я использую команды frame.add (fieldPanel, «card2»); и cardLayout.show (рамка, «карта2»);, но когда этот код будет выполнен, все мое окно станет черным, а не покажет fieldPanel. Только когда цикл while (который находится именно под этими строками) завершен, отображается поле FieldPanel. В чем может быть проблема?Java CardLayout не изменяет Panel до тех пор, пока не завершится незакрепленный цикл

Вот код:

пользовательского интерфейса класс:

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 

    } 
} 

}

Snake класс: пакета модель;

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

Пожалуйста, прочитайте больше о параллельности в Свинг: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

Я твердо полагаю, что метод singlePlayer() выполняется в случае Диспетчерская нити. Цикл while, содержащий метод Thread.sleep(..), обновляет GUI, который замораживает графический интерфейс (или чертит его).

Вы должны убедиться, что все методы, выполняемые в EDT, возвращаются быстро.

+0

Собственно, когда я прокомментирую Thread.sleep() часть. ничего не меняется. Проблема остается – xpg94

+0

Прочтите учебник. Основные правила: никогда не блокируйте EDT. Все вещи Swing и GUI должны работать в EDT. – Uli

+0

Я добавил еще один намек на цикл while в singePlayer(). Все методы EDT должны возвращаться как можно быстрее и никогда не должны блокироваться. – Uli

Смежные вопросы