我想知道我何时写作以及何时删除,但是,在延迟0.5秒之后,它会告诉我“你已经停止写入/删除”但是,它只显示该消息并且它在删除或写入之后半秒延迟。
我如何正确使用Thread.sleep(500);
?
我目前的源代码:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class TextChangedFrame extends JFrame {
JTextField textField = new JTextField("Put your text here");
JLabel label = new JLabel("You have written: ");
public TextChangedFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300, 100);
setLayout(new BorderLayout());
getContentPane().add(textField, BorderLayout.CENTER);
getContentPane().add(label, BorderLayout.SOUTH);
textField.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
label.setText("I'm writting: " + textField.getText());
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
label.setText("I stopped writing");
}
public void removeUpdate(DocumentEvent e) {
label.setText("I'm deleting");
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
label.setText("I stopped deleting");
}
public void changedUpdate(DocumentEvent e) {
}
});
}
public static void main(String[] args) {
TextChangedFrame frame = new TextChangedFrame();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
答案 0 :(得分:2)
这个问题相当差,而且不是很清楚,所以在问题解决之前我无法给出确切的答案。
目前您似乎正在使用Thread.sleep(500)
导致延迟500毫秒。在大多数程序中,这都可行。
Thread.sleep(int x)
暂停(或冻结,取决于你询问的人)当前操作x
毫秒(在你的情况下,500毫秒)。
在您正在使用的应用程序中,您正在使用它来暂停文本更改。由于它的位置,它目前冻结整个摇摆箱,并没有恢复。
如果您必须使用Thread.sleep(int x)
,那么我建议您将正在使用的文本保存为字符串,然后在更新字符串后更新TextChangedFrame
。这允许您暂停操作,而不会暂停TextChangedFrame
。
伪码:
String oldString = "old string";
String newString = "new string";
// setup your dialog/popup here, with oldString
Thread.sleep(500);
// modify the dialog/popup here, changing oldString to newString
这应该避免任何冻结问题。 (我认为,问题和评论,你的问题是)。
更好的解决方案是使用Swing Timers Hovercraft Full Of Eels 中提到的his comment
答案 1 :(得分:2)
再次,使用Swing Timer进行肮脏的工作。你所做的就是编辑或删除时,调用Timer重新启动以重新设置定时器并启动它。如果Timer正在运行,restart()方法将停止它。
public void insertUpdate(DocumentEvent e) {
label.setText(EDITING);
writeDeleteTimer.restart();
}
例如:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
@SuppressWarnings("serial")
public class TextChangedFrame extends JPanel {
public static final String STOPPED_EDITING = "No Longer Editing or Deleting";
private static final String EDITING = "Editing";
private static final String DELETING = "Deleting";
private static final int TIMER_DELAY = 500;
private static final int PREF_W = 400;
private static final int PREF_H = 100;
private JTextField textField = new JTextField("Put your text here");
private JLabel label = new JLabel("You have written: ");
private ActionListener timerListener = new TimerListener();
private Timer writeDeleteTimer = new Timer(TIMER_DELAY, timerListener);
public TextChangedFrame() {
setLayout(new BorderLayout());
add(textField, BorderLayout.CENTER);
add(label, BorderLayout.SOUTH);
textField.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
label.setText(EDITING);
writeDeleteTimer.restart();
}
public void removeUpdate(DocumentEvent e) {
label.setText(DELETING);
writeDeleteTimer.restart();
}
public void changedUpdate(DocumentEvent e) {
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent evt) {
label.setText(STOPPED_EDITING);
Timer timer = (Timer) evt.getSource();
timer.stop();
}
}
private static void createAndShowGui() {
TextChangedFrame mainPanel = new TextChangedFrame();
JFrame frame = new JFrame("TextChangedFrame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
答案已编辑:无需重新创建Timer对象。只需在其上调用restart()
,因为如果它正在运行,它将停止当前的计时器。