我正在编写一个文本编辑器,主面板由3个JTextPane
组成,2个侧面显示行和常见语法错误的数量,1个位于主编辑的中间。整个内容都打包在JScrollPane
。
当用户跳过一行(按ENTER)时会出现自动滚动问题,附加的KeyListener
会在双方JTextPane
中添加一个新条目(该行的num和语法错误),
作为反应,文档底部的JScrollPane
自动滚动可能会显示插入双方JTextPane
s中的新文本。
我通过在JScrollBar
s中为每个新行(由用户添加)设置KeyListener
的位置来部分解决问题。例如,使用scrollRectToVisible,或者通过在JTextPane
s中选择一个文本的正确部分来更好。
但是,最终效果不是很大,对于每个新行,垂直滚动条会振荡,我们可以通过按ENTER键几秒钟轻松崩溃应用程序。我一直在寻找具有JScrollPane类的许多方法的解决方案并尝试AdjustmentListener
,但未成功。你能帮助我吗?
PS:抱歉我的英文。我是法国人,我们的论坛很糟糕。
答案 0 :(得分:0)
SSCCE很有灵感来源,因为这个很好用(运行时看不到我的问题)似乎我的方法确实有效,但在我的实际代码中并没有在正确的监听器中运行。
不管怎么说,还是要谢谢你!
有一个SSCCE,它是一个简单的JScrollPane,由一个用于编辑的中央JTextPane和一个用于行号的横向组成。 placeScroll()方法放置滚动条,以便当paneLigne尝试将其向下推时,主JTextPane中的插入符号位于中间(垂直)。
再见
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.BorderLayout;
import javax.swing.JScrollPane;
public class SSCCE extends JFrame {
private JTextPane paneLigne, main;
private String tempchain;
public SSCCE() {
this.setSize(500,500);
this.setTitle("S");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
paneLigne = new JTextPane();
paneLigne.setEditable(false);
tempchain = "";
for(int j=1; j<40; j++)
tempchain+=" " + j + " \n";
paneLigne.setText(tempchain);
main = new JTextPane();
main.addKeyListener(new KeyListener() {
private int lastnline=0;
public void keyPressed(KeyEvent arg0) {
if(arg0.getKeyCode()==10) {
String tecste=main.getText();
int n=nbLignes(tecste);
if(n>38) {
if(lastnline<n) {
paneLigne.setText(paneLigne.getText()+" " + (n+1) + " \n");
} else {
this.retablirLignes(tecste);
}
} else {
paneLigne.setText(tempchain);
}
lastnline=n;
this.placeScroll();
}
}
@Override
public void keyReleased(KeyEvent arg0) { }
@Override
public void keyTyped(KeyEvent arg0) { }
private int nbLignes(String str) {
int ret=1;
for(int n=0, cpt=0; (n=str.indexOf('\n', cpt))!=-1; cpt=n+1)
ret++;
return ret;
}
public void retablirLignes(String stret) {
int n=this.nbLignes(stret);
String retoure="";
if(n>=40) {
for(int j=1; j<n+2; j++)
retoure+=" " + j + " \n";
paneLigne.setText(retoure);
}
lastnline=n;
}
public void placeScroll() {
// TODO Auto-generated method stub
if(paneLigne!=null) {
int n=this.nbLignesBuen(main.getText().substring(0, main.getCaretPosition()));
if(n!=-1) {
paneLigne.select(paneLigne.getText().indexOf(""+n), n+1);
} else {
paneLigne.select(0,1);
}
}
}
private int nbLignesBuen(String str) { //return the index of the last 20th line
int ret=0;
for(int n, cpt=0; (n=str.indexOf('\n', cpt))!=-1; cpt=n+1)
ret++;
if(ret>20)
ret-=20;
else
ret=-1;
return ret;
}
});
JPanel contentpane=new JPanel(new BorderLayout());
contentpane.add(paneLigne, BorderLayout.WEST);
contentpane.add(main, BorderLayout.CENTER);
this.setContentPane(new JScrollPane(contentpane));
this.setVisible(true);
}
public static void main(String[] args) {
SSCCE fen = new SSCCE();
}
}