关于JTextPane的setCaretPosition问题(探索ing)

这个问题来源于今天写一个项目诞生的,网上真没找到相关问题的解决方法,就看到有人问,但是问的好像也不是明确,毕竟没有贴代码。然后经过我吃过东西后,想到了解决方法,超开心!!!(不吃东西,脑子可能有些不好使,哈哈)

为了方便理解,我会用实现查找功能的项目,进行演示,以JTextArea和JTextPane做两个查找功能的项目,首先是JTextArea。

import javax.swing.*;
import java.awt.event.*;
public class AboutJTextPaneProblem extends JFrame{
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new AboutJTextPaneProblem();
	}
	AboutJTextPaneProblem(){
		JTextArea jta = new JTextArea();
		JTextField jtf = new JTextField();
		jtf.setSize(300,50);
		jtf.setLocation(10,0);
		JButton jb = new JButton("查找");

		jb.setSize(100,50);
		jb.setLocation(jtf.getWidth()+10,0);
		jb.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				jta.setCaretPosition(0);
				String str1 = jtf.getText();
				String str2 = jta.getText();
				int k =0;
				if(!str1.isEmpty()){
					k = str2.indexOf(str1);
				}if(k > -1){
					jta.setCaretPosition(k);//光标定位
					jta.select(k,k+str1.length());//选取查找内容
					jta.requestFocus();//聚焦
				}
			}
		});


		JScrollPane jScrollPane = new JScrollPane(jta);
		jScrollPane.setSize(400,350);
		jScrollPane.setLocation(10,jb.getHeight()+10);
		add(jtf);
		add(jb);
		add(jScrollPane);
		setLayout(null);
		setVisible(true);
		setSize(500,500);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}


页面如下
单击"查找"后,选中了"1"。
在这里插入图片描述

然后,将代码JTextArea换成JTextPane

import javax.swing.*;
import java.awt.event.*;
public class AboutJTextPaneProblem extends JFrame{
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new AboutJTextPaneProblem();
	}
	AboutJTextPaneProblem(){
		JTextPane jta = new JTextPane();
		JTextField jtf = new JTextField();
		jtf.setSize(300,50);
		jtf.setLocation(10,0);
		JButton jb = new JButton("查找");

		jb.setSize(100,50);
		jb.setLocation(jtf.getWidth()+10,0);
		jb.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				jta.setCaretPosition(0);
				String str1 = jtf.getText();
				String str2 = jta.getText();
				int k =0;
				if(!str1.isEmpty()){
					k = str2.indexOf(str1);
				}if(k > -1){
					jta.setCaretPosition(k);//光标定位
					jta.select(k,k+str1.length());//选取查找内容
					jta.requestFocus();//聚焦
				}
			}
		});


		JScrollPane jScrollPane = new JScrollPane(jta);
		jScrollPane.setSize(400,350);
		jScrollPane.setLocation(10,jb.getHeight()+10);
		add(jtf);
		add(jb);
		add(jScrollPane);
		setLayout(null);
		setVisible(true);
		setSize(500,500);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}

同上面操作一样,结果就报错了
在这里插入图片描述
报错详情如下

