JTextPane 换行行为

2024-01-02

最近我一直在做一个Java文本编辑器项目,我想使用JTextPane更换旧的JTextArea以实现语法高亮。然而,一个JTextPane缺乏方法JTextArea(例如append(), getLineStartOffset()等),我想在我的课堂上重新实现它们MyTextPane(一个子类JTextPane)但遇到了麻烦。

我当前的代码(只有一小部分独立部分):

import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;

public class MyTextPane extends JTextPane
{
    public MyTextPane()
    {
        super();
    }

    public void append(String text)
    {
        try
        {
            Document doc = this.getDocument();
            doc.insertString(doc.getLength(),text,null);
        }
        catch (BadLocationException ex)
        {
            //must succeed
            throw new InternalError(ex.getMessage());
        }
    }

    public void insert(String text, int pos)
    {
        try
        {
            this.getStyledDocument().insertString(pos,text,null);
        }
        catch (BadLocationException ex)
        {
            throw new IllegalArgumentException(ex);
        }
    }

    public void replaceRange(String str, int start, int end)
    {
        try
        {
            Document doc = this.getDocument();
            doc.remove(start,end-start);
            doc.insertString(start,str,null);
        }
        catch (BadLocationException ex)
        {
            throw new IllegalArgumentException(ex);
        }
    }

    public void setLineWrap(boolean isLineWrap)
    {
        /*
         * implements later
         */
    }

    public boolean getLineWrap()
    {
        /*
         * implements later
         */
         return true;
    }

    public void setWrapStyleWord(boolean isWrapStyleWord)
    {
        /*
         * implements later
         */
    }

    public boolean getWrapStyleWord()
    {
        /*
         * implements later
         */
        return true;
    }

    public void setTabSize(int size)
    {
        /*
         * implements later
         */        
    }

    public int getTabSize()
    {
        /*
         * implements later
         */
        return 4;
    }

    public int getLineCount()
    {
        //follow JTextArea implementation
        Element root = this.getDocument().getDefaultRootElement();
        return root.getElementCount();
    }

    public int getLineStartOffset(int line) throws BadLocationException
    {
        //follow JTextArea implementation
        int count = this.getLineCount();
        Document doc = this.getDocument();
        if (line < 0)
        {
            throw new BadLocationException("Negative line", -1);
        }
        if (line >= count)
        {
            throw new BadLocationException("No such line", doc.getLength() + 1);
        }
        return doc.getDefaultRootElement().getElement(line).getStartOffset();
    }

    public int getLineEndOffset(int line) throws BadLocationException
    {
        //follow JTextArea implementation
        int count = this.getLineCount();
        Document doc = this.getDocument();
        if (line < 0)
        {
            throw new BadLocationException("Negative line", -1);
        }
        if (line >= count)
        {
            throw new BadLocationException("No such line", doc.getLength() + 1);
        }
        int end = doc.getDefaultRootElement().getElement(line).getEndOffset();
        return (line==count-1)?(end-1):end;
    }

    public int getLineOfOffset(int off) throws BadLocationException
    {
        //follow JTextArea implementation
        Document doc = this.getDocument();
        if (off < 0)
        {
            throw new BadLocationException("Can't translate offset to line", -1);
        }
        if (off > doc.getLength())
        {
            throw new BadLocationException("Can't translate offset to line", doc.getLength() + 1);
        }
        return doc.getDefaultRootElement().getElementIndex(off);
    }

