这几天在搞一个文本编辑器,也渐渐摸到了些头绪。
之前,我总想着要获得文本区当前行和列位置,其实是进了个误区。因为正确来说不是文本区当前行和列位置,而是光标在文本区内文本的行列位置。所以不是要对文本区操作以获得行位置,而是要对文本文档操作来获得。
列(column)当然容易解决,其实就是用当前光标位置到"/n"符号后面(.../n|...)的距离+1。因为行列是从0开始算的,日常是从1开始算的,所以+1。而lastIndexOf("/n")是找"/n"的前一位置的(...|/n...),
int pos = textArea.getCaretPosition(); // 获得光标相对0行0列的位置
col = pos - textArea.getText().substring(0, pos).lastIndexOf("/n");
就能获得光标列位置col。
行(row),前面说了,其实是要找到文本文档的行位置。
int pos = textArea.getCaretPosition(); // 获得光标相对0行0列的位置
row = textArea.getLineOfOffset(pos) + 1; // 返回行是从0算起的,所以+1
就可以得到光标的行位置row。
//-----------------------------------------------------------------------------------------
// 下面是一个简单的例子:
//-----------------------------------------------------------------------------------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CurrentRowAndColDemo extends JFrame {
private JPanel panel = null;
private JTextArea textArea = null;
private JLabel theLabelShowRowAndColumn = null;
private JScrollPane scrollPane = null;
/**
* This is the default constructor
*/
public CurrentRowAndColDemo() {
super();
initialize();
}
/**
* This method initializes this
*
* @return void
*/
private void initialize() {
this.setTitle("获得光标在文本区中的行列位置演示");
this.add(getJPanel(), BorderLayout.CENTER);
this.pack();
this.setVisible(true);
}
/**
* This method initializes panel
*
* @return javax.swing.JPanel
*/
private JPanel getJPanel() {
if (panel == null) {
panel = new JPanel(new BorderLayout());
panel.add(getScrollPane(), BorderLayout.CENTER);
panel.add(getJLabel(), BorderLayout.SOUTH);
}
return panel;
}
/**
* This method initializes textArea
*
* @return javax.swing.JTextArea
*/
private JTextArea getJTextArea() {
if (textArea == null) {
textArea = new JTextArea();
textArea.addMouseListener(new TextMouseListener());
textArea.addKeyListener(new TextKeyListener());
}
return textArea;
}
/**
* This method initializes scrollPane
*
* @return javax.swing.JScrollPane
*/
private JScrollPane getScrollPane() {
if (scrollPane == null) {
scrollPane = new JScrollPane();
scrollPane.setPreferredSize(new Dimension(320, 180));
scrollPane.setViewportView(getJTextArea());
}
return scrollPane;
}
/**
* This method initializes theLabelShowRowAndColumn
*
* @return javax.swing.JTextArea
*/
private JLabel getJLabel() {
if (theLabelShowRowAndColumn == null) {
theLabelShowRowAndColumn = new JLabel();
theLabelShowRowAndColumn.setText("行:1 列:1");
theLabelShowRowAndColumn.setBorder( BorderFactory.createEmptyBorder(0, 16, 0, 0) );
}
return theLabelShowRowAndColumn;
}
// 文本区的鼠标事件的适配器
class TextMouseListener extends MouseAdapter {
// 按下鼠标
public void mousePressed(MouseEvent e) {
// 敲击左键
if (e.getModifiers() == MouseEvent.BUTTON1_MASK) {
getCurrenRowAndCol(); // 获得当前的行和列位置
}
}
// 松开鼠标
public void mouseReleased(MouseEvent e) {
// 敲击左键
if (e.getModifiers() == MouseEvent.BUTTON1_MASK) {
getCurrenRowAndCol(); // 获得当前的行和列位置
}
}
}
// 文本区的键盘事件的适配器
class TextKeyListener extends KeyAdapter {
// 按下某键
public void keyPressed(KeyEvent e) {
getCurrenRowAndCol(); // 获得当前的行和列位置
}
// 释放某键
public void keyReleased(KeyEvent e) {
getCurrenRowAndCol(); // 获得当前的行和列位置
}
}
// 获得当前的行和列位置,并显示在theLabelShowRowAndColumn上
private void getCurrenRowAndCol() {
int row = 0;
int col = 0;
int pos = textArea.getCaretPosition(); // 获得光标相对0行0列的位置
// 列!!!
col = pos - textArea.getText().substring(0, pos).lastIndexOf("/n");
// 行!!!
try {
row = textArea.getLineOfOffset(pos) + 1; // 返回行是从0算起的,所以+1
}catch(Exception exception) {
}
theLabelShowRowAndColumn.setText("行:" + row + " 列:" + col);
}
public static void main(String[] args) {
new CurrentRowAndColDemo();
}
}
//---------------- The End -----------------------------------------------------------
效果图如下:
效果如下: