JLabel改变了它自己

时间:2014-01-23 14:48:00

标签: java swing jlabel

我一直在研究应该是一个相对简单的游戏,Mormon Sim。目标是在挨家挨户时进行成功的对话。这很简单,只需单击一个按钮,它就会根据调用的按钮和方法更改JLabel的文本。例如,使用Knock按钮将激活方法knockResponse,它将计算是否有人会来到门口。根据计算结果,有人会回答您的门,否则您将被拒之门外。问题是,经过几次点击后,通常一旦玩家通过敲击检查,JLabel就会开始回复到其他文本,并在几个不同的东西之间来回,有时完全无视他们的挥动计时器。我真的不知道这里发生了什么,我真的找不到这种情况会发生的原因。整整一周的谷歌搜索没有产生类似的问题或解决方案。 TL; DR Java已经自我意识

import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.Timer;

//To do: ASCII art in JLabels
public class mainMenu implements ActionListener{

    static JButton start = new JButton("Start!"), knock = new JButton("Knock"), talk = new JButton("Talk"), stats = new JButton("Stats");
    static int level = 1, stamina = 100, knocking = 1, speech = 1, points = 0;
    static JFrame frame = new JFrame("Mormon Sim");
    static mainMenu game = new mainMenu();
    static JLabel text = new JLabel(), knockSkill, speechSkill, staminaBar;
    static JPanel DoorMenu = new JPanel();
    JTextField name = new JTextField("Enter your name here", 25);
    static String playerName;

