关于Java的JTextPane组件(探索ing)

ps:这篇文章不得不说,拖了很久了(几个月吧)。最近决定来完成它,嘿嘿

基于网上对于该组件的知识比较杂,或者说没什么人讲解组件,然后经自己的探索和学习其他人关于"JTextPane"组件后,俺融合了一下"JTextPane"控件的大概内容。


关于JTextPane组件,我感觉挺牛的,其能用于加入指定文本大小、颜色、对齐方式及内容等,且可以实现指定文本的定位!(就跟记事本的查找功能一样)。其类似于"JTextArea"组件,但胜于其。 (个人感觉是这么回事,哈哈)


为了便于理解,我将对其的功能进行逐一讲解


目录如下(快速导航,网页右上角也有。)


0.基本概述

1.插入指定文本大小

2.插入指定文本颜色

3.插入指定文本对齐方式

4.替换指定文本内容(跟记事本的替换功能差不多)

0.基本概述

 首先,了解一下基本的。
 JTextPane组件需要用到StyledDocument、SimpleAttributeSet以及StyleConstants才能很好的实现上述的功能。(当然,也需要JFrame,不然就没法显示了,哈哈)
 基本操作如下代码

static JTextPane jTextPane = new JTextPane();
static StyledDocument doc = jTextPane.getStyledDocument();

 然后需要自定义一个方法以及相关参数。(方法名随意)

public static void insertText(String text/*文本内容*/, Color colorName/*文本颜色*/, int textSize/*文本大小*/, int textAlign/*对齐方式*/) {

        SimpleAttributeSet set = new SimpleAttributeSet();
        StyleConstants.setForeground(set, colorName);//设置文本颜色
        StyleConstants.setFontSize(set, textSize);//设置文本大小
        StyleConstants.setAlignment(set, textAlign);//设置文本对齐方式
        doc.setParagraphAttributes(jTextPane.getText().length(), doc.getLength() - jTextPane.getText().length(), set, false);//决定前者三个设置能否改变
    }

emmm,可以不加Color,textSize,textAlign该三者任一个,三个都不加也可以。
颜色默认为黑,字体大小默认为好像是12(跟按钮默认字体大小一样),对齐方式默认是左对齐。
颜色可以设置Color类里面能设置的颜色。
字体大小应该是没用限制的。多大都可以,就是看不看的到的问题。(我设置10000都行QWQ)
对齐方式有三种:左对齐,居中,右对齐,两边对齐。分别可以用

StyleConstants.ALING_LEFT(左对齐),数字表示为0
StyleConstants.ALIGN_CENTER(居中),数字表示为1
StyleConstants.ALIGN_RIGHT(右对齐),数字表示为2
StyleConstants.JUSTIFIED(两端对齐),数字表示为3,虽说为两端对齐,但还是在左对齐QWQ。暂时还没研究
出如何真的两端对齐QWQ

上述是对这三个的简单介绍。

		StyleConstants.setForeground(set, colorName);//设置文字颜色
        StyleConstants.setFontSize(set, textSize);//设置字体大小
        StyleConstants.setAlignment(set, textAlign);//设置文本对齐方式

下面说说下列代码
doc.setParagraphAttributes(jTextPane.getText().length(), doc.getLength() - jTextPane.getText().length(), set, false)

其的作用是为了设置所添加文本的位置,以此来精确改变相关内容。

第一个设置初始位置
而jTextPane.getText().length()是获取jTextPane现有文本长度。决定了在现有文本前或者后面添加文本。

