我写了一个小的swing程序来获取用户输入(一系列0/1字符,然后是“完成”)将字符串返回给主类 - 下面附带的代码。问题是它在正常模式下运行时会挂起,但是当断点放在“return new String(str)”行(在函数getData()中)并且之后单步执行时,它可以正常工作。我认为这是一个计时问题,并在while循环之前输入“Thread.sleep(400)”(参见注释行) - 现在它工作正常。
但这段代码看起来很愚蠢。是否有更好的方法来编写此代码 - 获取用户输入并将用户指定的字符串返回给调用类?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class DataEntryPanel extends JPanel implements ActionListener {
private JButton Button0, Button1, ButtonDone;
private JLabel DataEntered;
public char[] str = "________".toCharArray();
int posn = 0;
public boolean dataDone = false;
public DataEntryPanel() {
this.setLayout(new FlowLayout(FlowLayout.CENTER));
Button0 = new JButton("0"); Button0.addActionListener(this); this.add(Button0);
Button1 = new JButton("1"); Button1.addActionListener(this); this.add(Button1);
ButtonDone = new JButton("Done"); ButtonDone.addActionListener(this); this.add(ButtonDone);
DataEntered = new JLabel("xxxxxxxx"); this.add(DataEntered);
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if(source==Button0) DataEntered.setText(setData('0'));
else if(source==Button1) DataEntered.setText(setData('1'));
else if(source==ButtonDone) dataDone=true;
}
public String setData(char c) {
if(posn<8) str[posn++] = c;
return new String(str);
}
}
class DataEntryFrame extends JFrame {
public JPanel panel;
private void centerWindow (Window w) {
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension d = tk.getScreenSize();
setLocation((d.width-w.getWidth())/2, (d.height-w.getHeight())/2);
}
public DataEntryFrame() {
setTitle("Data Entry");
setSize(267, 200);
centerWindow(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new DataEntryPanel();
this.add(panel);
}
public String getData() {
DataEntryPanel p = (DataEntryPanel) panel;
System.out.printf("waiting for data......\n");
// try {
while(!p.dataDone)
// Thread.sleep(400)
; // looping on data completion
// } catch (InterruptedException e) { e.printStackTrace(); }
return new String(p.str);
}
}
public class FRead {
public FRead() {
JFrame frame = new DataEntryFrame();
frame.setVisible(true);
DataEntryFrame f = (DataEntryFrame) frame;
String s = f.getData();
System.out.printf("string obtained=%s\n", s);
System.exit(0);
}
public static void main(String[] args) throws Exception {
new FRead();
}
}
答案 0 :(得分:2)
你可能遇到了EDT问题并且在你的while循环中耗尽了你的CPU。
pack()
或setSize()
),然后只需拨打setLocationRelativeTo(null);
while(!true) ;
循环,这会耗尽你的CPU并阻止当前的线程。dataDone
变量应声明为volatile
,因为您正在“主”主题中读取它,但它已由EDT修改。以下是代码的略微修改版本,似乎效果更好:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GUI {
class DataEntryPanel extends JPanel implements ActionListener {
private JButton button0, button1, buttonDone;
private JLabel dataEntered;
public char[] str = "________".toCharArray();
int posn = 0;
public volatile boolean dataDone = false;
private String data;
public DataEntryPanel() {
this.setLayout(new FlowLayout(FlowLayout.CENTER));
button0 = new JButton("0");
button0.addActionListener(this);
this.add(button0);
button1 = new JButton("1");
button1.addActionListener(this);
this.add(button1);
buttonDone = new JButton("Done");
buttonDone.addActionListener(this);
this.add(buttonDone);
dataEntered = new JLabel("xxxxxxxx");
this.add(dataEntered);
}
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == button0) {
dataEntered.setText(setData('0'));
} else if (source == button1) {
dataEntered.setText(setData('1'));
} else if (source == buttonDone) {
JOptionPane.showMessageDialog(this, "Data entered is " + String.format("string obtained=%s\n", getData()));
System.exit(0);
}
}
public String getData() {
return data;
}
public String setData(char c) {
if (posn < 8) {
str[posn++] = c;
}
return data = new String(str);
}
}
protected void initUI() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Data Entry");
frame.setSize(267, 200);
frame.setLocationRelativeTo(null);
DataEntryPanel panel = new DataEntryPanel();
frame.add(panel);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new GUI().initUI();
}
});
}
}
答案 1 :(得分:1)
一种选择是使用模态对话框。打开模态对话框后,之后的代码只有在关闭后才会执行。关闭后,您可以从外部调用对话框类的getter方法,以获取输入的值。