gpt4 book ai didi

java - AWTEvent 和 EventQueue

转载 作者:行者123 更新时间:2023-12-01 18:59:39 24 4
gpt4 key购买 nike

我有一个外部设备一次向我发送 1 个字符的数据。我正在将其写入 JTextPane 上的 StyledDocument。这些数据是在不是 AWT 线程的线程上发送给我的,因此我需要创建 AWTEvents 并将它们推送到 EventQueue,以便 AWT 处理写入,这样我就不会收到异常。

我现在有一个有趣的问题......

我的文本正在向后打印到文档。

这显然是因为我在收到字符时一次将其推送到事件队列 1。队列显然是最后入栈的,最先弹出的。我正在尝试找到一种方法,可以在添加新事件或类似事件之前触发事件,以便我可以按顺序触发事件。

http://www.kauss.org/Stephan/swing/index.html是我用来创建事件的示例。

private class RUMAddTextEvent extends AWTEvent {

public static final int EVENT_ID = AWTEvent.RESERVED_ID_MAX + 1;
private int index;
private String str;
private AttributeSet as;

public RUMAddTextEvent(Component target, int index, String str, AttributeSet as) {
super(target, EVENT_ID);
this.index = index;
this.str = str;
this.as = as;
}

public int getIndex() {
return index;
}

public String getStr() {
return str;
}

public AttributeSet getAs() {
return as;
}
}

private class RUMRemoveTextEvent extends AWTEvent {

public static final int EVENT_ID = AWTEvent.RESERVED_ID_MAX + 1;
int index;
int size;

RUMRemoveTextEvent(Component target, int index, int size) {
super(target, EVENT_ID);
this.index = index;
this.size = size;
}

public int getIndex() {
return index;
}

public int getSize() {
return size;
}
}

/**
* Prints a character at a time to the RUMComm window.
*
* @param c
*/
public void simpleOut(Character c) {
cursor.x++;
if (lines.isEmpty()) {
this.lines.add(c.toString());
} else {
this.lines.add(cursor.y, this.lines.get(cursor.y).concat(c.toString()));
this.lines.remove(cursor.y + 1);

}

try {
//doc.insertString(doc.getLength(), c.toString(), as);

eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
eventQueue.postEvent(new RUMAddTextEvent(this, doc.getLength(), c.toString(), as));
getCaret().setDot(doc.getLength());
} catch (Exception ex) {
//Exceptions.printStackTrace(ex);
}
}

/**
* Creates a new line
*/
public void newLine() {
cursor.y++;
cursor.x = 0;
this.lines.add("");

//doc.insertString(doc.getLength(), "\n", null);
eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
eventQueue.postEvent(new RUMAddTextEvent(this, doc.getLength(), "\n", null));
getCaret().setDot(doc.getLength());

}

/**
* Backspace implementation.
*
*/
public void deleteLast() {
int endPos = doc.getLength();
//doc.remove(endPos - 1, 1);
eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
eventQueue.postEvent(new RUMRemoveTextEvent(this, endPos - 1, 1));
cursor.x--;

}

@Override
protected void processEvent(AWTEvent awte) {
//super.processEvent(awte);
if (awte instanceof RUMAddTextEvent) {
RUMAddTextEvent ev = (RUMAddTextEvent) awte;
try {
doc.insertString(ev.getIndex(), ev.getStr(), ev.getAs());
} catch (BadLocationException ex) {
Exceptions.printStackTrace(ex);
}
} else if (awte instanceof RUMRemoveTextEvent) {
RUMRemoveTextEvent ev = (RUMRemoveTextEvent) awte;
try {
doc.remove(ev.getIndex(), ev.getSize());
} catch (BadLocationException ex) {
Exceptions.printStackTrace(ex);
}

} else {
super.processEvent(awte);
}
}

最佳答案

我只能鼓励那些尝试遵守 Swing 线程规则的人。然而,尽管您努力创建事件并将它们推送到 EventQueue 上,但您仍然可以通过调用文档长度和更改来访问后台 Thread 上的 Swing 组件。插入符位置。

扩展文本组件以在其上设置文本对我来说似乎有点过分,而且当然不是解决此问题的最佳方法。就我个人而言,我会让后台线程填充一个缓冲区,并偶尔将该缓冲区刷新到文本文档(例如,在每个新行,使用计时器每秒两次,每次达到 1000 个字符时, ...)。对于更新,我只需使用 SwingUtilities.invokeLater

一些示例代码来说明这一点,取 self 的一个旧项目。它不会编译,但它说明了我的观点。该类将 String 附加到应在 EDT 上访问的 ISwingLogger。请注意使用 javax.swing.Timer 对 EDT 进行定期更新。

import javax.swing.Timer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class SwingOutputStream extends ByteArrayOutputStream{
private final ISwingLogger fSwingLogger;

private Timer fTimer;
private final StringBuilder fBuffer = new StringBuilder( 1000 );

public SwingOutputStream( ISwingLogger aSwingLogger ) {
fSwingLogger = aSwingLogger;

fTimer = new Timer( 200, new ActionListener() {
public void actionPerformed( ActionEvent aActionEvent ) {
flushBuffer();
}
} );
fTimer.setRepeats( false );
}

@Override
public void flush() throws IOException {
synchronized( fBuffer ){
fBuffer.append( toString( "UTF-8") );
}
if ( fTimer.isRunning() ){
fTimer.restart();
} else {
fTimer.start();
}

super.flush();
reset();
}

private void flushBuffer(){
synchronized ( fBuffer ){
final String output = fBuffer.toString();
fSwingLogger.appendString( output );
fBuffer.setLength( 0 );
}
}
}

关于java - AWTEvent 和 EventQueue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12680413/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com