    public static void main(String[] args)
    {
        final SimpleAttributeSet BOLD_SET = new SimpleAttributeSet();
        StyleConstants.setBold(BOLD_SET, true);
        StyleConstants.setForeground(BOLD_SET, new Color(0,0,125));
        SwingUtilities.invokeLater(new Runnable()
        {            
            @Override
            public void run()
            {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                MyTextPane textPane = new MyTextPane();
                frame.add(new JScrollPane(textPane), BorderLayout.CENTER);
                frame.setSize(200,200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

正如你所看到的,我已经添加了一些方法,例如append()。但是,我想不出任何方法来控制换行策略。

默认行为很奇怪:当有一个短单词和一个长单词时,

如果我连续输入没有空格的字符,

它首先看起来像是用文字包裹的。然而当我继续输入字符时,

它根本不包裹。

有没有什么优雅的方法来控制 a 的包装策略JTextPane?换句话说,可以JTextPane像 a 一样包裹单词JTextArea?我发现了很多重复项(例如this https://stackoverflow.com/questions/4702891/toggling-text-wrap-in-a-jtextpane, this https://stackoverflow.com/questions/7156038/jtextpane-line-wrapping and this https://stackoverflow.com/questions/14636186/jtextpane-wont-wrap)但找不到解决方案。提前致谢。


这是关于同一问题的讨论:自 Java 7 以来 JTextPane 中的自动换行行为 https://community.oracle.com/message/10692405。用户提出的解决方案斯坦尼斯拉夫 https://community.oracle.com/people/StanislavL?customTheme=otn(他在 Stack Overflow 上似乎也非常活跃:斯坦尼斯拉夫 https://stackoverflow.com/users/301607/stanislavl)使用 Java 8 支持自动换行。它使用自定义WrapEditorKit作为编辑器套件JTextPane(以及WrapEditorKit类依次使用WrapColumnFactory and WrapLabelView类)。

将此与NonWrappingTextPane 示例 http://www.java2s.com/Code/Java/Swing-JFC/NonWrappingWrapTextPane.htm(来自 Kim Topley 的《Core Swing:高级编程》一书)可以关闭换行:

import java.awt.*;
import javax.swing.*;

public class WrapTestApp extends JFrame {
    public static void main(final String[] arguments) {
        new WrapTestApp();
    }

    public WrapTestApp() {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setBounds(800, 400, 200, 200);
        getContentPane().setLayout(new BorderLayout());
        final CustomTextPane textPane = new CustomTextPane(true);
        final JScrollPane scrollPane = new JScrollPane(textPane);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        getContentPane().add(scrollPane, BorderLayout.CENTER);
        textPane.setText("ExampleOfTheWrapLongWordWithoutSpaces");
        setVisible(true);
    }
}

The CustomTextPane class:

import javax.swing.*;
import javax.swing.text.*;

public class CustomTextPane extends JTextPane {
    private boolean lineWrap;

    public CustomTextPane(final boolean lineWrap) {
        this.lineWrap = lineWrap;

        if (lineWrap)
            setEditorKit(new WrapEditorKit());
    }

    @Override
    public boolean getScrollableTracksViewportWidth() {
        if (lineWrap)
            return super.getScrollableTracksViewportWidth();
        else
            return getParent() == null
                  || getUI().getPreferredSize(this).width <= getParent().getSize().width;
    }

    private class WrapEditorKit extends StyledEditorKit {
        private final ViewFactory defaultFactory = new WrapColumnFactory();

        @Override
        public ViewFactory getViewFactory() {
            return defaultFactory;
        }
    }

    private class WrapColumnFactory implements ViewFactory {
        @Override
        public View create(final Element element) {
            final String kind = element.getName();
            if (kind != null) {
                switch (kind) {
                    case AbstractDocument.ContentElementName:
                        return new WrapLabelView(element);
                    case AbstractDocument.ParagraphElementName:
                        return new ParagraphView(element);
                    case AbstractDocument.SectionElementName:
                        return new BoxView(element, View.Y_AXIS);
                    case StyleConstants.ComponentElementName:
                        return new ComponentView(element);
                    case StyleConstants.IconElementName:
                        return new IconView(element);
                }
            }

            // Default to text display.
            return new LabelView(element);
        }
    }

    private class WrapLabelView extends LabelView {
        public WrapLabelView(final Element element) {
            super(element);
        }

        @Override
        public float getMinimumSpan(final int axis) {
            switch (axis) {
                case View.X_AXIS:
                    return 0;
                case View.Y_AXIS:
                    return super.getMinimumSpan(axis);
                default:
                    throw new IllegalArgumentException("Invalid axis: " + axis);
            }
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JTextPane 换行行为 的相关文章

  • 如何让 BlazeDS 忽略属性?

    我有一个 java 类 它有一个带有 getter 和 setter 的字段 以及第二对 getter 和 setter 它们以另一种方式访问 该字段 public class NullAbleId private static final
  • 序列的排列?

    我有具体数量的数字 现在我想以某种方式显示这个序列的所有可能的排列 例如 如果数字数量为3 我想显示 0 0 0 0 0 1 0 0 2 0 1 0 0 1 1 0 1 2 0 2 0 0 2 1 0 2 2 1 0 0 1 0 1 1 0
  • Mockito:如何通过模拟测试我的服务?

    我是模拟测试新手 我想测试我的服务方法CorrectionService correctPerson Long personId 实现尚未编写 但这就是它将执行的操作 CorrectionService将调用一个方法AddressDAO这将
  • 使用 LinkedList 实现下一个和上一个按钮

    这可能是一个愚蠢的问题 但我很难思考清楚 我编写了一个使用 LinkedList 来移动加载的 MIDI 乐器的方法 我想制作一个下一个和一个上一个按钮 以便每次单击该按钮时都会遍历 LinkedList 如果我硬编码itr next or
  • 动态选择端口号?

    在 Java 中 我需要获取端口号以在同一程序的多个实例之间进行通信 现在 我可以简单地选择一些固定的数字并使用它 但我想知道是否有一种方法可以动态选择端口号 这样我就不必打扰我的用户设置端口号 这是我的一个想法 其工作原理如下 有一个固定
  • 来自 dll 的 Java 调用函数

    我有这个 python 脚本导入zkemkeeperdll 并连接到考勤设备 ZKTeco 这是我正在使用的脚本 from win32com client import Dispatch zk Dispatch zkemkeeper ZKE
  • java.lang.IllegalStateException:提交响应后无法调用 sendRedirect()

    这两天我一直在尝试找出问题所在 我在这里读到我应该在代码中添加一个返回 我做到了 但我仍然得到 java lang IllegalStateException Cannot call sendRedirect after the respo
  • Eclipse Maven Spring 项目 - 错误

    I need help with an error which make me crazy I started to study Java EE and I am going through tutorial on youtube Ever
  • 如何访问JAR文件中的Maven资源? [复制]

    这个问题在这里已经有答案了 我有一个使用 Maven 构建的 Java 应用程序 我有一个资源文件夹com pkg resources 我需要从中访问文件 例如directory txt 我一直在查看各种教程和其他答案 但似乎没有一个对我有
  • 为什么 Java 8 不允许非公共默认方法?

    让我们举个例子 public interface Testerface default public String example return Hello public class Tester implements Testerface
  • java for windows 中的文件图标叠加

    我正在尝试像 Tortoise SVN 或 Dropbox 一样在文件和文件夹上实现图标叠加 我在网上查了很多资料 但没有找到Java的解决方案 Can anyone help me with this 很抱歉确认您的担忧 但这无法在 Ja
  • 不接受任何内容也不返回任何内容的函数接口[重复]

    这个问题在这里已经有答案了 JDK中是否有一个标准的函数式接口 不接受也不返回任何内容 我找不到一个 像下面这样 FunctionalInterface interface Action void execute 可运行怎么样 Functi
  • 如何阻止破折号自行包裹?

    我有一个标题 标题最后一个单词的末尾是一个破折号 单词和破折号之间没有空格 当浏览器窗口变小时 破折号会中断并换成新行 在自己的行上有一个破折号是不好的排版 如何停止破折号之前的换行 以便最后一个单词运行到新行 这是代码 h1 XYZ co
  • 我如何在java中读取二进制数据文件

    因此 我正在为学校做一个项目 我需要读取二进制数据文件并使用它来生成角色的统计数据 例如力量和智慧 它的设置是让前 8 位组成一个统计数据 我想知道执行此操作的实际语法是什么 是不是就像读文本文件一样 这样 File file new Fi
  • 干净构建 Java 命令行

    我正在使用命令行编译使用 eclipse 编写的项目 如下所示 javac file java 然后运行 java file args here 我将如何运行干净的构建或编译 每当我重新编译时 除非删除所有内容 否则更改不会受到影响 cla
  • 在java中为组合框分配键

    我想添加一个JComboBox在 Swing 中这很简单 但我想为组合中的每个项目分配值 我有以下代码 JComboBox jc1 new JComboBox jc1 addItem a jc1 addItem b jc1 addItem
  • 长轮询会冻结浏览器并阻止其他 ajax 请求

    我正在尝试在我的中实现长轮询Spring MVC Web 应用程序 http static springsource org spring docs 2 0 x reference mvc html但在 4 5 个连续 AJAX 请求后它会
  • 如何将双精度/浮点四舍五入为二进制精度?

    我正在编写对浮点数执行计算的代码的测试 不出所料 结果很少是准确的 我想在计算结果和预期结果之间设置一个容差 我已经证实 在实践中 使用双精度 在对最后两位有效小数进行四舍五入后 结果始终是正确的 但是usually四舍五入最后一位小数后
  • 如何防止在Spring Boot单元测试中执行import.sql

    我的类路径中有一个 import sql 文件 其中包含一些 INSERT 语句 当使用 profile devel 运行我的应用程序时 它的数据被加载到 postgres 数据库中 到目前为止一切正常 当使用测试配置文件执行测试时 imp
  • Spring Rest 和 Jsonp

    我正在尝试让我的 Spring Rest 控制器返回jsonp但我没有快乐 如果我想返回 json 但我有返回的要求 完全相同的代码可以正常工作jsonp我添加了一个转换器 我在网上找到了用于执行 jsonp 转换的源代码 我正在使用 Sp

随机推荐

  • 如何将通知号码添加到按钮图标?

    我正在尝试使用 PyQt5 制作 GUI 它将有一个带有图标的通知按钮 我想在图标上添加一个带有通知数量的小气泡 如果无法提供数字 我想使用红点作为备用方法 但是我应该如何跟踪新通知 如通知侦听器 并在窗口运行时更改图标 我一直在谷歌上搜索
  • c# itextsharp PDF 创建,每页带有水印

    我正在尝试使用 itextsharp Java itext 的 C 端口 以编程方式创建多个 PDF 文档 每个页面上都带有水印 我可以在使用 PdfStamper 创建文档后执行此操作 然而 这似乎涉及重新打开文档阅读它 然后创建一个每个
  • 为什么存在 REP LODS AL 指令?

    换句话说 在任何情况下我可能需要这个指示吗 根据英特尔指令手册 该指令的作用如下 将 E CX 字节从 DS E SI 加载到 AL 以 NASM 为例 section data src db 0 1 2 3 section code mo
  • 如何将自定义 Jupyter 内核放置在虚拟环境中?

    我有一个自定义 Jupyter 内核 它使用使用 matplotlib 样式表的自定义 IPython 配置文件运行 IPython 我知道要正常运行它 我会输入 config matplotlib stylelib 中的 matplotl
  • 在 C# 中计算重复日期的正确方法

    在我的项目中 我需要计算重复事件的日期 一开始我只有一个开始日期 时间以及该事件必须如何重复的信息 Every Day Every Week Every 2 Weeks Every 3 Weeks Every Month Every 2 M
  • 如何使用 Nokogiri::XML::Builder 创建元素名称中带有连字符的 XML?

    我正在尝试使用 Nokogiri 构建 XML 文档 有些元素中有连字符 这是一个例子 require nokogiri builder Nokogiri XML Builder new do xml xml foo bar hello e
  • 使用 maven-surefire 运行测试时,Spring-Autowiring 在 @BeforeClass 之后发生

    我在依赖注入 Spring 自动装配 和 maven surefire 方面遇到一些问题 当使用 TestNG 在 eclipse 中运行时 以下测试可以正常工作 服务对象被注入 然后 BeforeClass 方法被调用 Transacti
  • 带圆角半径的自动布局(带砌体)

    我想用 Masonry 布局一个圆形 UIImageView 所以我创建了这样的 UIImageView self imageView mas makeConstraints MASConstraintMaker make make cen
  • 如何保持 ExpandableListView 打开?

    我正在研究 ExpandableListView 我已经完成了工作 现在我只想做的一件事是我不希望 ListView 在单击可扩展列表视图时变为 DropDown 而是希望显示它与所有项目一起打开无需对其进行任何单击即可显示在内部 谁能告诉
  • 正确使用 `for_each_arg` - 转发过多?

    我真的很高兴发现for each arg https twitter com ericniebler status 559119062895431680 这使得处理参数包变得更加容易 template
  • 将 AsyncLayoutInflater 与 DataBinding 结合使用

    我目前使用以下方法来膨胀我的大部分布局DataBindingUtil inflate inflater layoutId parent attachToParent https developer android com reference
  • 通过 OSX ssh rsync 保留别名

    我在 OSX Yosemite 上通过 ssh 进行 rsync 保存别名时遇到了麻烦 rsync av e ssh email protected cdn cgi l email protection Users me stuff Use
  • 使用带有投影的 find() 方法使用 mongodb java driver 3.4 检索数据

    我正在使用 mongodb java 驱动程序 3 4 mongodb数据库中文档按照以下结构保存 id ObjectId 595a9fc4fe3f36402b7edf0e id 123 priceInfo object1 value1 o
  • 从 CSV 数据中删除尾随逗号

    这是在另一个数字后添加逗号的代码 但我想删除最后一个逗号 str MSISDN Append MSISDN x TrimStart 我建议您使用而不是手动附加内容String Join这将使事情一开始就正确 您可以使用 LINQ 来修剪值
  • 如何提高Redis服务器的CPU使用率?

    我的目标是让我们的 Redis 服务器在生产中达到 80 左右的 CPU 利用率 这将有利于我们的后端服务器设计 确保我们不会充分利用 CPU 同时也为增长和峰值留出一些空间 在使用Redis自己的基准测试工具时redis benchmar
  • 在嵌套文件夹中查找文件[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 如何在嵌套文件夹中搜索文件 看看这个函数 System IO DirectoryInfo GetFiles SearchPattern
  • 如何检查我的应用程序从磁盘写入和读取了多少字节?

    我不知道我是否没有使用正确的词在网络上搜索 但我没有找到解决方案来查看我的应用程序已经在磁盘上读取和写入了多少 有人可以帮我解决这个问题吗 tks 解决 如果有人需要功能标志 type IO COUNTERS record ReadOper
  • 如何获取当前页面的html?

    我想解析当前页面的html 如何在asp net中获取当前页面的html 提前致谢 对于客户端 在互联网浏览器中 右键点击浏览器 gt 查看源代码 在火狐浏览器中 右键点击浏览器 gt 查看页面源代码 对于服务器端 您可以重写页面的渲染方法
  • 尝试在路径 file:///var/mobile/Media/PhotoData/Photos.sqlite 添加只读文件?

    我刚刚更新到新的 Xcode beta 6 0 当尝试使用 iOS 8 为 ipad mini 进行编译时 我在控制台中收到一个奇怪的错误 尝试在路径 file var mobile Media PhotoData Photos sqlit
  • JTextPane 换行行为

    最近我一直在做一个Java文本编辑器项目 我想使用JTextPane更换旧的JTextArea以实现语法高亮 然而 一个JTextPane缺乏方法JTextArea 例如append getLineStartOffset 等 我想在我的课堂