2011-06-05 102 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

相關問題