    public JPanel createStartMenu(){//JPanel for the start menu. Replaced on start click
        JPanel startMenu = new JPanel();
        JLabel instructions = new JLabel("<html>Welcome to Mormon Adventure, the first text-based mormon sim. Your goal is to <br>hold as many successful door to door<br>conversations as possible. Every successful conversation earns you a<br>skill point and a level. Level 15 is a win!<br>A conversation requires stamina as it goes on, find Orange Crush to replenish your stamina<html>");

        startMenu.setLayout(null);
        startMenu.setLocation(0, 0);
        startMenu.setSize(500, 500);

        start.setLocation(200, 300);
        start.setSize(100, 50);
        start.addActionListener(this);
        startMenu.add(start);

        instructions.setLocation(100, 100);
        instructions.setSize(300, 200);
        startMenu.add(instructions);

        name.setSize(150, 25);
        name.setLocation(100, 50);
        name.addActionListener(this);
        startMenu.add(name);

        startMenu.setOpaque(true);
        return startMenu;
    }
    public JPanel createDoorMenu(){//used for knocking, speaking, and going to the stat page. The problem is here
        talk.setEnabled(false);
        String knockText = "<html>You walk up the driveway of the next house on your<br>list. As you approach the door, you adjust your<br>tie, and smooth your hair. Your mouth is dry, and<br>you could really go for a bottle of orange crush.<br>You decide you should get one after this house.<br>Time to knock, someone is clearly home.<html>";

        DoorMenu.setLayout(null);
        DoorMenu.setLocation(0, 0);
        DoorMenu.setSize(500, 500);

        text = new JLabel(knockText);
        text.setLocation(100, 150);
        text.setSize(300, 200);
        DoorMenu.add(text);

        knock.setLocation(100, 400);
        knock.setSize(100, 50);
        knock.addActionListener(this);
        DoorMenu.add(knock);

        talk.setLocation(200, 400);
        talk.setSize(100, 50);
        talk.addActionListener(this);
        DoorMenu.add(talk);

        stats.setLocation(300, 400);
        stats.setSize(100, 50);
        stats.addActionListener(this);
        DoorMenu.add(stats);

        knockSkill = new JLabel("Knocking: " +knocking+ "   Speech: " +speech+ "   Level: " +level+ "   Skill Points: " +points);
        knockSkill.setLocation(100, 25);
        knockSkill.setSize(500, 50);
        DoorMenu.add(knockSkill);


        DoorMenu.setOpaque(true);
        return DoorMenu;
    }
    public JPanel createStatMenu(){//still doesn't do anything
        JPanel statMenu = new JPanel();


        return statMenu;
    }
    public static void knockResponse(){//generates a response from a knock based on knock level (1 <= x <= 10). Random number (1 <= y <= 10) is generated, level determines how many are successful
        //max knock level will shatter the door. 50/50 chance of conversation or police. max speech + police will talk them into letting you go
        knock.setEnabled(false);
        Random rand = new Random();
        int n = rand.nextInt(10) + 1;

        if(n > knocking){//knock check loss
            text.setText("<html>All you hear is someone yelling to go away...<br>Oh well. You chipper up and go to<br>the next house on your list. That orange Crush<br>will have to wait!<html>");
            ActionListener taskPerformer = new ActionListener(){//delay the label reset
                public void actionPerformed(ActionEvent evt){
                    text.setText("<html>You walk up the driveway of the next house on your<br>list. As you approach the door, you adjust your<br>tie, and smooth your hair. Your mouth is dry, and<br>you could really go for a bottle of orange crush.<br>You decide you should get one after this house.<br>Time to knock, someone is clearly home.<html>");
                    knock.setEnabled(true);
                }
            };
            new Timer(1000, taskPerformer).start();

        }
        if(n <= knocking && knocking != 10){//successful knock check
            knock.setEnabled(false);
            stats.setEnabled(false);

            text.setText("<html>Someone's coming to the door!<br>You straighten your hair and adjust your tie.<html>");

            ActionListener taskPerformer = new ActionListener(){//delay the label reset
                public void actionPerformed(ActionEvent evt){
                    text.setText("<html>The door opens, and you introduce yourself;<br>\"Hi! my name is " +playerName+ ". Have you accepted my homeboy JC as your lord and savior?\"<html>");//I couldn't really think of anything to make him say other than that
                    talk.setEnabled(true);
                }
            };
            new Timer(1000, taskPerformer).start();

        }
        if(knocking == 10){//door breaks
            text.setText("<html>You managed to shatter the door thanks to<br>your orange crush powered knocking skeelz.<html>");
            n = rand.nextInt(1) + 1;
            if(n == 0){//response check. Both are empty for now
                text.setText("0");
            }else if(n == 1){
                text.setText("1");
            }
        }
    }
    public static void successCalc(){//calculate the success in talking to someone by 
        talk.setEnabled(false);
        Random rand = new Random();
        int n = rand.nextInt(10) + 1;

        if(n <= speech && speech != 10){
            level++;
            points++;
            text.setText("<html>After some time, your conversation is over.<br>That went well. Better than you thought.<br>As you leave, you feel a rumbling in your gut.<br>It soon becomes painful. You fall to<br>the ground, and a gleaming light comes from<br>your stomach, as a skill point bursts out.<br>You hear a faint \"dunananaaa...\"<html>");
            talk.setEnabled(false);
            knockSkill.setText("Knocking: " +knocking+ "   Speech: " +speech+ "   Level: " +level+ "   Skill Points: " +points);
        }else if(n > speech){
            talk.setEnabled(false);
            text.setText("<html>After a moment of you speaking, all they do<br>is start blaring death metal.<br>You decide it's time to leave!<html>");
        }else if(speech == 10){
            text.setText("<html>Your golden, heavenly voice convinces them<br>to convert immediately.<br>You run down to the nearest convenience store<br>and grab yourself an orange Crush. Bottled, of course.<html>");
        }
    }
    public void actionPerformed(ActionEvent e){
        if(e.getSource() == start){

            frame.getContentPane().removeAll();
            frame.setContentPane(createDoorMenu());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(500, 500);
            frame.setResizable(false);
            frame.setVisible(true);

        }else if(e.getSource() == knock){
            knock.setEnabled(false);
            knockResponse();
        }else if(e.getSource() == talk){
            talk.setEnabled(false);
            successCalc();
        }
        playerName = name.getText();
    }
    public static void createAndShowGUI(){
        JFrame.setDefaultLookAndFeelDecorated(false);

        frame.setContentPane(game.createStartMenu());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);
        frame.setResizable(false);
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                createAndShowGUI();
            }
        });
    }

}

感谢您的帮助,我很难提问。

1 个答案:

答案 0 :(得分:4)

默认情况下为Timer starts out repeating。所以,你的计时器每一秒都在燃烧,永远。

你应该致电setRepeats(false)

void doLater(ActionListener action, int delay) {
   Timer timer = new Timer(delay, action);
   timer.setRepeats(false);
   timer.start();
}