微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何删除最后一行/组件/图标/小部件/等来自 JTextPane

如何解决如何删除最后一行/组件/图标/小部件/等来自 JTextPane

我有一个庞大的 Java 项目,它使用像 UI 这样的控制台。对于控制台,我使用 JTextPane。最近我需要分别删除第一行和最后一行的方法。我删除第一行的方法很简单,如下

public void removeFirstLine() {
        try {
            Element root = outputArea.getDocument().getDefaultRootElement();
            Element first = root.getElement(0);
            outputArea.getDocument().remove(first.getStartOffset(),first.getEndOffset());
            outputArea.setCaretPosition(outputArea.getDocument().getLength());
        } catch (BadLocationException e) {
            ErrorHandler.handle(e);
        }
    }

然而,当我尝试删除最后一行(不是文本,我重复不是文本)时,我的问题就出现了。该行可以是任何可附加到 JTextPane 的内容,例如自定义组件、文本字符串、图标等。如果有人知道如何删除附加到 JTextPane 的最后一个“东西”,我将永远感激您。

编辑:添加最小的可重现示例:

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

public class Test {
    public static void main(String[] args) {
        new test();
    }

    private static final String ELEM = AbstractDocument.ElementNameAttribute;
    private static final String ICON = StyleConstants.IconElementName;
    private static final String COMP = StyleConstants.ComponentElementName;
    private JTextPane outputArea;

    test() {
        try {
            //init pane
            outputArea = new JTextPane();

            //insert component
            JTextField c = new JTextField(20);
            Style cs = outputArea.getStyledDocument().addStyle("name",null);
            StyleConstants.setComponent(cs,c);
            outputArea.getStyledDocument().insertString(outputArea.getStyledDocument().getLength(),"string",cs);

            //new line
            println("");

            //add string
            println("this is a string added to the pane");

            //add image
            outputArea.insertIcon(new ImageIcon("/path/to/image.png"));

            //new line
            println("");

            //before
            printContents();

            //----------------------------
            //call removeLastLine() as many times as needed and it should remove the last added "thing"
            //regardless of the order added (ex: component,text,icon should function the same as text,component obvIoUsly)

            //changes should be reflected here
            printContents();

        } catch (Exception e) {
            e.printstacktrace();
        }
    }

    public void removeLastLine() {
        //Todo remove last line of text,last component,last image icon,etc.
    }

    public void println(String Usage) {
        try {
            StyledDocument document = (StyledDocument) outputArea.getDocument();
            document.insertString(document.getLength(),Usage + "\n",null);
            outputArea.setCaretPosition(outputArea.getDocument().getLength());
        }

        catch (Exception e) {
            e.printstacktrace();
        }
    }

    public void printContents() {
        try {
            ElementIterator iterator = new ElementIterator(outputArea.getStyledDocument());
            Element element;
            while ((element = iterator.next()) != null) {
                System.out.println(element);
                AttributeSet as = element.getAttributes();
                if (as.containsAttribute(ELEM,ICON)) {
                    System.out.println(StyleConstants.getIcon(as).getClass());
                }
                else if (as.containsAttribute(ELEM,COMP)) {
                    System.out.println(StyleConstants.getComponent(as).getClass());
                }
            }
        } catch (Exception e) {
            e.printstacktrace();
        }
    }
}

解决方法

以下是我之前使用过的用于删除文本的代码:

public void removeLastLine() {
    //  We use start minus 1 to make sure we remove the newline
    //  character of the previous line
    Element root = outputArea.getDocument().getDefaultRootElement();
    Element line = root.getElement(root.getElementCount() - 1);
    int start = line.getStartOffset();
    int end = line.getEndOffset();

    try
    {
        outputArea.getDocument().remove(start - 1,end - start);
    }
    catch(BadLocationException ble)
    {
        System.out.println(ble);
    }
}

似乎也适用于其他对象,因为“after”输出与“before”输出不同。

我会让您验证文本窗格是否按预期更新。

我从 Limit Lines in Document

获取了代码

编辑:

尝试删除第一行时,上面的代码不起作用,因为起始偏移量将为负。

以下是也处理删除第一行的更新版本:

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

public class Test {
    public static void main(String[] args) {

        new Test();
    }

