Custom Script Editor I'm making my own script editor (in this case for Arma: Cold War Assault) because I want to learn and this is challenging enough. 

Let me just get this out of the way: please don't tell me that I should do easier things. I want to do this anyway.

So, basically I have the simple GUI for now with a working new/open/save file menu. 

I've managed to highlight certain words with different colors (because I want to tackle the hardest part first) but it's not efficient. 

I've come up with several ideas for the algorithm (didn't implement them all), but I want to know what you'do, if there's a certain way and what I am doing wrong.

This all happens inside a JTextPane class.



The arrays containing the reserved words:

Collections.addAll(keywords, "private", "public", "if", "not", "then", "else", "else if");          
Collections.addAll(operators, "+", "-", "=", "==", "?", "!","(", ")","{", "}", "_", "-", "^", "&lt;", "&gt;");            

ArrayList&lt;String&gt; keywords = new ArrayList&lt;String&gt;();
ArrayList&lt;String&gt; operators = new ArrayList&lt;String&gt;();




Everytime the user makes an update to the document, it get's updated:

@Override
public void insertUpdate(DocumentEvent e) {
    update();
}

@Override
public void removeUpdate(DocumentEvent e) {
    update();
}




When the user stops typing, it waits 500 ms to update the screen: 

Timer t;

/**
 * Updates the text when user stops typing
 */
public void update(){

    if (t != null) {
        if (t.isRunning())
            t.stop();
    }

    t = new Timer(250, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {

            long start = System.currentTimeMillis();

            String text = getText();                

            SimpleAttributeSet attrs = new SimpleAttributeSet();
            StyleConstants.setForeground(attrs, Color.BLACK);
            StyledDocument doc = getStyledDocument();
            doc.setCharacterAttributes(0, text.length(), attrs, true);

            int index = 0, carriage = 0;

            while ((index &lt; text.length())) {

                if (text.codePointAt(index) == 10) {
                    carriage += 1;
                }

                for (String s : Keywords.listKeywords()) {                      
                    if (text.startsWith(s, index)){
                        changeColor(doc, reserved.get(s), index, carriage, s.length(), false);
                        index += s.length();
                        break;
                    }
                }

                for (String s : Keywords.listOperators()) {
                    if (text.startsWith(s, index)){
                        changeColor(doc, reserved.get(s), index, carriage, s.length(), false);
                        index += s.length();
                        break;
                    }
                }

                index++;
            }
            wordCount.setText("word count: " + index);
            System.out.println("Iterations took: "
                    + (System.currentTimeMillis() - start) + " ms");

            t.stop();
        }
    });
    t.start();
}

private void changeColor(StyledDocument doc, Color color, int index, int carriage, int length, boolean replace) {
    SimpleAttributeSet attrs = new SimpleAttributeSet();
    StyleConstants.setForeground(attrs, color);
    doc.setCharacterAttributes(index - carriage, length, attrs, replace);
}


How would I go about doing this more efficiently?

As of right now, with almost 145.000 words i have a delay of about 400 ms with 12 keywords and other words.
As a general direction for improvement, your technique for finding those keywords uses startsWith, which will effectively compare any given character once per potential keyword or operator. If you switch to regular expressions, by compiling a Pattern that matches any keyword or any operator, you build (what amounts to) a lookup table that typically allows one comparison per character, reducing the total number of comparisons significantly.

You can even use Pattern.quote to make building the String easier.

public Pattern fromList(List&lt;String&gt; strings) {
  StringBuilder builder = new StringBuilder();
  boolean isFirst = true;
  for (String string : strings) {
    if (!isFirst) {
      builder.append('|');
    }
    builder.append(Pattern.quote(string));
    isFirst = false;
  }
  return Pattern.compile(builder.toString());
}


After that, search for every occurrence of the String using either Pattern.matcher() (or Scanner.next()), which will save you those repeated comparisons. At that point you can use the start and end methods on Matcher (or the same on Scanner.match()).

I do notice that your algorithm will tend to highlight the first half of terms like publicValue even if the compiler does not detect it as a keyword. For this, you may want to customize the patterns you generate to match word boundaries.