【问题标题】:Wait for button press JButton等待按钮按下 JButton
【发布时间】:2013-08-02 02:50:06
【问题描述】:

我正在寻找一种让我的程序等到按下按钮以继续该功能的方法。在我的主要函数中,我正在调用一个函数,该函数使用 JPanel、按钮和标签显示我的基本 GUI。当然,它显示了 GUI 并结束了不允许我更改 GUI 的功能。

    public static Player player = new Player();
    public static Gui gui = new Gui();
    public static boolean inMain = true;
    public static boolean inBattle = false;

    public static void main(String[] args){
    showMainGui();  
    }

我认为我正在寻找的东西看起来像这样:

public static void main(String[] args){
    showMainGui();
    while(inBattle == false){
        // wait until inBattle changes
    }
}

while 循环将循环并等待,直到在 showMainGui 中创建的按钮将 inBattle 更改为 true。我怎么能做到这一点?这让我很困惑。我的目标是单击一个 JButton,按钮变为不同的按钮

我在 showMainGui() 上创建的按钮的动作监听器;

public class Hunt implements ActionListener{

    @Override
public void actionPerformed(ActionEvent e) {

    MainClass.inBattle = true;
}
}

这是我的 showMainGui() 方法

public static void showMainGui(){
    gui.panel.add(gui.healthLabel);
    gui.panel.add(gui.pbsLabel);
    gui.panel.add(gui.staminaLabel);
    gui.panel.add(gui.levelLabel);

    //Adding initial buttons
    gui.panel.add(gui.exploreButton);
    gui.panel.add(gui.huntButton);
    gui.panel.add(gui.newsLabel);
    gui.panel.add(gui.effectLabel);
    updateGui();

}

【问题讨论】:

  • 你能提供更多代码吗?您在 Battel 中更改的位置以及如何更改 + showMainGUI 方法
  • 抱歉,showMainGUI 没有给我们任何信息。或许 updateGUI 可以...
  • updateGui 所做的只是将标签文本设置为变量
  • 那么什么是调用 setVisible 方法?新的 Gui()?
  • 是的,setVisible 在 gui 实例中

标签: java swing jpanel actionlistener jlabel


【解决方案1】:

你可以通过让线程休眠来等待。

while(inBattle == false){
    try {
       Thread.sleep(200);
    } catch(InterruptedException e) {
    }
}
// perform operations when inBattle is true

也别忘了打inBattle volatile

【讨论】:

  • 我尝试过 sleep 方法,但似乎对我不起作用,但我会完全按照您的方式尝试。你能解释一下易失性吗?我还没学过
  • 您的 GUI 正在另一个线程上执行,主线程应该等待,否则它将完成执行并终止。这个 inbattle 变量是一个共享变量,您可以通过它进行同步
  • 谢谢,我现在明白了,但是我怎样才能使变量变为 volatile?
  • 只需将 volatile 添加到声明 public static volatile boolean inBattle = false;
  • 我已经这样做了,但似乎没有任何变化。如果我要从 main 方法添加按钮,而不是调用将项目添加到实例的函数,那会起作用吗?
【解决方案2】:

我会 +1 Peters answer,但我觉得这需要详细说明。

绝对不需要 while 循环或额外的线程。只需将侦听器添加到您的 UI 组件。这是一个非常简单的例子:

    JButton button = new JButton("This is a button!");

    //Add action listener to button
    button.addActionListener(new ActionListener() {

    public void actionPerformed(ActionEvent e)
    {
        //Perform function when button is pressed
        System.out.println("You clicked the button");
    }
 }); 

您添加了动作侦听器,同时仍保持 while 循环,为什么?移除 while 循环并使用监听器。

再次重复Peter,但RTFM。只是read the documentation,它提供了清晰的示例。没有充分的理由使用该循环。


您的应用程序没有崩溃,它完全按照您的要求执行:

public static void main(String[] args){
    showMainGui();
    while(inBattle == false){
        // wait until inBattle changes
    }
}

你是说,当 inBattle 为假时,什么也不做,但如果 inBattle 为真,什么也不做,然后结束 main 函数——如果没有什么可做的,点击按钮后你期望它做什么?

【讨论】:

  • 我已经有一个按钮,在我的 showMainGui() 函数中创建了一个动作监听器。当我使用我的按钮时,它会使应用程序崩溃
【解决方案3】:

为您的按钮添加监听器并更改监听器

http://docs.oracle.com/javase/tutorial/uiswing/events/index.html

【讨论】:

    【解决方案4】:

    阅读此答案时,我一直在寻找解决方案,但我意识到如果您尝试帮助更新您的 gui,这可能会对您有所帮助。

    我假设你正在使用 JPanels 和其他东西(我是),但你应该试试这个:

    在我的游戏中:

    MainWindow window = new MainWindow();
        WelcomePanel welcome = new WelcomePanel(window);
        window.add(welcome);
        window.setVisible(true);
    
        while (Data.isWelcomeConfigDone != true) {
            try {
                Thread.sleep(500);
            }
            catch (InterruptedException e) {}
    
        }
        window.validate();
        window.setVisible(false);
        window.remove(welcome);
    
        GamePanel game = new GamePanel(window, welcome);
    
        window.add(game);
        window.setVisible(true);
        game.setVisible(true);
    
        while (true) {}
    

    我的想法和你一样,只是循环,直到我的条件变为假。但是,我感觉这家伙没有更新,所以你需要添加这个:

    window.validate(); // or whatever it is. My window is a JFrame, 
                          but it should work in a JPanel
    

    我知道这真的很晚了,但是对于出现这个问题的人来说,这应该会有所帮助。

    validate()文档:

    公共无效验证() 验证此容器及其所有子组件。 validate 方法用于使容器重新布置其子组件。在容器显示后修改此容器的子组件(添加到容器中或从容器中删除,或更改布局相关信息)时,应调用它。

    如果此 Container 无效,则此方法调用 validateTree 方法并将此 Container 标记为有效。否则,不执行任何操作。

    覆盖: 在类组件中验证 也可以看看: add(java.awt.Component), Component.invalidate(), JComponent.revalidate(), validateTree()

    【讨论】:

      【解决方案5】:

      以上答案没有回答我的问题版本,所以我修改了另一个解决方案。当我搜索“等待按钮按下 jbutton”时,这是第一个答案。

      我的有效解决方案使用了等待通知的概念。我在按钮上附加了一个 ActionListener:

          public void actionPerformed(ActionEvent e) { 
                   buttonClicked = true;
                   synchronized (b) {
                       b.notify();
                       
                   } 
          } 
      

      (抱歉缩进,如果有人想编辑,请继续)单击按钮时会发送通知。然后我附加了一个名为 waitForEnter() 的方法:

      public static void waitForEnter() throws InterruptedException {
              synchronized(b) {
                  try {
                      
                      b.wait();
                  } catch (InterruptedException ex) {
                      System.out.println("Interrupted");
                  }
              }
              System.out.println("After button clicked");
          //... more code
          }
      

      当我调用这个方法时,它会暂停主线程的执行,直到单击名为“b”的按钮。这对我来说效果很好。

      【讨论】:

        猜你喜欢
        • 2013-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-03
        • 2017-04-03
        相关资源
        最近更新 更多