java - JLabel 自行改变

标签 java swing jlabel

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

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();
            }
        });
    }

}

感谢您的帮助,我不擅长提问。

最佳答案

计时器 starts out repeating , 默认情况下。因此,您的计时器每秒都在计时,永远计时。

你应该调用setRepeats(false) :

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

关于java - JLabel 自行改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21311456/

相关文章:

java - 如果在提交表单时条件总是路由到 hasError 条件

java - 创建时如何将焦点设置在 JOptionPane 内的特定 JTextfield 上?

java - 更改后我应该重画GUI吗?

java - JLabel 不与字符串进行比较

java - 在不损失质量的情况下在 JPanel 或 JLabel 中调整图像大小和显示

java - Tomcat 7 java.lang.NoClassDefFoundError : javax/el/ELManager 错误

java - 添加 jar 文件后的 Android Studio preDexDebug

Java,如果可拖动对象接触其他对象

java - JPA CriteriaBuilder 方法 : keys and values. 如何使用它们?

java - 无法关闭 Windows 并打开其他窗口