Печать с паузой, не работающей в Java
Я пытаюсь получить программу, написанную в java, для вывода текстового письма по букве с паузой между каждой буквой. Кодовое слово обертывает строку и печатает ее. Мой метод задержки "slow()" работает хорошо, когда задержка составляет половину секунды или секунду, но при более низких задержках она делает некоторые странные вещи.
Когда печать и задержка являются слишком короткими, программа зависает на этой строке для времени задержки количества печатаемых букв до того, как линия вернется, а затем выплевывает все сразу.
Также, когда для задержки установлено значение 250 миллисекунд, текст также выводится неверно.
В примере строка:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla vitae molestie leo, sed molestie turpis."
Ожидаемый результат:
Lorem ipsum dolor sit amet, consectetur adipiscing
Элит. Nulla vitae molestie leo, sed molestie turpis.
Но выход 250 равен:
Lrem ipsum dolrst aet, adetiscing conseteur
Элит. ulla vitae olestie lo sed oleste turis.
Здесь код:
public static void main(String[] args) {
String x = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla vitae molestie leo, sed molestie turpis.";
say(500,x); // Works Nicely, does one letter at a time with a 0.5s wait in between.
System.out.println();
say(250,x); // Has proper delay, but prints strange stuff
System.out.println();
say(100,x); // Prints Line by line with a wait of (letters*0.1s) wait in between.
}
public static void say(int speed, String words) {
int i = 0;
int ii = 0;
while (i < words.length()) {
slow(speed);
System.out.print("" + words.charAt(i));
if (ii >= 50 && words.charAt(i) == ' ') {
System.out.println(words.charAt(i));
ii = 0;
} else {
ii++;
}
i++;
}
System.out.println(" ");
}
public static void slow(int time) {
try {
Thread.sleep(time);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
Альтернативный метод slow()
с такими же ошибками:
public static void slow(int time) {
long startTime = System.currentTimeMillis();
while(System.currentTimeMillis() - startTime < time) {
}
}
Я не уверен, что это важно, но все это делается в NetBeans 7.4 x64 с JDK 1.7.
Я новичок в Java, но не новичок в программировании. Любая помощь будет оценена!
Основная проблема - это время, это то, что мне нужно для работы; Странная печать - это просто вопрос.
Ответы
Ответ 1
Это запах рыбный. Ваш код выглядит хорошо и отлично работает для меня, запустив его из командной строки. Я думаю, как сказал Джим Гаррисон, это связано с вашей средой. Вы пытались запустить свою программу из командной строки, чтобы оставить Netbeans из нее?
Следующее, что я подозреваю, это строка Thread.currentThread().interrupt();
в вашем блоке catch(InterruptedException ex)
. Попробуйте прокомментировать это (и ничего не делайте, за исключением, возможно, печати трассировки стека InterruptedException
(ex.printStackTrace()
).
Ответ 2
Идиоматическое решение с использованием Timer/TimerTask:
Идиоматические примечания:
Q23794090.java
import javax.annotation.Nonnull;
import java.text.BreakIterator;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicLong;
public class Q23794090
{
private static final Timer TIMER = new Timer();
private static AtomicLong DELAY = new AtomicLong(0L);
private static void say(final long delay, @Nonnull final String value, @Nonnull final BreakIterator bi)
{
bi.setText(value);
int start = bi.first();
int end = bi.next();
while (end != BreakIterator.DONE)
{
final String s = value.substring(start, end);
TIMER.schedule(new TimerTask()
{
@Override
public void run()
{
System.out.print(s);
}
}, DELAY.addAndGet(delay));
start = end;
end = bi.next();
}
TIMER.schedule(new TimerTask()
{
@Override
public void run()
{
System.out.println();
System.out.println("========================");
}
}, DELAY.addAndGet(0));
}
public static void main(final String[] args)
{
final String x = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla vitae molestie leo, sed molestie turpis.";
say(250, x, BreakIterator.getCharacterInstance());
say(500, x, BreakIterator.getWordInstance());
say(1000, x, BreakIterator.getSentenceInstance());
TIMER.schedule(new TimerTask()
{
@Override
public void run()
{
TIMER.cancel();
}
}, DELAY.addAndGet(1000));
try { Thread.currentThread().join(); }
catch (InterruptedException e) { throw new RuntimeException(e); }
}
}
Работает в Intellij Idea 13.x
В консоли, поэтому нет проблем с вызовом System.out.flush()
любой такой глупости.
Что нужно улучшить:
-
BreakIterator
factory принимают необязательный Locale
, так как нет Latin
, который я мог бы найти легко, я просто позволяю ему использовать значение по умолчанию. В моем случае это en_US
. Ваше возражение может отличаться.