第二个设置更改的长度
那么估计要问为什么要doc.getLength() - jTextPane.getText.length()呢。因为doc的length和JTextPane的length不一样!(这个很重要!我在我的另一篇文章有对其其他的描述。该文章

第三个嘛,就是用SimpleAttributeSet。这个就不多说了。

第四个是设置是否替换现有设置。

setParagraphAttributes方法的相关定义及介绍(文档的)

public abstract void setParagraphAttributes(int offset,
                                            int length,
                                            javax.swing.text.AttributeSet s,
                                            boolean replace)
                                            
Sets paragraph attributes.

Params:
offset – the start of the change >= 0
length – the length of the change >= 0
s – the non-null attributes to change to. Any attributes defined will be applied to the text for the given range.
replace – indicates whether or not the previous attributes should be cleared before the new attributes are set. If true, the operation will replace the previous attributes entirely. If false, the new attributes will be merged with the previous attributes.
翻译一下,就明白了(下附百度翻译)

设置段落属性。
参数:
偏移–更改的开始>=0
长度–更改的长度>=0
s–要更改为的非空属性。定义的任何属性都将应用于给定范围的文本。
replace–指示在设置新属性之前是否应清除以前的属性。如果为true,则该操作将完全替换以前的属性。如果为false,则新属性将与以前的属性合并。

OK,差不多就是这样。进入下面的实操吧!(看实操更易于理解,我是这么觉得的,哈哈)

1.插入指定文字大小

OK,进入正式的操作,有了上面的方法定义后,开了注释的应该就更为明白了。既然上面说,要用到StyledDocument,那么必然就是要在该方法里操作喽。

public static void insertText(String text/*文本内容*/, Color colorName/*文本颜色*/, int textSize/*文本大小*/, int textAlign/*对齐方式*/){
        SimpleAttributeSet set = new SimpleAttributeSet();
        StyleConstants.setForeground(set, colorName);//设置文本颜色
        StyleConstants.setFontSize(set, textSize);//设置文本大小
        StyleConstants.setAlignment(set, textAlign);//设置文本对齐方式
        doc.setParagraphAttributes(jTextPane.getText().length(), doc.getLength() - jTextPane.getText().length(), set, false);
        try {
            doc.insertString(doc.getLength(), text, set);//插入文本
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }

也就是在insertText方法里面加入了

		try {
            doc.insertString(doc.getLength(), text, set);//插入文本
        } catch (BadLocationException e) {
            e.printStackTrace();
        }

可以用try或者方法直接throws(这个关键词的作用,就不用多说吧。不晓得百度哈。)
因为只要实现字体大小,那么就只用setFontSize方法就可以了(代码如下)

public static void write(String text/*文本内容*/,int textSize/*字体大小*/) throws BadLocationException {
        SimpleAttributeSet set = new SimpleAttributeSet();
        StyleConstants.setFontSize(set, textSize);//设置字体大小
        doc.setParagraphAttributes(jTextPane.getText().length(), doc.getLength() - jTextPane.getText().length(), set, false);
        doc.insertString(doc.getLength(),text,set);
    }

实现效果:
在这里插入图片描述
在这里插入图片描述

整体代码如下

import javax.swing.*;
import javax.swing.text.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class AboutJTextPane extends JFrame{
    static JLabel jlSize = new JLabel("输入大小:");
    static JTextField jtfSize = new JTextField();
    static JLabel jlText = new JLabel("输入文本:");
    static JTextField jtfText = new JTextField();
    static JButton changeTextSize = new JButton("写入文本");//改变文本按钮
    static JTextPane jTextPane = new JTextPane();
    static StyledDocument doc = jTextPane.getStyledDocument();

    public static void main(String[] args){
        new AboutJTextPane();
    }
    AboutJTextPane(){
        jlText.setBounds(0,0,120,30);
        jtfText.setBounds(120,0,200,30);

        jlSize.setBounds(0,35,100,30);
        jtfSize.setBounds(100,35,200,30);

        //按钮相关设置
        changeTextSize.setBounds(300,35,150,30);
        changeTextSize.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    write(jtfText.getText(),Integer.parseInt(jtfSize.getText()));
                } catch (BadLocationException badLocationException) {
                    badLocationException.printStackTrace();
                }
            }
        });

        //JTextPane相关设置
        jTextPane.setBounds(10,100,300,300);

        add(jlSize);
        add(jlText);
        add(jtfSize);
        add(jtfText);
        add(changeTextSize);
        add(jTextPane);
        setLayout(null);
        setBounds(500,500,500,500);
        setTitle("JTextPane组件");
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public static void write(String text/*文本内容*/,int textSize/*文本大小*/) throws BadLocationException {
        SimpleAttributeSet set = new SimpleAttributeSet();
        StyleConstants.setFontSize(set, textSize);//设置文本大小
        doc.setParagraphAttributes(jTextPane.getText().length(), doc.getLength() - jTextPane.getText().length(), set, false);
        doc.insertString(doc.getLength(),text,set);
    }
}

2.插入指定文本颜色

这边是文字颜色了,那么就是用到setForeground方法

