package org.ui.syntaxes; import javax.swing.*; import javax.swing.text.*; import java.awt.*; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class SyntaxHighlighter { private final CharAttrib defaultCharAttribs; protected JTextPane textPane; protected TabSet tabset; private final List> elements; private int selectionStart; private int selectionLength; private final int fontSize; public SyntaxHighlighter(JTextPane textPane, float tabSize, int fontSize) { this.textPane = textPane; this.fontSize = fontSize; this.elements = new ArrayList<>(); this.defaultCharAttribs = new CharAttrib(false, false, textPane.getForeground()); createTabset(tabSize); } public SyntaxHighlighter(JTextPane textPane, float tabSize, int fontSize, Color backgroundColor) { this.textPane = textPane; this.fontSize = fontSize; this.elements = new ArrayList<>(); this.defaultCharAttribs = new CharAttrib(false, false, textPane.getForeground()); this.defaultCharAttribs.setBackgroundColor(backgroundColor); createTabset(tabSize); } protected void createHighlightPattern(String regex, CharAttrib attribs) { this.elements.add(new Pair<>(regex, attribs)); } private void createTabset(float tabSize) { TabStop[] tabs = new TabStop[8]; for (int i = 0; i < tabs.length; i++) { tabs[i] = new TabStop(tabSize * i + tabSize, 0, 0); } this.tabset = new TabSet(tabs); } public final void highlight() { this.selectionStart = 0; this.selectionLength = this.textPane.getDocument().getLength(); createHighlight(this.defaultCharAttribs); try { for (Pair entry : this.elements) { Matcher matcher = Pattern.compile(entry.getA(), Pattern.MULTILINE | Pattern.DOTALL).matcher( this.textPane.getDocument().getText(0, this.textPane.getDocument().getLength())); while (matcher.find()) { this.selectionStart = matcher.start(); this.selectionLength = matcher.end() - this.selectionStart; createHighlight(entry.getB()); } } } catch (BadLocationException e) { e.printStackTrace(); } } private void createHighlight(CharAttrib attribs) { StyleContext sc = StyleContext.getDefaultStyleContext(); AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Background, this.defaultCharAttribs.getBackgroundColor()); aset = sc.addAttribute(aset, StyleConstants.FontFamily, new Font("Monospaced", Font.PLAIN, 16).getFamily()); aset = sc.addAttribute(aset, StyleConstants.FontSize, this.fontSize); aset = sc.addAttribute(aset, StyleConstants.Bold, attribs.isBold()); aset = sc.addAttribute(aset, StyleConstants.Italic, attribs.isItalic()); aset = sc.addAttribute(aset, StyleConstants.TabSet, this.tabset); if (attribs.getColor() == null) { Color foregroundColor = (Color) this.textPane.getStyledDocument() .getCharacterElement(this.selectionStart).getAttributes() .getAttribute(StyleConstants.Foreground); aset = sc.addAttribute(aset, StyleConstants.Foreground, foregroundColor.darker()); } else { aset = sc.addAttribute(aset, StyleConstants.Foreground, attribs.getColor()); } this.textPane.getStyledDocument().setCharacterAttributes(this.selectionStart, this.selectionLength, aset, false); } }