单击鼠标后如何在 JTextArea 中继续自动滚动?
How to continue autoscroll in JTextArea after mouse click?
我有一个非常有用的自动滚动 JTextArea/JScrollPane 可以在底部连续添加文本行并向上滚动。我希望能够双击一个词并将其复制到剪贴板以进一步处理该词。但我希望自动滚动继续从底部滚动。
但是,只要我在 JTextArea 中按下鼠标,滚动就会停止。新行仍然添加,但滚动冻结。然后垂直滚动条开始向上移动,显示文本正在添加到视图区域下方。我可以用滚动条手动向下滚动,但它只是手动的。自动滚动已被禁用。
我怀疑问题出在焦点上。不知何故,也许自动滚动失去了对手动鼠标事件的关注。我尝试了各种修复,但没有任何效果。
我正在使用非常有用的 Caret 更新策略来启用从底部滚动。
caret = (DefaultCaret) jTextArea1.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
这里是大大减少但功能齐全的 Java 代码说明了这个问题。
package demoswingworker;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.swing.SwingWorker;
import javax.swing.text.DefaultCaret;
public class ScrollTextArea extends javax.swing.JFrame {
String[] sentences;
Map sentenceMap = new TreeMap();
DefaultCaret caret;
public ScrollTextArea() {
initComponents();
caret = (DefaultCaret) jTextArea1.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
this.setLocation(0, 0);
this.setSize(140, 300);
this.setVisible(true);
for (int i = 0; i < 100; i++) {
sentenceMap.put(i, i + "-abcdef");
}
scroll();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setBackground(new java.awt.Color(255, 153, 0));
setFont(new java.awt.Font("Times New Roman", 1, 14)); // NOI18N
jTextArea1.setBackground(new java.awt.Color(255, 153, 0));
jTextArea1.setColumns(20);
jTextArea1.setFont(new java.awt.Font("Times New Roman", 1, 22)); // NOI18N
jTextArea1.setLineWrap(true);
jTextArea1.setRows(5);
jTextArea1.setWrapStyleWord(true);
jScrollPane1.setViewportView(jTextArea1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 974, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
pack();
}// </editor-fold>
public static void main(String args[]) {
new ScrollTextArea();
}
protected void scroll() {
SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
@Override
protected Void doInBackground() throws Exception {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
jTextArea1.append(sentenceMap.get(i).toString() + "\n");
publish(i);
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
}
@Override
protected void done() {
jTextArea1.append("Done");
}
};
worker.execute();
}
// Variables declaration - do not modify
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextArea jTextArea1;
// End of variables declaration
}
这种自动滚动机制依赖于光标始终位于文本区域内容的末尾。只要光标在末尾,您就会自动滚动。当光标移动到除末尾以外的任何地方时,自动滚动停止。
因此,要恢复自动滚动,您唯一需要做的就是将光标移动到最后。您可以寻找一种以编程方式执行此操作的方法,但在此之前,您可以在希望恢复自动滚动时点击 Ctrl+End
。
另外请注意,我在您的代码中发现了几个警告,这意味着您在编程时没有启用许多有用的警告,这往往是非常容易出错的业务。
我有一个非常有用的自动滚动 JTextArea/JScrollPane 可以在底部连续添加文本行并向上滚动。我希望能够双击一个词并将其复制到剪贴板以进一步处理该词。但我希望自动滚动继续从底部滚动。
但是,只要我在 JTextArea 中按下鼠标,滚动就会停止。新行仍然添加,但滚动冻结。然后垂直滚动条开始向上移动,显示文本正在添加到视图区域下方。我可以用滚动条手动向下滚动,但它只是手动的。自动滚动已被禁用。
我怀疑问题出在焦点上。不知何故,也许自动滚动失去了对手动鼠标事件的关注。我尝试了各种修复,但没有任何效果。
我正在使用非常有用的 Caret 更新策略来启用从底部滚动。
caret = (DefaultCaret) jTextArea1.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
这里是大大减少但功能齐全的 Java 代码说明了这个问题。
package demoswingworker;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.swing.SwingWorker;
import javax.swing.text.DefaultCaret;
public class ScrollTextArea extends javax.swing.JFrame {
String[] sentences;
Map sentenceMap = new TreeMap();
DefaultCaret caret;
public ScrollTextArea() {
initComponents();
caret = (DefaultCaret) jTextArea1.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
this.setLocation(0, 0);
this.setSize(140, 300);
this.setVisible(true);
for (int i = 0; i < 100; i++) {
sentenceMap.put(i, i + "-abcdef");
}
scroll();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setBackground(new java.awt.Color(255, 153, 0));
setFont(new java.awt.Font("Times New Roman", 1, 14)); // NOI18N
jTextArea1.setBackground(new java.awt.Color(255, 153, 0));
jTextArea1.setColumns(20);
jTextArea1.setFont(new java.awt.Font("Times New Roman", 1, 22)); // NOI18N
jTextArea1.setLineWrap(true);
jTextArea1.setRows(5);
jTextArea1.setWrapStyleWord(true);
jScrollPane1.setViewportView(jTextArea1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 974, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
pack();
}// </editor-fold>
public static void main(String args[]) {
new ScrollTextArea();
}
protected void scroll() {
SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
@Override
protected Void doInBackground() throws Exception {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
jTextArea1.append(sentenceMap.get(i).toString() + "\n");
publish(i);
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
}
@Override
protected void done() {
jTextArea1.append("Done");
}
};
worker.execute();
}
// Variables declaration - do not modify
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextArea jTextArea1;
// End of variables declaration
}
这种自动滚动机制依赖于光标始终位于文本区域内容的末尾。只要光标在末尾,您就会自动滚动。当光标移动到除末尾以外的任何地方时,自动滚动停止。
因此,要恢复自动滚动,您唯一需要做的就是将光标移动到最后。您可以寻找一种以编程方式执行此操作的方法,但在此之前,您可以在希望恢复自动滚动时点击 Ctrl+End
。
另外请注意,我在您的代码中发现了几个警告,这意味着您在编程时没有启用许多有用的警告,这往往是非常容易出错的业务。