public static void write(String text/*文本内容*/,Color textColor/*文本颜色*/) throws BadLocationException {
        SimpleAttributeSet set = new SimpleAttributeSet();
        StyleConstants.setForeground(set, textColor);//设置文本颜色
        doc.setParagraphAttributes(jTextPane.getText().length(), doc.getLength() - jTextPane.getText().length(), set, false);
        doc.insertString(doc.getLength(),text,set);
    }

效果如下
在这里插入图片描述
在这里插入图片描述

快速过下,整体代码如下:


import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class AboutJTextPane extends JFrame{
    static String[] color = new String[]{"红色","蓝色","洋红"};
    static JLabel jlText = new JLabel("输入文本:");
    static JLabel jlColor = new JLabel("选择颜色:");
    static JComboBox jcb = new JComboBox(color);
    static JTextField jtfText = new JTextField();
    static JButton changeTextSize = new JButton("写入文本");//改变文本按钮
    static JTextPane jTextPane = new JTextPane();
    static StyledDocument doc = jTextPane.getStyledDocument();

    public static void main(String[] args){
        new AboutJTextPane();
    }
    AboutJTextPane(){
        jlText.setBounds(0,0,120,30);
        jtfText.setBounds(120,0,200,30);

        jlColor.setBounds(0,35,100,30);
        jcb.setBounds(100,35,200,30);

        //按钮相关设置
        changeTextSize.setBounds(300,35,150,30);
        changeTextSize.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    String choose = jcb.getSelectedItem().toString().trim();
                    System.out.println(choose);
                    switch (choose){
                        case "红色":
                            write(jtfText.getText(),Color.red);
                            break;
                        case "蓝色":
                            write(jtfText.getText(),Color.blue);
                            break;
                        case "洋红":
                            write(jtfText.getText(),Color.magenta);

                    }
                } catch (Exception ea) {
                    ea.printStackTrace();
                }
            }
        });

        //JTextPane相关设置
        jTextPane.setBounds(10,100,300,300);

        add(jlColor);
        add(jlText);
        add(jcb);
        add(jtfText);
        add(changeTextSize);
        add(jTextPane);
        setLayout(null);
        setBounds(500,500,500,500);
        setTitle("JTextPane组件");
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public static void write(String text/*文本内容*/, Color textColor/*文本颜色*/) throws BadLocationException {
        SimpleAttributeSet set = new SimpleAttributeSet();
        StyleConstants.setForeground(set, textColor);//设置文本颜色
        doc.setParagraphAttributes(jTextPane.getText().length(), doc.getLength() - jTextPane.getText().length(), set, false);
        doc.insertString(doc.getLength(),text,set);
    }
}

3.插入指定文本对齐方式

下面是文本对齐方式,那就是用到setAlignment方法

public static void write(String text/*文本内容*/, int textAlign/*对齐方式*/) throws BadLocationException {
        SimpleAttributeSet set = new SimpleAttributeSet();
        StyleConstants.setAlignment(set, textAlign);//设置对齐方式
        doc.setParagraphAttributes(jTextPane.getText().length(), doc.getLength() - jTextPane.getText().length(), set, false);
        doc.insertString(doc.getLength(),text,set);
    }

效果如下
在这里插入图片描述
在这里插入图片描述


这边提下面这幅图的情况
在这里插入图片描述
因为我的代码是这样的

switch (choose){
                        case "左对齐":
                            write(jtfText.getText()+"\n",0);
                            break;
                        case "居中":
                            write(jtfText.getText(),1);
                            break;
                        case "右对齐":
                            write(jtfText.getText(),2);

                    }

可见,“居中”和“右对齐”的代码里都少了“\n”(换行符),因为它改变的属性是整行的。这个希望大家注意下

整体代码如下:


