在 Jtextpane (在Jscrollpane中)每当我们输入文本时,它将从上到下打印,
是否可以将滚动条保持在底部,并在添加文本时向上移动旧文本(启用滚动条)?
例如:如果用户位于第1行并输入" xyz"然后按ENTER键。应该启用滚动条,并且应该在第二行使用插入符号向上移动xyz。因此,如果用户向上滚动,他将能够看到" xyz"。
问题与我以前的问题类似。我想说清楚得到答案。
感谢。
修改
public class TextPane extends JFrame implements ActionListener, KeyListener{
public static TextPane instance;
private static JTextPane terminal = new JTextPane();
private static JScrollPane scroll = new JScrollPane();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
TextPane.getInstance().init();
}
});
}
private static TextPane getInstance() {
if(null == instance){
instance = new TextPane();
}
return instance;
}
private EnterAction enterAction;
private void init() {
terminal.setFont(new Font("Courier new", Font.PLAIN, 12));
terminal.setLayout(new BorderLayout());
terminal.setBackground(Color.black);
terminal.setForeground(Color.white);
terminal.addKeyListener(this);
terminal.setCaretColor(Color.green);
terminal.setDragEnabled(false);
enterAction = new EnterAction();
terminal.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter");
terminal.getActionMap().put("enter", enterAction);
DefaultCaret caret = (DefaultCaret) terminal.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
scroll.setViewportView(terminal);
add(scroll);
setTitle("Dummy");
setSize(500 , 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(true);
setVisible(true);
}
class EnterAction extends AbstractAction {
//I typed a single line (in first line) of text and pressed enter.
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent ae ) {
try {
Document doc = terminal.getDocument();
int car = terminal.getCaretPosition();
//Currently i tried adding newlines to get scroll bar in order to hide previously displayed contents.
for(int i=0 ; i< 35 ; i++){
doc.insertString(doc.getLength(), "\n", null);
}
terminal.setCaretPosition(car + 1); // To set the caret at second line.
JScrollBar sb = scroll.getVerticalScrollBar();
sb.setValue( sb.getMaximum());//to keep the scroll bar at bottom.(Any how above setCaretPositon() makes it not work).
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
@Override
public void actionPerformed(ActionEvent e) {}
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {}
@Override
public void keyReleased(KeyEvent e) {}
}
答案 0 :(得分:1)
我认为这就是你想要的。一些说明:
invokeLater
将代码添加到Event Dispatch Thread的末尾。这确保了对Document的所有更新都已完成,因此滚动条的最大值将是正确的。守则:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
public class NavigationFilterSuffix extends NavigationFilter
{
private int suffixLength;
private Document doc;
public NavigationFilterSuffix(int suffixLength, Document doc)
{
this.suffixLength = suffixLength;
System.out.println(suffixLength);
this.doc = doc;
}
public void setDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias)
{
int endOfDocument = doc.getLength() - suffixLength + 1;
fb.setDot(Math.min(dot, endOfDocument), bias);
}
public void moveDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias)
{
int endOfDocument = doc.getLength() - suffixLength + 1;
fb.moveDot(Math.min(dot, endOfDocument), bias);
}
public static void main(String args[]) throws Exception
{
final JTextArea terminal = new JTextArea(15, 30);
// add 14 new lines (one less than rows specified above
terminal.setText("\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
terminal.setFont(new Font("Courier new", Font.PLAIN, 12));
terminal.setBackground(Color.black);
terminal.setForeground(Color.white);
terminal.setCaretColor(Color.green);
terminal.setDragEnabled(false);
terminal.setCaretPosition(0);
final JScrollPane scrollPane = new JScrollPane( terminal );
Action enterAction = new EnterAction();
terminal.getInputMap().put( KeyStroke.getKeyStroke("ENTER"), "enter");
terminal.getActionMap().put("enter", enterAction);
terminal.setNavigationFilter(new NavigationFilterSuffix(terminal.getRows(), terminal.getDocument()));
JFrame frame = new JFrame("Navigation Filter Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(scrollPane);
frame.pack();
Dimension d = frame.getSize();
d.width += 20;
frame.setSize(d);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
static class EnterAction extends AbstractAction
{
public void actionPerformed(ActionEvent ae )
{
try
{
final JTextArea terminal = (JTextArea)ae.getSource();
Document doc = terminal.getDocument();
int car = terminal.getCaretPosition();
doc.insertString(car, "\n", null);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
JScrollPane scrollPane = (JScrollPane)SwingUtilities.getAncestorOfClass(JScrollPane.class, terminal);
JScrollBar sb = scrollPane.getVerticalScrollBar();
sb.setValue( sb.getMaximum());
}
});
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}
祝你好运。
答案 1 :(得分:0)
根据上述对话的示例代码。请检查这是否能解决您的目的。
public class ThingDoer extends JPanel {
public ThingDoer() {
JTextArea text = new JTextArea(1, 10);
text.setLineWrap(true);
text.setWrapStyleWord(true);
JScrollPane scrollPane = new JScrollPane(text,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
);
add(scrollPane);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.add(new ThingDoer());
frame.pack();
frame.setSize(200, 300);
frame.setVisible(true);
}
}