    private static final String ELEM = AbstractDocument.ElementNameAttribute;
    private static final String ICON = StyleConstants.IconElementName;
    private static final String COMP = StyleConstants.ComponentElementName;
    private JTextPane outputArea;

    Test() {
        try {
            //init pane
            outputArea = new JTextPane();

            JButton button = new JButton("Remove Last Line");
            button.addActionListener((e) -> removeLastLine());

            JFrame frame = new JFrame();
            frame.add( new JScrollPane(outputArea) );
            frame.add( button,BorderLayout.PAGE_END);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.setSize(300,300);
            frame.setLocationByPlatform( true );
            frame.setVisible( true );

            println("first line");

            //insert component
            JTextField c = new JTextField(20);
            Style cs = outputArea.getStyledDocument().addStyle("name",null);
            StyleConstants.setComponent(cs,c);
            outputArea.getStyledDocument().insertString(outputArea.getStyledDocument().getLength(),"string",cs);

            //new line
            println("");

            //add string
            println("this is a string added to the pane");

            //add image
            outputArea.insertIcon(new ImageIcon("about16.gif"));

            //new line
            println("\nsecond last line");

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

    public void removeLastLine()
    {
        //  We use start minus 1 to make sure we remove the newline
        //  character of the previous line

        Element root = outputArea.getDocument().getDefaultRootElement();
        Element line = root.getElement(root.getElementCount() - 1);
        int start = line.getStartOffset();
        int end = line.getEndOffset();

        try
        {
            int offset = start - 1;
            int length = end - start;

            //  removing the first line

            if (offset < 0)
            {
                offset = 0;
                length -= 1;
            }

            outputArea.getDocument().remove(offset,length);
        }
        catch(BadLocationException ble)
        {
            System.out.println(ble);
        }
    }

    public void println(String Usage) {
        try {
            StyledDocument document = (StyledDocument) outputArea.getDocument();
            document.insertString(document.getLength(),Usage + "\n",null);
            outputArea.setCaretPosition(outputArea.getDocument().getLength());
        }

        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
,

我用我整个下午写的以下代码解决了这个问题。

 /**
     * Removes the last "thing" addeed to the JTextPane whether it's a component,*  icon,or string of multi-llined text.
     *
     *  In more detail,this method figures out what it'll be removing and then determines how many calls
     *   are needed to {@link StringUtil#removeLastLine()}
     */
 public void removeLast() {
        boolean removeTwoLines = false;

        LinkedList<Element> elements = new LinkedList<>();
        ElementIterator iterator = new ElementIterator(outputArea.getStyledDocument());
        Element element;
        while ((element = iterator.next()) != null) {
            elements.add(element);
        }

        int leafs = 0;

        for (Element value : elements)
            if (value.getElementCount() == 0)
                leafs++;

        int passedLeafs = 0;

        for (Element value : elements) {
            if (value.getElementCount() == 0) {
                if (passedLeafs + 3 != leafs) {
                    passedLeafs++;
                    continue;
                }

                if (value.toString().toLowerCase().contains("icon") || value.toString().toLowerCase().contains("component")) {
                    removeTwoLines = true;
                }
            }
        }

        if (removeTwoLines) {
            removeLastLine();
        }

        removeLastLine();
    }

    /**
     * Removes the last line added to the linked JTextPane. This could appear to remove nothing,*  but really be removing just a newline (line break) character.
     */
    public void removeLastLine() {
        try {
            LinkedList<Element> elements = new LinkedList<>();
            ElementIterator iterator = new ElementIterator(outputArea.getStyledDocument());
            Element element;
            while ((element = iterator.next()) != null) {
                elements.add(element);
            }

            int leafs = 0;

            for (Element value : elements)
                if (value.getElementCount() == 0)
                    leafs++;

            int passedLeafs = 0;

            for (Element value : elements) {
                if (value.getElementCount() == 0) {
                    if (passedLeafs + 2 != leafs) {
                        passedLeafs++;
                        continue;
                    }

                    outputArea.getStyledDocument().remove(value.getStartOffset(),value.getEndOffset() - value.getStartOffset());
                }
            }
        } catch (BadLocationException ignored) {}
        catch (Exception e) {
            e.printStackTrace();
        }
    }

可以在以下位置查看完整代码:https://github.com/NathanCheshire/Cyder/blob/master/src/cyder/utilities/StringUtil.java

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?