import javax.swing.*;
import javax.swing.text.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class AboutJTextPane extends JFrame{
    static String[] color = new String[]{"左对齐","居中","右对齐"};
    static JLabel jlText = new JLabel("输入文本:");
    static JLabel jlColor = new JLabel("选择对齐方式:");
    static JComboBox jcb = new JComboBox(color);
    static JTextField jtfText = new JTextField();
    static JButton changeTextSize = new JButton("写入文本");//改变文本按钮
    static JTextPane jTextPane = new JTextPane();
    static StyledDocument doc = jTextPane.getStyledDocument();

    public static void main(String[] args){
        new AboutJTextPane();
    }
    AboutJTextPane(){
        jlText.setBounds(0,0,120,30);
        jtfText.setBounds(100,0,200,30);

        jlColor.setBounds(0,35,100,30);
        jcb.setBounds(100,35,200,30);

        //按钮相关设置
        changeTextSize.setBounds(300,35,150,30);
        changeTextSize.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    String choose = jcb.getSelectedItem().toString().trim();
                    System.out.println(choose);
                    switch (choose){
                        case "左对齐":
                            write(jtfText.getText()+"\n",0);
                            break;
                        case "居中":
                            write(jtfText.getText(),1);
                            break;
                        case "右对齐":
                            write(jtfText.getText(),2);

                    }
                } catch (Exception ea) {
                    ea.printStackTrace();
                }
            }
        });

        //JTextPane相关设置
        jTextPane.setBounds(10,100,300,300);

        add(jlColor);
        add(jlText);
        add(jcb);
        add(jtfText);
        add(changeTextSize);
        add(jTextPane);
        setLayout(null);
        setBounds(500,500,500,500);
        setTitle("JTextPane组件");
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public static void write(String text/*文本内容*/, int textAlign/*对齐方式*/) throws BadLocationException {
        SimpleAttributeSet set = new SimpleAttributeSet();
        StyleConstants.setAlignment(set, textAlign);//设置对齐方式
        doc.setParagraphAttributes(jTextPane.getText().length(), doc.getLength() - jTextPane.getText().length(), set, false);
        doc.insertString(doc.getLength(),text,set);
    }
}

4.替换指定文本内容

OK,到了最有意思的部分了,会了这部分后,实现记事本的替换功能应该是没问题了(当然,实现该功能也可以不用JTextPane)。也有点兴奋,因为其中有些定位问题是自己解决的,嘿嘿。

如标题,需要替换指定文本,那么就要实现相关文本的定位。代码如下

		/*向上找*/
        searchUp.setBounds(301,0,80,30);
        searchUp.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String searchText = jtfText.getText();
                String paneText = "";
                try {
                    paneText = doc.getText(0, doc.getLength());
                } catch (BadLocationException badLocationException) {
                    badLocationException.printStackTrace();
                }
                if (jTextPane.getSelectedText() == null) {
                    k = paneText.lastIndexOf(searchText, jTextPane.getCaretPosition() - 1);
                } else {
                    k = paneText.lastIndexOf(searchText, jTextPane.getCaretPosition() - jTextPane.getSelectedText().length() - 1);

                }
                k2 = k + searchText.length();
                if (k > -1) {
                    jTextPane.setCaretPosition(k);
                    jTextPane.select(k, k2);
                    jTextPane.requestFocus();
                } else {
                    JOptionPane.showMessageDialog(null, "找不到您查找的内容!", "查找", JOptionPane.INFORMATION_MESSAGE);
                }
            }
        });
        /*向下找*/
        searchDown.setBounds(382,0,80,30);
        searchDown.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String searchText = jtfText.getText();
                String paneText = "";
                try {
                    paneText = doc.getText(0, doc.getLength());
                } catch (BadLocationException badLocationException) {
                    badLocationException.printStackTrace();
                }
                int k = 0;
                if (jtfText.getSelectedText() == null) {
                    k = paneText.indexOf(searchText, jTextPane.getCaretPosition() + 1);
                } else {
                    k = paneText.indexOf(searchText, jTextPane.getCaretPosition() - searchText.length() + 1);
                }
                if (k > -1) {
                    jTextPane.setCaretPosition(k);
                    jTextPane.select(k, k + searchText.length());
                    jTextPane.requestFocus();
                } else {
                    JOptionPane.showMessageDialog(null, "找不到查找的内容?", "查找", JOptionPane.INFORMATION_MESSAGE);
                }
            }
        });

这里添加了两个按钮,分别是“向上找”和“向下找”。因为可能存在多个需要替换的文本,所以整两个确定相关位置(精确替换)。
二者的k值是有变化的,认真观察可以发现,它们后面有"-1"或"+1",前者决定着是向上,后者决定着是向下。相关取值为啥这样可参考我这个文章(还是之前提到的文章,嘿嘿),当然最好自己理解一下,比较好。

