Java 在JTextArea中使用定时器实现打字机效果?
我正在做一个文本冒险游戏,遇到了一个问题,我无法以我想要的方式显示一些文本。当输入一些单词时,玩家可以开始引入一个新房间。我希望这个介绍能有“打字机”的效果。此事件需要在我的程序ActionPerformed方法中发生。例如,当用户键入“Move”,然后单击enter键时,我希望结果文本一次打印一个字符 以下是我在ActionPerformed之外使用的当前方法,以实现此效果:Java 在JTextArea中使用定时器实现打字机效果?,java,swing,timer,Java,Swing,Timer,我正在做一个文本冒险游戏,遇到了一个问题,我无法以我想要的方式显示一些文本。当输入一些单词时,玩家可以开始引入一个新房间。我希望这个介绍能有“打字机”的效果。此事件需要在我的程序ActionPerformed方法中发生。例如,当用户键入“Move”,然后单击enter键时,我希望结果文本一次打印一个字符 以下是我在ActionPerformed之外使用的当前方法,以实现此效果: public void slowPrint(String message, long millisPerChar) {
public void slowPrint(String message, long millisPerChar)
{
//makes it so that the player cannot input while the text is being displayed
userinput.setEditable(false);
String o;
for (int i = 0; i < message.length(); i++)
{
//adds each letter one-by-one
o = "" + message.charAt(i);
output.append(o);
//moves the JTextArea to the bottom
output.setCaretPosition (output.getDocument ().getLength ());
//delay so that you can see each letter being added
try {
Thread.sleep(millisPerChar);;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace(); }
}
//after the text is displayed allow the user to input again
userinput.setEditable(true);
}
我希望使用类似于我的“slowPrint”方法的东西,而不是一直追加
希望这是有意义的,任何帮助都将不胜感激 a的两个基本值是
ActionListener
slowPrint
方法中创建计时器,则保留对它的引用非常重要,以便以后可以停止它。因此,您必须在以后添加ActionListener
。在ActionListener
中,您可以通过一个附加变量跟踪当前文本位置(忘记for循环)。然后,您只需手动检查是否已打印所有文本,并相应地停止计时器
如果希望延迟最初也发生,只需调用timer.setInitialDelay(delay)
修改了
slowPrint
方法的示例:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.Timer;
public class Foo {
private JTextField input;
private JTextArea output;
public static void main(String[] args) throws IOException {
EventQueue.invokeLater(() -> new Foo().createAndShowGUI());
}
public void createAndShowGUI() {
output = new JTextArea();
output.setEditable(false);
input = new JTextField();
input.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
slowPrint("This is a test answer.\n", 100);
}
});
JPanel contentPane = new JPanel(new BorderLayout(5, 5));
contentPane.add(input, BorderLayout.NORTH);
contentPane.add(output);
JFrame frame = new JFrame("Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(contentPane);
frame.setSize(800, 600);
frame.setVisible(true);
}
public void slowPrint(String message, int millisPerChar) {
input.setEditable(false);
input.setFocusable(false);
Timer timer = new Timer(millisPerChar, null);
timer.addActionListener(new ActionListener() {
int counter = 0;
@Override
public void actionPerformed(ActionEvent e) {
output.append(String.valueOf(message.charAt(counter++)));
output.setCaretPosition(output.getDocument().getLength());
if (counter >= message.length()) {
timer.stop();
input.setEditable(true);
input.setFocusable(true);
input.requestFocusInWindow();
}
}
});
timer.start();
}
}
private void controlOne(String s)
{
if(one.getHasLight() == true)
{
if(!one.getPushYes())
{
output.append(one.dealWithLight(s, output));
}
else output.append(one.commands(s));
}
else output.append(one.commands(s));
}
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.Timer;
public class Foo {
private JTextField input;
private JTextArea output;
public static void main(String[] args) throws IOException {
EventQueue.invokeLater(() -> new Foo().createAndShowGUI());
}
public void createAndShowGUI() {
output = new JTextArea();
output.setEditable(false);
input = new JTextField();
input.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
slowPrint("This is a test answer.\n", 100);
}
});
JPanel contentPane = new JPanel(new BorderLayout(5, 5));
contentPane.add(input, BorderLayout.NORTH);
contentPane.add(output);
JFrame frame = new JFrame("Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(contentPane);
frame.setSize(800, 600);
frame.setVisible(true);
}
public void slowPrint(String message, int millisPerChar) {
input.setEditable(false);
input.setFocusable(false);
Timer timer = new Timer(millisPerChar, null);
timer.addActionListener(new ActionListener() {
int counter = 0;
@Override
public void actionPerformed(ActionEvent e) {
output.append(String.valueOf(message.charAt(counter++)));
output.setCaretPosition(output.getDocument().getLength());
if (counter >= message.length()) {
timer.stop();
input.setEditable(true);
input.setFocusable(true);
input.requestFocusInWindow();
}
}
});
timer.start();
}
}