2011-06-05 80 views
0

当你调用一个输入方法时,当你有一个while循环(或任何循环)时,你可能会知道,程序停止并等待输入。Java:在没有输入提示的情况下暂停程序

例如

while { 
     String input = in.readLine(); 
     int x = 55; //This will not execute until input has been given a value 
     System.out.println (x + x); 
     } 

现在我正在使用按钮进行输入。有什么办法可以使用JButton,JPanel,JFrame等来做同样的事情(在循环中停止程序)?

注意:如果需要,我也可以使用Runnable()接口。

更新: 我正在使用侦听器的按钮。这是确切的问题。

public void actionPerformed (ActionEvent x){ string = x.getActionCommand} 

public void someOtherMethod() 
{ 

while (true){ 
start(); 
if (string.equals ("exit") break; // This line will never execute because start() 
    //is always repeating itself. 
    } 
} 

编辑: 我找到了解决方案(终于来了!)

这是所有需要做的事情....

string = ""; 
while (true){ 
if (string.equals (""); 
start(); 
if (string.equals ("exit") break; // I guess I didn't explain the problem too well... 
    } 

感谢您对大家的帮助!

+1

您需要更好地了解GUI的工作方式。你可以让一个主程序无限循环。但是,这应该从GUI中分离出来。 GUI在其自己的线程(事件分派线程(EDT))中运行,并且您的主程序应该在其他线程中运行。当然,主线程和GUI线程有时必须进行通信,但这应该保持在最低限度。有一个标准的方式来处理Swing的线程,你应该阅读教程(我知道它很长很复杂)。 – toto2 2011-06-05 14:47:51

+0

@托托是正确的。你的解决方案不是一个很好的解决方案。要掌握手头的问题,您需要打破对程序性,线性驱动程序的依赖,并学习*事件驱动程序的范例。图形用户界面几乎完全由事件驱动。 – 2011-06-05 14:51:20

回答

2

我想你遇到的问题是如何改变一下按钮取决于已经输入到GUI中的内容。请记住,使用GUI,用户可以随时以任何顺序与任何启用的GUI组件进行交互。关键是检查按钮的ActionListener中GUI的状态,然后根据此GUI的状态更改此方法的行为。例如,如果你的GUI有三个JTextField的情况下,字段1,字段2,和sumField和一个JButton Add按钮:

private JTextField field1 = new JTextField(5); 
    private JTextField field2 = new JTextField(5); 
    private JTextField sumField = new JTextField(5); 
    private JButton addButton = new JButton("Add"); 

你想Add按钮在字段1和字段2加号一起放入sumField的结果,你“再显然不会想如果任何字段为空做任何添加,所以你在JButton的ActionListener的测试吧:

addButton.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     String text1 = field1.getText().trim(); 
     String text2 = field2.getText().trim(); 

     if (text1.isEmpty() || text2.isEmpty()) { 
      // data not entered... so return the method and do nothing 
      return; 
     } 

     // if we've reached this point, the user has entered in text and so we handle it 

这里的整个事情:

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

public class WaitForInput extends JPanel { 
    private JTextField field1 = new JTextField(5); 
    private JTextField field2 = new JTextField(5); 
    private JTextField sumField = new JTextField(5); 
    private JButton addButton = new JButton("Add"); 

    public WaitForInput() { 
     addButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      String text1 = field1.getText().trim(); 
      String text2 = field2.getText().trim(); 

      if (text1.isEmpty() || text2.isEmpty()) { 
       // data not entered... so return the method and do nothing 
       return; 
      } 

      try { 
       int number1 = Integer.parseInt(field1.getText()); 
       int number2 = Integer.parseInt(field2.getText()); 
       int sum = number1 + number2; 

       sumField.setText("" + sum); 
      } catch (NumberFormatException e1) { 
       // TODO: use JOptionPane to send error message 

       // clear the fields 
       field1.setText(""); 
       field2.setText(""); 
      } 
     } 
     }); 

     add(field1); 
     add(new JLabel("+")); 
     add(field2); 
     add(new JLabel("=")); 
     add(sumField); 
     add(addButton); 
    } 

    private static void createAndShowUI() { 
     JFrame frame = new JFrame("WaitForInput"); 
     frame.getContentPane().add(new WaitForInput()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowUI(); 
     } 
     }); 
    } 
} 