Exception in thread “AWT-EventQueue-0” java.lang.IllegalArgumentException: bad position: 17
at javax.swing.text.JTextComponent.setCaretPosition(JTextComponent.java:1629)
at csdn.article.AboutJTextPaneProblem 1. a c t i o n P e r f o r m e d ( A b o u t J T e x t P a n e P r o b l e m . j a v a : 28 ) a t j a v a x . s w i n g . A b s t r a c t B u t t o n . f i r e A c t i o n P e r f o r m e d ( A b s t r a c t B u t t o n . j a v a : 2022 ) a t j a v a x . s w i n g . A b s t r a c t B u t t o n 1.actionPerformed(AboutJTextPaneProblem.java:28) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022) at javax.swing.AbstractButton 1.actionPerformed(AboutJTextPaneProblem.java:28)atjavax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)atjavax.swing.AbstractButtonHandler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6539)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6304)
at java.awt.Container.processEvent(Container.java:2239)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2297)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4904)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4535)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4476)
at java.awt.Container.dispatchEventImpl(Container.java:2283)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue 3. r u n ( E v e n t Q u e u e . j a v a : 703 ) a t j a v a . s e c u r i t y . A c c e s s C o n t r o l l e r . d o P r i v i l e g e d ( N a t i v e M e t h o d ) a t j a v a . s e c u r i t y . P r o t e c t i o n D o m a i n 3.run(EventQueue.java:703) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain 3.run(EventQueue.java:703)atjava.security.AccessController.doPrivileged(NativeMethod)atjava.security.ProtectionDomainJavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:84)
at java.awt.EventQueue$4.run(EventQueue.java:733)
at java.awt.EventQueue 4. r u n ( E v e n t Q u e u e . j a v a : 731 ) a t j a v a . s e c u r i t y . A c c e s s C o n t r o l l e r . d o P r i v i l e g e d ( N a t i v e M e t h o d ) a t j a v a . s e c u r i t y . P r o t e c t i o n D o m a i n 4.run(EventQueue.java:731) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain 4.run(EventQueue.java:731)atjava.security.AccessController.doPrivileged(NativeMethod)atjava.security.ProtectionDomainJavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

经过我的一些尝试发现,JTextPane用getText()的内容是和JTextArea用getText()的内容是有区别的。从使用length()可以发现

用下述文本做区分
在这里插入图片描述

JTextArea的
在这里插入图片描述

JTextPane的

虽然下图没有报错,但是"1"未被选中,如果你在给它加几个回车就会报错了QWQ
在这里插入图片描述
看,是不是发现二者的长度不一样。你可能会说它们之相差5,但事实上不是的,一开始我也是这样认为的。
后面我突然想到"doc"就是看了一下setCaretPosition()方法的代码
在这里插入图片描述
跟"doc"有关,我就想到JTextPane可以Document类进行修改文本指定内容的大小和颜色之类的,同样,它可以用getText(),其获取长度为getLength()
OK,我加入并修改一些代码。请看下图在这里插入图片描述
记得导入Document,代码是"import javax.swing.text.Document",我是idea自动导了。QWQ

import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import java.awt.event.*;
public class AboutJTextPaneProblem extends JFrame{
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new AboutJTextPaneProblem();
	}
	AboutJTextPaneProblem(){
		JTextPane jta = new JTextPane();
		Document doc = jta.getDocument();

		JTextField jtf = new JTextField();
		jtf.setSize(300,50);
		jtf.setLocation(10,0);
		JButton jb = new JButton("查找");

		jb.setSize(100,50);
		jb.setLocation(jtf.getWidth()+10,0);
		jb.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				jta.setCaretPosition(0);
				String str1 = jtf.getText();
				String str2 = null;
				try {
					str2 = doc.getText(0,doc.getLength());
				} catch (BadLocationException badLocationException) {
					badLocationException.printStackTrace();
				}
				System.out.println("jta.getText().length():"+doc.getLength());
				int k =0;
				if(!str1.isEmpty()){
					k = str2.indexOf(str1);
				}if(k > -1){
					jta.setCaretPosition(k);//光标定位
					jta.select(k,k+str1.length());//选取查找内容
					jta.requestFocus();//聚焦
				}
			}
		});


		JScrollPane jScrollPane = new JScrollPane(jta);
		jScrollPane.setSize(400,350);
		jScrollPane.setLocation(10,jb.getHeight()+10);
		add(jtf);
		add(jb);
		add(jScrollPane);
		setLayout(null);
		setVisible(true);
		setSize(500,500);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}

OK,再次运行并单击"查找"按钮。看下图
在这里插入图片描述
换成doc.getLength()获取。结果就和JTextArea的一样了,同时"1"也被选中了,哈哈。
所以setCaretPosition()也成功定位。

OK,就是这样,废了废脑子,哈哈。真的超开心,哈哈。
如果如上操作无法解决您的问题,或者有些懵,希望你能评论你的情况或者私信发给我,咱们一起研究研究(无法解决您的问题的话),多谢了啦,共同进步嘛。


And,感谢你观看我的文章,感恩

posted @ 2022-09-14 22:05  晓星晨曦  阅读(131)  评论(0编辑  收藏  举报