首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java代码优化--如何优化这个remove()函数?

Java代码优化--如何优化这个remove()函数?
EN

Stack Overflow用户
提问于 2015-05-12 15:05:54
回答 3查看 194关注 0票数 1

我正在为一个名为编译器的类创建一个自定义语言作为一个项目。整个项目使用Java语言,使用JFlex作为我的词法分析器,使用杯子作为语法分析器。

我为该语言创建了一个简单的文本编辑器,它基本上由一个JTextPane组成,用户可以在其中键入将被解析的自定义代码。这个JTextPane有一个DefaultStyledDocument,用于设置字符属性,例如,为JTextPane内的代码(文本)更改关键字、注释、字符串、数字等的颜色。

下面是我使用的代码:

代码语言:javascript
复制
        DefaultStyledDocument doc = new DefaultStyledDocument() {
        @Override
        public void insertString(int offset, String str, AttributeSet a) throws BadLocationException { //cuando se insertan caracteres.
            super.insertString(offset, str, a);
            String text = getText(0, getLength());
            syntax = new SyntaxHighlighter(new java.io.StringReader(text));
            Token val;
            try {
                while ((val = syntax.yylex()) != null) {
                    switch (val.type) {
                        case TokenType.KEYWORD:
                            setCharacterAttributes(val.start, val.length, keyword, true);
                            break;
                        case TokenType.COMMENT:
                            setCharacterAttributes(val.start, val.length, comment, true);
                            break;
                        case TokenType.STRING:
                            setCharacterAttributes(val.start, val.length, string, true);
                            break;
                        case TokenType.FUNCTION:
                            setCharacterAttributes(val.start, val.length, function, true);
                            break;
                        case TokenType.NUMBER:
                            setCharacterAttributes(val.start, val.length, plain, true);
                            break;
                        case TokenType.OPERATOR:
                            setCharacterAttributes(val.start, val.length, operator, true);
                            break;
                        case TokenType.READ:
                            setCharacterAttributes(val.start, val.length, number, true);
                            break;
                        default:
                            setCharacterAttributes(val.start, val.length, plain, true);
                            break;
                    }
                }
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(rootPane, "Oops! Exception triggered\n" + ex.getMessage());
            }
        }

        @Override
        //this is the method I want to optimize
        public void remove(int offs, int len) throws BadLocationException { 
            super.remove(offs, len);
            String text = getText(0, getLength());
            syntax = new SyntaxHighlighter(new java.io.StringReader(text));
            Token val;
            try {
                while ((val = syntax.yylex()) != null) {
                    switch (val.type) {
                        case TokenType.KEYWORD:
                            setCharacterAttributes(val.start, val.length, keyword, true);
                            break;
                        case TokenType.COMMENT:
                            setCharacterAttributes(val.start, val.length, comment, true);
                            break;
                        case TokenType.STRING:
                            setCharacterAttributes(val.start, val.length, string, true);
                            break;
                        case TokenType.FUNCTION:
                            setCharacterAttributes(val.start, val.length, function, true);
                            break;
                        case TokenType.NUMBER:
                            setCharacterAttributes(val.start, val.length, plain, true);
                            break;
                        case TokenType.OPERATOR:
                            setCharacterAttributes(val.start, val.length, operator, true);
                            break;
                        case TokenType.READ:
                            setCharacterAttributes(val.start, val.length, number, true);
                            break;
                        default:
                            setCharacterAttributes(val.start, val.length, plain, true);
                            break;
                    }
                }
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(rootPane, "Oops! Exception triggered\n" + ex.getMessage());
            }
        }
    };

this.codeTextPane.setStyledDocument(doc);

SyntaxHighlighter类基本上是一个词法器(由JFlex生成),仅用作搜索特定文本片段(关键字、字符串等)的方法。一切都很完美但是..。

问题:

当JTextPane中有相当数量的文本时,按住后退键移除文本会使程序延迟相当困难。我认为发生这种情况的原因可能是因为SyntaxHighlighter运行时每个字符都被删除,因为按住backspace键调用每个被删除字符的remove()函数。插入文本并不是一个真正的问题,因为您可以从一个文件加载代码(在该文件中的整个文本将由SyntaxHighlighter作为一个整体进行分析),或者您不能以足够快的速度键入以注意到延迟。

有什么方法可以优化这个吗?谢谢大家!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-12 15:42:31

总之,这些代码似乎是结构化的,而且很清楚,我很快就理解了它。因此,我的建议是:尽可能长地保留它(强制开放-封闭原则)。

我建议的唯一改变是将字符删除与突出显示分开。这一点已经提过了。但是,您应该这样做的原因是:您将能够延迟语法高亮显示,直到用户删除了一部分字符。因此,语法突出显示不会每次删除一个字符时都会被忽略。

我认为您应该将主文本分解为句法单元,然后只在已更改的句法单元上应用突出显示语法。主要问题是分析和识别变化的单元。

正如前面的作者所提到的,将语法突出显示到分离的线程中也会提高性能。

这些变化不是琐碎的,而是可能的。

票数 0
EN

Stack Overflow用户

发布于 2015-05-12 15:36:41

我的第一反应是采取加窗的策略。在您的代码中,维护一棵树或其他能够表示自包含范围的结构。然后,调整语法高亮符和代码的其他部分,使其只在树的部分(或他们所知道的任何部分)上工作。

抽象地说,你们可能有这样的关系:

代码语言:javascript
复制
class
  |
+----------+
method1    method2
              |
           +--------+--------+
           line1    line2    line3

..。,它允许在不更改内容的上下文中理解line3中的删除。

票数 1
EN

Stack Overflow用户

发布于 2015-05-14 06:17:10

定义类字段javax.swing.Timer syntaxTimer

在每个insert()remove()上检查syntaxTimer是否为null。

如果为null,则创建具有500 msec延迟的syntaxTimer实例(可以是300或1000,如您所愿)并启动syntaxTimer。如果不只是跳过计时器初始化,因为您已经初始化了它。

当调用syntaxTimeractionPerformed()时,执行与SyntaxHighlighter相关的逻辑并清除syntaxTimer (停止并设置syntaxTimer=null)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30194784

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档