编辑1
否则,如果你绝对必须使用一个循环,那么是的,在一个Runnable中做,然后在后台线程中执行。请记住在循环内调用Thread.sleep(...),即使是短暂的,也不会占用CPU。例如

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.*; 

public class HaltingProblem extends JPanel { 
    private static final int PANEL_HEIGHT = 400; 
    private static final int PANEL_WIDTH = 600; 
    private static final long SLEEP_DELAY = 100; 
    private Color[] colors = {Color.red, Color.orange, Color.yellow, 
     Color.green, Color.blue, Color.cyan}; 
    private boolean halt = false; 
    private JButton haltButton = new JButton("Halt"); 
    private int colorIndex = 0; 

    public HaltingProblem() { 
     setBackground(colors[colorIndex]); 
     haltButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      halt = !halt; // toggle it! 
     } 
     }); 
     add(haltButton); 

     new Thread(new Runnable() { 
     public void run() { 
      while (true) { 
       keepDoingThis(); 
      } 
     } 
     }).start(); 
    } 

    private void keepDoingThis() { 
     try { 
     Thread.sleep(SLEEP_DELAY); 
     } catch (InterruptedException e) {} 

     if (halt) { 
     return; 
     } 
     colorIndex++; 
     colorIndex %= colors.length; 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      setBackground(colors[colorIndex]); 
     } 
     }); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(PANEL_WIDTH, PANEL_HEIGHT); 
    } 

    private static void createAndShowUI() { 
     JFrame frame = new JFrame("HaltingProblem"); 
     frame.getContentPane().add(new HaltingProblem()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowUI(); 
     } 
     }); 
    } 
} 
+0

哇,你真的去了所有在那里:) – khellang 2011-06-05 14:49:29

1

当您使用GUI时,编程范例有点不同。

通过在按钮上注册监听器,当发生什么事情时您会收到通知 - 如果没有任何事情发生,Swing事件循环(EDT)已经在做“无”。

虽然也许我误解了这个问题。

+0

是的。我正在使用监听器,问题在于,循环只是一直在四处走动,并且在监听器动作发生时它总是被覆盖。我会稍微更新OP文章。 – 2011-06-05 13:59:27

+0

@Jimmy:解决方案是不使用循环。相反,当按下按钮时,请检查JTextField中的文本以查看它是否包含所需的字符串。你需要改变你的思维方式。 – 2011-06-05 14:05:47

+0

@Hovercraft完整的鳗鱼,我希望我能改变我的思维方式,不幸的是我的程序必须有一个主循环来控制流量。我知道这很奇怪,但老师是老师。 – 2011-06-05 14:07:20

1

如果你有一个GUI,你通常不会有一个无限期执行的中央主循环。响应事件的典型方法是使用event listeners

mybutton.addListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { System.out.println("Clicked"); } 
    }); 
+0

这就是问题 - 我想要一个中央主循环来执行,而我有GUI:S我希望这里有人知道如何解决这个问题。 – 2011-06-05 14:03:54

+0

@Jimmy:GUI已经*是​​主循环。这听起来像你需要某种工作者线程;见例如http://download.oracle.com/javase/tutorial/uiswing/concurrency/。 – 2011-06-05 14:10:38

1

让您JFrame实施ActionListener并调用button.addActionListener(this)。然后actionPerformed(ActionEvent event)方法中的代码将执行单击按钮时:)

或者你可以让ActionListener匿名与

button.addActionListener(new ActionListener() { 
    void actionPerformed(ActionEvent event) { 
     // Insert code to execute when button is clicked 
    } 
} 
+1

不,不要让JFrame实现ActionListener,因为这会造成非常差的设计(将控件和GUI元素混合在一个类中),并且不能很好地扩展。是的,匿名监听器或单独的监听器类,1+。 – 2011-06-05 14:03:54

+0

这仍然不完全解决我的问题。当点击按钮时,我想要一个中央循环来控制我的程序流/字符串动作命令。 – 2011-06-05 14:05:29

+1

我不认为你知道流程如何在GUI应用程序中工作。在常规控制台应用程序中,代码以特定顺序执行,但在GUI应用程序中,代码通过从GUI引发事件来执行。看看一些GUI和并发教程... – khellang 2011-06-05 14:15:23

相关问题