重置按钮不起作用

时间:2014-01-28 01:23:43

标签: java swing reset

如果有人能帮我解决我的代码,我会很高兴。我有一个项目涉及一个人工生命形式(一个臭虫)吃食物和避免障碍。到目前为止,我在地图上随机生成食物。当我点击重置按钮时,所有食物消失并且虫子返回到第一个方格并且不是随机的。谁能告诉我为什么?另外,我如何阻止虫子和食物有时被放在同一个面板上。任何帮助都会很棒,谢谢!     包Javaproject;

import java.lang.Math.*; 
import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.File; 
import java.util.Random; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.Clip; 
import javax.swing.BorderFactory; 
import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JSlider; 
import javax.swing.JSpinner; 
import javax.swing.JTextField; 
import javax.swing.JToolBar; 
import javax.swing.SpinnerNumberModel; 
import javax.swing.Timer; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 



@SuppressWarnings("serial") 
public class JumpinJackFlash extends JPanel implements ActionListener, ChangeListener { 
private JPanel gridPanel;  //the panel containing the 2D grid 
private JPanel cells[][]; //the cells of the 2D grid 

private JToolBar toolBar; 
private JButton jb_start, jb_stop, jb_reset; 

private JTextField jtf_info; 

private Timer timer; 
private int speed; //cycles per second 
private int cycleNum; 
private JSpinner jspin_speed; 

private final static String RELPATHICONS = "icons" + File.separator; //relative path to icons folder 
private final static String RELPATHSOUNDS = "sounds" + File.separator; //relative path to sounds folder 

private static Random ran = new Random(); 
private static final int hsize=10; 
private static final int vsize=10; 


//the moving item: 
private JLabel jack; 
private int jack_x, jack_y; 
private File boingSoundFile; 

private JLabel Food; 
private int food_x, food_y; 

private static JSlider slider() { 
    JSlider slider; 
    slider = new JSlider(JSlider.VERTICAL, 0, 20, 0); 
    slider.setMajorTickSpacing(5); 
    slider.setPaintTicks(true); 
    return slider; 
} 
/** 
 * The constructor 
 */


public JumpinJackFlash(){ 
    gridPanel = new JPanel(new GridLayout(hsize, vsize)); 
    cells = new JPanel[hsize][vsize]; 
    for(int i=0; i<hsize; i++){ 
        for(int j=0; j<vsize; j++){ 
            cells[i][j] = new JPanel(); 
            cells[i][j].setBackground(Color.white); 
            cells[i][j].setBorder(BorderFactory.createLineBorder(Color.black)); 
            gridPanel.add(cells[i][j]); 

        }    
    } 

    //{ 
    // cells[i][j] = Food 
    // } 


    jack = new JLabel(getImageIcon("download.gif")); 
    boingSoundFile = new File(RELPATHSOUNDS+File.separator+"boing.wav"); 
    //init position within the 2D grid 

    int rand1 = (int) (Math.random() * 9); 
    int rand2 = (int) (Math.random() * 9); 
    jack_x = rand1;  
    jack_y= rand2; 
    cells[jack_x][jack_y].add(jack); 


    for (int i=0; i<5; i++) 
    { 
        int rand3 = (int) (Math.random() * 9); 
        int rand4 = (int) (Math.random() * 9); 
        food_x = rand3;  
        food_y= rand4; 
        cells[food_x][food_y].add(new JLabel(getImageIcon("food.gif"))); 
    } 

    //The toolbar 
    toolBar = new JToolBar(); 
    jb_start = new JButton(getImageIcon("start.gif")); 
    jb_start.setToolTipText("start"); 
    jb_stop = new JButton(getImageIcon("stop.gif")); 
    jb_stop.setToolTipText("stop"); 
    jb_reset = new JButton(getImageIcon("back.gif")); 
    jb_reset.setToolTipText("reset"); 
    toolBar.add(jb_start); 
    toolBar.add(jb_stop); 
    toolBar.add(jb_reset); 

    //Some text for info 
    jtf_info = new JTextField("cycle "+"<"+cycleNum+">"); 
    jtf_info.setBackground(Color.LIGHT_GRAY); 

    //The speed 
    speed = 1; //init speed of the animation (1 cycle per second) 
    SpinnerNumberModel jsm = new SpinnerNumberModel(speed,1,50,1); 
    jspin_speed = new JSpinner(jsm); 
    JLabel jlb_speed = new JLabel("Speed", JLabel.CENTER); 
    JPanel speedPanel = new JPanel(new BorderLayout()); 
    speedPanel.add(jlb_speed, BorderLayout.NORTH); 
    speedPanel.add(jspin_speed, BorderLayout.CENTER); 
    speedPanel.add(new JLabel("(steps per second)", JLabel.CENTER), BorderLayout.SOUTH); 
    gridPanel.add(slider(), BorderLayout.EAST); 

    //A panel for the toolbar 
    JPanel topPanel = new JPanel(new BorderLayout()); 
    topPanel.add(toolBar, BorderLayout.WEST); 
    topPanel.add(speedPanel, BorderLayout.EAST); 

    //Set the layout of the main panel 
    this.setLayout(new BorderLayout()); 
    add(topPanel, BorderLayout.NORTH); 
    add(gridPanel, BorderLayout.CENTER); 
    add(jtf_info, BorderLayout.SOUTH); 

    //Init the timer and register 'this' as listener 
    timer = new Timer(1000/speed, this); //create a new Timer object and register 'this' as 
                                         //listener for the periodic Timer events 
    timer.setInitialDelay(500); //in msec 
    cycleNum = 0; 

    //Register 'this' listener for the events generated by the jbuttons  
    //and by the Timer object. 
    jb_start.addActionListener(this); 
    jb_stop.addActionListener(this); 
    jb_reset.addActionListener(this); 

    //Register 'this' listener for the events generated by the jspinner 
    jspin_speed.addChangeListener(this); 
} 

/** 
 * The call back method for the events generated by the jbuttons  
 * and for the periodic events generated by the timer. 
 */
public void actionPerformed(ActionEvent e){ 
    if(e.getSource() == timer){ 
        cycleNum++;           //next step (cycle) of the synchronous animation 
        gridContent_update(); //update the content of the grid 
        this.repaint();       //repaint the view 

    } else if(e.getSource() == jb_start) { 
        speed = ((SpinnerNumberModel)jspin_speed.getModel()).getNumber().intValue(); 
        timer.setDelay(1000/speed); 
        timer.start(); //start the animation by starting the timer 

    } else if(e.getSource() == jb_stop) { 
        timer.stop(); 

    } else if(e.getSource() == jb_reset) { 
        timer.stop(); 
        cycleNum = 0; 
        gridContent_reset(); 
        this.repaint(); 

    } else { 
        //System.out.println("##### unknown event source #####"); 
    } 
} 

/** 
 * The call back method for the events generated by the jspinner, 
 * which is used to change the animation speed. 
 */
public void stateChanged(ChangeEvent e) { 
    if(e.getSource() == jspin_speed) { 
        speed = ((SpinnerNumberModel)jspin_speed.getModel()).getNumber().intValue(); 
        timer.setDelay(1000/speed); 
    } 
} 

/** 
 * Set new random coordinates for the moving item.<br> 
 * It check if the passed new coordinates are valid,  
 * i.e. within the grid dimensions. 
 *   
 * @param coordX 
 * @param coordY 
 * @return true if new valid coordinates have been set. 
 */
private boolean moveJackTo(int coordX, int coordY){ 
    if((coordX>=0) && (coordX<hsize) && (coordY>=0) && (coordY<vsize)){ 
        if((coordX!=jack_x) || (coordY!=jack_y)){ //valid new coordinates 
            cells[jack_x][jack_y].removeAll(); //remove jack from start pos 
            jack_x = coordX; 
            jack_y = coordY; 
            cells[jack_x][jack_y].add(jack); //add jack to dest pos  

            return true; 

        } 
    } 
    return false; //the coordinates have not been changed 
} 

/** 
 * This method is used to change the content of the 2D grid, 
 * i.e. the position of the moving item jack. 
 */
private void gridContent_update(){ 
    boolean moved = false; 
    while(!moved){ //repeat until new valid coordinates have been set 
        int x = jack_x; 
        int y = jack_y; 






        Random rn = new Random(); 
        int answer = rn.nextInt(4) + 1; 
        switch(answer){ 
        case(1):  
        { 
        y++; break; 
        } 
        case(2):  
        { 
        y--; break; 
        } 
        case(3):  
        { 
        x++; break; 
        } 
        case(4):  
        { 
         x--; break; 
        } 

        } 

        moved = moveJackTo(x, y); 
    } 

    jtf_info.setText("cycle <"+cycleNum+">"); 

    this.validate(); //should be invoked when this container's subcomponents are modified  
} 

/** 
 * This method is used to reset the content of the 2D grid, 
 * i.e. the initial position of the moving item jack. 
 */
private void gridContent_reset(){ 
    for (int i = 0; i < hsize; i++) { 
        for (int j = 0; j < vsize; j++) { 
            cells[i][j].removeAll(); 
            cells[i][j].setBackground(Color.white); 
        } 
    } 

    //init position 
    jack_x=0; 
    jack_y=0; 
    cells[jack_x][jack_y].add(jack); 

    cycleNum = 0; 
    jtf_info.setText("cycle <"+cycleNum+">"); 

    this.validate(); //should be invoked when this container's subcomponents are modified  
} 


/** 
 * Return a ImageIcon with the given icon or generate an error message. 
 */
private static ImageIcon getImageIcon(String iconFilename) { 
    ImageIcon theIcon; 
    File theImage = new File(RELPATHICONS + iconFilename); 
    if (theImage.isFile()) { 
        theIcon = new ImageIcon(theImage.getAbsolutePath()); 

    } else { 
        // show an error message and quit 
        theIcon = null; 
        JOptionPane.showMessageDialog(null, "Error - file not found: "
                + iconFilename); 
        System.exit(-1); 
    } 
    return (theIcon); 
} 

/** 
 * Return a ImageIcon with the given icon or a default image 
 */
private static ImageIcon getImageIcon(String iconFilename, String std_iconFilename) { 
    ImageIcon theIcon; 
    File theImage = new File(RELPATHICONS + iconFilename); 
    if (theImage.isFile()) { 
        theIcon = new ImageIcon(theImage.getAbsolutePath()); 

    } else { 
        theImage = new File(RELPATHICONS + std_iconFilename); 
        theIcon = new ImageIcon(theImage.getAbsolutePath()); 
    } 
    return (theIcon); 
} 

/** 
 * play a sound 
 * @param theSoundFile 
 */
private static void playSound(File theSoundFile) { 
    try { 
        Clip clip = AudioSystem.getClip(); 
        AudioInputStream ais = AudioSystem.getAudioInputStream(theSoundFile); 
        clip.open(ais); 
        clip.loop(0); 
    } catch (Exception e) { 
        System.err.println(e); 
        e.printStackTrace(); 
    } 
} 

/** 
 * Create the GUI and show it. For thread safety, this method should be 
 * invoked by the event-dispatching thread. 
 */
private static void createAndShowGUI() { 
    // Create the container 


    JFrame wm_frame = new JFrame("Synchronous Animation"); 

    // Quit the application when this frame is closed: 
    wm_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    // Create and add the content panel 
    JumpinJackFlash wm_panel = new JumpinJackFlash(); 
    wm_frame.add(wm_panel);     // OR frame.setContentPane(panel); 

    // Display the window 
    wm_frame.pack(); // adapt the frame size to its content 
    wm_frame.setLocation(10, 10); // in pixels 
    wm_frame.setVisible(true); // Now the frame will appear on screen 
} 

public static void main (String args[]){ 
    // Schedule a job for the event-dispatching thread: 
    // creating and showing this application's GUI. 
    javax.swing.SwingUtilities.invokeLater(new Runnable() { 
        public void run() { 
            createAndShowGUI(); 
        } 
    }); 
} 

}

1 个答案:

答案 0 :(得分:3)

基本上,当点击“休息”按钮时,您应该restarting Timer重新开始。

} else if (e.getSource() == jb_reset) {
    timer.stop();
    cycleNum = 0;
    gridContent_reset();
    // Restart the timer...
    timer.start();
    this.repaint();
}

关于问题的后半部分,基本上,您需要检查JPanel cells[x][y]是否包含任何子项,并将x / y值随机化为不存在(或者您达到某种限制,以防止无限循环的可能性)

另一种方法可能是随机化一个列表(可能包含每个单元格的JPanel),当你想要添加食物时简单地弹出第一个元素,并在没有食物存在时将其添加回来(在该单元格内) )

您应该打破代码,以便至少将模型和视图分开。

模型将包含有关游戏状态的信息,视图将负责渲染它。这将有助于简化大部分逻辑,因为当您想要确定放置食物的位置时,您不应该关心屏幕上的内容。