好的,下面就是实现替换了。这个需要用到JTextPane的replaceSelection方法。代码如下

 jTextPane.replaceSelection(jtfChange.getText());//替换选中文本

OK,既然定位和替换都整好了,那么展示一下效果吧

在这里插入图片描述
整体代码如下

import javax.swing.*;
import javax.swing.text.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class AboutJTextPane extends JFrame{
    static int k,k2 = 0;
    static JLabel jlText = new JLabel("需替换的文本:");
    static JLabel jlColor = new JLabel("         替换内容:");
    static JTextField jtfChange = new JTextField();
    static JTextField jtfText = new JTextField();
    static JButton searchUp = new JButton("向上找");
    static JButton searchDown = new JButton("向下找");
    static JButton changeTextSize = new JButton("替换");//改变文本按钮
    static JTextPane jTextPane = new JTextPane();
    static StyledDocument doc = jTextPane.getStyledDocument();

    public static void main(String[] args){
        new AboutJTextPane();
    }
    AboutJTextPane(){
        jlText.setBounds(0,0,100,30);
        jtfText.setBounds(100,0,200,30);

        jlColor.setBounds(0,35,100,30);
        jtfChange.setBounds(100,35,200,30);

        //按钮相关设置
        /*向上找*/
        searchUp.setBounds(301,0,80,30);
        searchUp.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String searchText = jtfText.getText();
                String paneText = "";
                try {
                    paneText = doc.getText(0, doc.getLength());
                } catch (BadLocationException badLocationException) {
                    badLocationException.printStackTrace();
                }
                if (jTextPane.getSelectedText() == null) {
                    k = paneText.lastIndexOf(searchText, jTextPane.getCaretPosition() - 1);
                } else {
                    k = paneText.lastIndexOf(searchText, jTextPane.getCaretPosition() - jTextPane.getSelectedText().length() - 1);

                }
                k2 = k + searchText.length();
                if (k > -1) {
                    jTextPane.setCaretPosition(k);
                    jTextPane.select(k, k2);
                    jTextPane.requestFocus();
                } else {
                    JOptionPane.showMessageDialog(null, "找不到您查找的内容!", "查找", JOptionPane.INFORMATION_MESSAGE);
                }
            }
        });
        /*向下找*/
        searchDown.setBounds(382,0,80,30);
        searchDown.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String searchText = jtfText.getText();
                String paneText = "";
                try {
                    paneText = doc.getText(0, doc.getLength());
                } catch (BadLocationException badLocationException) {
                    badLocationException.printStackTrace();
                }
                int k = 0;
                if (jtfText.getSelectedText() == null) {
                    k = paneText.indexOf(searchText, jTextPane.getCaretPosition() + 1);
                } else {
                    k = paneText.indexOf(searchText, jTextPane.getCaretPosition() - searchText.length() + 1);
                }
                if (k > -1) {
                    jTextPane.setCaretPosition(k);
                    jTextPane.select(k, k + searchText.length());
                    jTextPane.requestFocus();
                } else {
                    JOptionPane.showMessageDialog(null, "找不到查找的内容?", "查找", JOptionPane.INFORMATION_MESSAGE);
                }
            }
        });
        /*替换*/
        changeTextSize.setBounds(301,35,162,30);
        changeTextSize.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                jTextPane.replaceSelection(jtfChange.getText());//替换选中文本内容
            }
        });

        //JTextPane相关设置
        jTextPane.setBounds(10,100,460,340);

        add(searchUp);
        add(searchDown);
        add(jlColor);
        add(jlText);
        add(jtfChange);
        add(jtfText);
        add(changeTextSize);
        add(jTextPane);
        setLayout(null);
        setResizable(false);
        setBounds(500,500,500,500);
        setTitle("JTextPane组件");
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}







 JTextPane组件的相关操作就是这样了啦,JTextPane其实还可以插入图片,也就是用到JTextPane自带的方法insertIcon(),然后setCaretPosition方法是设置插入图片的位置(也是JTextPane),我觉得上述内容都可以整会,那么插入图片就不用我教了吧(本人有些懒,哎呀,有时间了再来补充了啦)
 唔。。。。。写了几个小时,毕竟有段时间了QWQ
 好了,就这样,撤退了。有什么不好之处,请谅解或指正。以及若出现什么问题,请在评论区或私信告诉我,谢谢了!




最后,感谢你能阅读我的文章,感恩!

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