2011-08-04 144 views
3

我是Swing的新手,我創建了一個帶有按鈕和文本字段的簡單GUI類。在這個類中有一個方法,String createAndShowUI(),我希望它返回文本字段的文本。我創建了另一個調用此方法的主類,並期望返回文本字段的文本。然而,我的問題是,這種方法不會等待用戶輸入文本字段並單擊按鈕;它在GUI被調用後立即返回。我希望它等待按鈕點擊。Swing GUI不會等待用戶輸入

// TestSwing.java 
import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class TestSwing extends JPanel implements ActionListener 
{ 
JButton submit; 
JTextField t1; 
String msg = "No Msg"; 
public TestSwing() 
{ 
submit = new JButton("Submit"); 
t1 = new JTextField(10); 
submit.addActionListener(this); 
setLayout(new FlowLayout()); 
add(t1); 
add(submit); 

} 

public void actionPerformed(ActionEvent e) 
{ 
    if(e.getSource() == submit) 
    { 
     msg = t1.getText(); 

    } 

} 

public String createAndShowUI() 
{ 
JFrame f = new JFrame("Sample frame"); 
f.add(new TestSwing()); 
f.pack(); 
f.setVisible(true); 
return msg; 
} 

} 

//Main.java 
public class Main 
{ 
public static void main(String[] arg) 
{ 
System.out.println(new TestSwing().createAndShowUI()); 
} 

} 

回答

4

Swing是事件驅動的。無論你想要使用msg應被稱爲後果被調用的動作偵聽器。

或者您可以使用JOptionPane現成的解決方案之一,例如

String userInput = JOptionPane.showInputDialog("Please enter ..."); 
+0

偉大的思想想象一樣:1+ :) –

+0

它確定如果我使用JOptionPane,但仍然是問題是我怎樣才能得到textfiled的文本回到主類,我需要它 – bhuvan

+0

@ user87:讀在觀察者設計模式上,這就是你需要的。 –

6

你得到你的字符串msg的用戶有機會去改變它之前,原因是你正在以一種程序化的方式思考,這對Swing來說不起作用。事實上,你必須改變你的整個思維方式,以編寫像Swing這樣的事件驅動編程。所以msg不會在創建類後顯示,而只會在用戶啓動一個事件之後才顯示 - 在這裏按下一個按鈕,提示ActionListener調用其actionPerformed方法。例如(突出的變化與//!!評論):

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

// Significant changes noted with the //!! comment 
public class TestSwing extends JPanel implements ActionListener { 
    JButton submit; 
    JTextField t1; 
    String msg = "No Msg"; 

    public TestSwing() { 
     submit = new JButton("Submit"); 
     t1 = new JTextField(10); 
     submit.addActionListener(this); 
     setLayout(new FlowLayout()); 
     add(t1); 
     add(submit); 

    } 

    public void actionPerformed(ActionEvent e) { 
     if (e.getSource() == submit) { 
     msg = t1.getText(); 

     //!! Display msg only **after** the user has pressed enter. 
     System.out.println(msg); 
     } 

    } 

    public void createAndShowUI() { //!! Don't have method return anything 
     JFrame f = new JFrame("Sample frame"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //!! close GUI 
     f.add(new TestSwing()); 
     f.pack(); 
     f.setLocationRelativeTo(null); // center GUI 
     f.setVisible(true); 
     //!! return msg; // get rid of 
    } 

    public static void main(String[] arg) { 
     new TestSwing().createAndShowUI(); 
    } 

} 

編輯2
你提到你想獲得味精文本的主要方法,或某處比TestSwing其他類等。一種方法是使用觀察者設計模式,在其中允許其他類「觀察」TestSwing類 - 這是「可觀察的」。有幾種方法可以做到這一點,包括:

  • 給予TestSwing稱爲像addActionListener(ActionListener al)一個公共無效的方法,並在方法體中添加傳遞到提交按鈕的監聽器。在類之外的這種方式可以直接將ActionListener添加到該按鈕並響應其事件。
  • 給TestSwing的方式來接受ChangeListeners和按鈕是否在它的ActionListener被按下時通知他們,或
  • 給TestSwing給予它的PropertyChangeSupport變量和公共插件使用的PropertyChangeListeners和刪除的PropertyChangeListener方法的能力。這就像ChangeListener的想法一樣,但是由於PCL可以監聽多個狀態變化,所以它提供了更多的靈活性和強大功能,而這正是我更喜歡的。例如:

最新版本TestSwing的:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.beans.*; 

@SuppressWarnings("serial") 
public class TestSwing extends JPanel { 
    public static final String MESSAGE = "Message"; 
    private JButton submit; 
    private JTextField mainTextField; 
    private String message = "No Msg"; 

    private PropertyChangeSupport propSupport = new PropertyChangeSupport(this); 

    public TestSwing() { 
     submit = new JButton("Submit"); 
     mainTextField = new JTextField(10); 
     submit.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      submitActionPerformed(e); 
     } 
     }); 
     setLayout(new FlowLayout()); 
     add(mainTextField); 
     add(submit); 
    } 

    public void addPropertyChangeListener(PropertyChangeListener listener) { 
     propSupport.addPropertyChangeListener(listener); 
    } 

    public void removePropertyChangeListener(PropertyChangeListener listener) { 
     propSupport.removePropertyChangeListener(listener); 
    } 

    public void setMessage(String newValue) { 
     String oldValue = message; 
     this.message = newValue; 
     PropertyChangeEvent event = new PropertyChangeEvent(this, MESSAGE, oldValue, newValue); 
     propSupport.firePropertyChange(event); 
    } 

    private void submitActionPerformed(ActionEvent e) { 
     if (e.getSource() == submit) { 
     setMessage(mainTextField.getText()); 
     } 
    } 

    public static void createAndShowUI() { 
     TestSwing testSwing = new TestSwing(); 
     testSwing.addPropertyChangeListener(new PropertyChangeListener() { 
     public void propertyChange(PropertyChangeEvent evt) { 
      if (evt.getPropertyName().equals(TestSwing.MESSAGE)) { 
       System.out.println("message = " + evt.getNewValue()); 
      } 
     } 
     }); 

     JFrame f = new JFrame("Sample frame"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(testSwing); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] arg) { 
     createAndShowUI(); 
    } 

} 

請在Observer Design Pattern更多信息,請閱讀起來。

+0

我知道我很喜歡說「爲了更好的幫助,請儘快發佈SSCCE」,但是速度太快,我甚至沒有機會回覆!;) –

+0

//讓我修改我的主類代碼 公共類主要 { 公共靜態無效的主要(字符串[] ARG) { 的System.out.println(新TestSwing()createAndShowUI())。 System.out.println(「這是行不應該顯示,直到用戶輸入文本」); } } – bhuvan

+0

@bhuvan:???你想說什麼? –