diff --git a/src/main/java/org/quiltmc/syntaxpain/DefaultSyntaxAction.java b/src/main/java/org/quiltmc/syntaxpain/DefaultSyntaxAction.java deleted file mode 100644 index 4c3a38c..0000000 --- a/src/main/java/org/quiltmc/syntaxpain/DefaultSyntaxAction.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License - * at http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.quiltmc.syntaxpain; - -import javax.swing.Action; -import javax.swing.text.JTextComponent; -import javax.swing.text.TextAction; -import java.awt.event.ActionEvent; - -/** - * The DefaultSyntaxAction. You can extend this class or implement the interface - * SyntaxAction to create your own actions. - * - * @author Ayman Al-Sairafi - */ -public abstract class DefaultSyntaxAction extends TextAction implements Action { - public DefaultSyntaxAction(String actionName) { - super(actionName); - this.putValue(NAME, actionName); - } - - @Override - public void actionPerformed(ActionEvent e) { - JTextComponent text = this.getTextComponent(e); - SyntaxDocument sdoc = Util.getSyntaxDocument(text); - if (text != null) { - this.actionPerformed(text, sdoc, text.getCaretPosition(), e); - } - } - - /** - * Convenience method that will be called if the Action is performed on a - * JTextComponent. SyntaxActions should generally override this method. - * @param target (non-null JTextComponent from Action.getSource - * @param sDoc (SyntaxDOcument of the text component, could be null) - * @param dot (position of caret at text document) - * @param e actual ActionEvent passed to actionPerformed - */ - public void actionPerformed(JTextComponent target, SyntaxDocument sDoc, int dot, ActionEvent e) { - throw new UnsupportedOperationException("Not yet implemented"); - } - - @Override - public String toString() { - return "Action " + this.getValue(NAME) + "of type " + this.getClass().getSimpleName(); - } -} diff --git a/src/main/java/org/quiltmc/syntaxpain/DocumentSearchData.java b/src/main/java/org/quiltmc/syntaxpain/DocumentSearchData.java index 21aac21..bdbea57 100644 --- a/src/main/java/org/quiltmc/syntaxpain/DocumentSearchData.java +++ b/src/main/java/org/quiltmc/syntaxpain/DocumentSearchData.java @@ -111,7 +111,7 @@ public boolean doFindPrev(JTextComponent target) { return false; } - SyntaxDocument sDoc = Util.getSyntaxDocument(target); + SyntaxDocument sDoc = SyntaxDocument.getFrom(target); if (sDoc == null) { return false; } @@ -166,7 +166,7 @@ public boolean doFindNext(JTextComponent target) { return false; } - SyntaxDocument sDoc = Util.getSyntaxDocument(target); + SyntaxDocument sDoc = SyntaxDocument.getFrom(target); if (sDoc == null) { return false; } diff --git a/src/main/java/org/quiltmc/syntaxpain/EscapeListener.java b/src/main/java/org/quiltmc/syntaxpain/EscapeListener.java deleted file mode 100644 index 68fe97f..0000000 --- a/src/main/java/org/quiltmc/syntaxpain/EscapeListener.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License - * at http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.quiltmc.syntaxpain; - -import javax.swing.RootPaneContainer; - -/** - * This interface is used by dialogs that will need to listen to ESC key. - * When the ESC key is pressed, escapePressed is called. - * @author Ayman Al-Sairafi - */ -public interface EscapeListener extends RootPaneContainer { - /** - * This method will be called when ESC key is pressed. - */ - void escapePressed(); -} diff --git a/src/main/java/org/quiltmc/syntaxpain/JavaSyntaxKit.java b/src/main/java/org/quiltmc/syntaxpain/JavaSyntaxKit.java index 86bfcf4..2af0dae 100644 --- a/src/main/java/org/quiltmc/syntaxpain/JavaSyntaxKit.java +++ b/src/main/java/org/quiltmc/syntaxpain/JavaSyntaxKit.java @@ -17,28 +17,41 @@ import org.quiltmc.syntaxpain.generated.JavaLexer; -import javax.swing.Action; -import javax.swing.ActionMap; -import javax.swing.InputMap; -import javax.swing.JEditorPane; -import javax.swing.KeyStroke; import javax.swing.text.DefaultEditorKit; import javax.swing.text.Document; import javax.swing.text.Element; -import javax.swing.text.JTextComponent; import javax.swing.text.View; import javax.swing.text.ViewFactory; import java.awt.Color; -import java.awt.Font; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.WeakHashMap; +@SuppressWarnings("unused") public class JavaSyntaxKit extends DefaultEditorKit implements ViewFactory { + public static final String CONTENT_TYPE = "text/enigma-sources"; + + private static SyntaxStyleMap styles = new SyntaxStyleMap( + new Color(0x3333EE), + new Color(0xCC6600), + new Color(0x999933), + new Color(0x000000), + new Color(0x000000), + new Color(0x000000), + new Color(0x000000), + new Color(0x339933), + new Color(0x000000), + new Color(0xcc6600) + ); + + public static void setSyntaxColors( + Color highlight, Color string, Color number, Color operator, Color delimiter, + Color type, Color identifier, Color comment, Color text, Color regex + ) { + styles = new SyntaxStyleMap( + highlight, string, number, operator, delimiter, + type, identifier, comment, text, regex + ); + } + private final Lexer lexer; - private final Map> editorComponents = new WeakHashMap<>(); - private static Font font = null; public JavaSyntaxKit() { super(); @@ -46,22 +59,6 @@ public JavaSyntaxKit() { this.lexer = new JavaLexer(); } - public void addComponents(JEditorPane editorPane) { - this.installComponent(editorPane, new PairsMarker()); - this.installComponent(editorPane, new LineNumbersRuler()); - } - - public void installComponent(JEditorPane pane, SyntaxComponent comp) { - comp.configure(); - comp.install(pane); - this.editorComponents.computeIfAbsent(pane, k -> new ArrayList<>()); - this.editorComponents.get(pane).add(comp); - } - - public static void setFont(Font newFont) { - font = newFont; - } - @Override public ViewFactory getViewFactory() { return this; @@ -69,59 +66,7 @@ public ViewFactory getViewFactory() { @Override public View create(Element element) { - return new SyntaxView(element); - } - - @Override - public void install(JEditorPane editorPane) { - super.install(editorPane); - - if (font == null) { - font = SyntaxpainConfiguration.getEditorFont(); - } - - editorPane.setFont(font); - - Color caretColor = SyntaxpainConfiguration.getTextColor(); - editorPane.setCaretColor(caretColor); - - if (SyntaxpainConfiguration.isQuickFindDialogEnabled()) { - this.addQuickFindDialogAction(editorPane); - } - - this.addComponents(editorPane); - } - - @Override - public void deinstall(JEditorPane editorPane) { - for (SyntaxComponent c : this.editorComponents.get(editorPane)) { - c.deinstall(editorPane); - } - - this.editorComponents.clear(); - editorPane.getInputMap().clear(); - ActionMap m = editorPane.getActionMap(); - m.clear(); - } - - /** - * Sets up the quick find action. - */ - public void addQuickFindDialogAction(JEditorPane editorPane) { - InputMap inputMap = new InputMap(); - inputMap.setParent(editorPane.getInputMap()); - ActionMap actionMap = new ActionMap(); - actionMap.setParent(editorPane.getActionMap()); - - QuickFindDialogAction action = new QuickFindDialogAction(); - actionMap.put(action.getClass().getSimpleName(), action); - - KeyStroke stroke = KeyStroke.getKeyStroke("control F"); - action.putValue(Action.ACCELERATOR_KEY, stroke); - inputMap.put(stroke, action.getClass().getSimpleName()); - - editorPane.setActionMap(actionMap); - editorPane.setInputMap(JTextComponent.WHEN_FOCUSED, inputMap); + return new SyntaxView(element, styles); } @Override @@ -131,6 +76,6 @@ public Document createDefaultDocument() { @Override public String getContentType() { - return "text/enigma-sources"; + return CONTENT_TYPE; } } diff --git a/src/main/java/org/quiltmc/syntaxpain/LineNumbersRuler.java b/src/main/java/org/quiltmc/syntaxpain/LineNumbersRuler.java index d5a762d..cf1f731 100644 --- a/src/main/java/org/quiltmc/syntaxpain/LineNumbersRuler.java +++ b/src/main/java/org/quiltmc/syntaxpain/LineNumbersRuler.java @@ -15,7 +15,6 @@ package org.quiltmc.syntaxpain; -import javax.swing.BorderFactory; import javax.swing.JEditorPane; import javax.swing.JPanel; import javax.swing.JScrollPane; @@ -24,7 +23,6 @@ import javax.swing.event.CaretListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; -import javax.swing.text.BadLocationException; import javax.swing.text.Element; import javax.swing.text.JTextComponent; import java.awt.Color; @@ -39,6 +37,8 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import static javax.swing.BorderFactory.createEmptyBorder; + /** * This class will display line numbers for a related text component. The text * component must use the same line height for each line. @@ -50,27 +50,57 @@ * * @author Ayman Al-Sairafi, Hanns Holger Rutz */ -public class LineNumbersRuler extends JPanel implements CaretListener, DocumentListener, PropertyChangeListener, SyntaxComponent { - private Status status; - private static final int MAX_HEIGHT = 0x100000; // issue #36 - avoid overflow on HiDPI monitors - // Text component this TextTextLineNumber component is in sync with - private JEditorPane editor; +public class LineNumbersRuler extends JPanel implements CaretListener, DocumentListener, PropertyChangeListener { + // issue #36 - avoid overflow on HiDPI monitors + private static final int MAX_HEIGHT = 0x100000; private static final int MINIMUM_DISPLAY_DIGITS = 2; - // Keep history information to reduce the number of times the component - // needs to be repainted - private int lastDigits; - private int lastHeight; - private int lastLine; - // The formatting to use for displaying numbers. Use in String.format(numbersFormat, line) - private String numbersFormat = "%3d"; - private Color currentLineColor; + public static R install(R ruler) { + ruler.editor.getDocument().addDocumentListener(ruler); + ruler.editor.addCaretListener(ruler); + ruler.editor.addPropertyChangeListener(ruler); + final JScrollPane scrollPane = getScrollPane(ruler.editor); + if (scrollPane != null) { + scrollPane.setRowHeaderView(ruler); + } + + return ruler; + } + + /** + * Gets the Line Number at the give position of the editor component. + * The first line number is ZERO + * + * @return line number + */ + public static int getLineNumber(JTextComponent editor, int pos) { + final SyntaxDocument doc = SyntaxDocument.getFrom(editor); + if (doc != null) { + return doc.getLineNumberAt(pos); + } else { + return editor.getDocument().getDefaultRootElement().getElementIndex(pos); + } + } + + public static int getLineCount(JTextComponent pane) { + final SyntaxDocument doc = SyntaxDocument.getFrom(pane); + if (doc != null) { + return doc.getLineCount(); + } + + int count = 0; + int p = pane.getDocument().getLength() - 1; + if (p > 0) { + count = getLineNumber(pane, p); + } + + return count; + } /** - * Returns the JScrollPane that contains this EditorPane, or null if no - * JScrollPane is the parent of this editor + * @return the {@link JScrollPane} of the {@link JEditorPane}, or null if there is no {@link JScrollPane} parent */ - public JScrollPane getScrollPane(JTextComponent editorPane) { + private static JScrollPane getScrollPane(JEditorPane editorPane) { Container p = editorPane.getParent(); while (p != null) { if (p instanceof JScrollPane) { @@ -83,55 +113,41 @@ public JScrollPane getScrollPane(JTextComponent editorPane) { return null; } - @Override - public void configure() { - Color foreground = SyntaxpainConfiguration.getLineRulerPrimaryColor(); - this.setForeground(foreground); - Color back = SyntaxpainConfiguration.getLineRulerSecondaryColor(); - this.setBackground(back); - this.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); - this.currentLineColor = SyntaxpainConfiguration.getLineRulerSelectionColor(); - } + // Text component this TextTextLineNumber component is in sync with + protected final JEditorPane editor; + protected final Color currentLineColor; + protected final int lineOffset; - @Override - public void install(final JEditorPane editor) { - this.editor = editor; + // Keep history information to reduce the number of times the component + // needs to be repainted + private int lastDigits; + private int lastHeight; + private int lastLine; + // The formatting to use for displaying numbers. Use in String.format(numbersFormat, line) + private String numbersFormat = "%3d"; - this.setFont(editor.getFont()); + public LineNumbersRuler(JEditorPane editor, Color currentLineColor) { + this(editor, currentLineColor, 0); + } - Insets ein = editor.getInsets(); - if (ein.top != 0 || ein.bottom != 0) { - Insets curr = this.getInsets(); - this.setBorder(BorderFactory.createEmptyBorder(ein.top, curr.left, ein.bottom, curr.right)); - } + public LineNumbersRuler(JEditorPane editor, Color currentLineColor, int lineOffset) { + this.editor = editor; + this.currentLineColor = currentLineColor; + this.lineOffset = lineOffset; - editor.getDocument().addDocumentListener(this); - editor.addCaretListener(this); - editor.addPropertyChangeListener(this); - JScrollPane sp = this.getScrollPane(editor); - if (sp != null) sp.setRowHeaderView(this); - this.setPreferredWidth(false); // required for toggle-lines to correctly repaint - this.status = Status.INSTALLING; - } + final Insets editorInsets = this.editor.getInsets(); + this.setBorder(createEmptyBorder(editorInsets.top, 5, editorInsets.bottom, 5)); - @Override - public void deinstall(JEditorPane editor) { - this.status = Status.DEINSTALLING; - editor.getDocument().removeDocumentListener(this); - editor.removeCaretListener(this); - editor.removePropertyChangeListener(this); - JScrollPane sp = this.getScrollPane(editor); - if (sp != null) { - sp.setRowHeaderView(null); - } + // required for toggle-lines to correctly repaint + this.setPreferredWidth(false); } /** * Calculate the width needed to display the maximum line number */ private void setPreferredWidth(boolean force) { - int lines = Util.getLineCount(this.editor); - int digits = Math.max(String.valueOf(lines).length(), MINIMUM_DISPLAY_DIGITS); + int lines = getLineCount(this.editor); + int digits = Math.max(String.valueOf(lines + this.lineOffset).length(), MINIMUM_DISPLAY_DIGITS); // Update sizes when number of digits in the line number changes @@ -157,35 +173,29 @@ private void setPreferredWidth(boolean force) { public void paintComponent(Graphics g) { super.paintComponent(g); - FontMetrics fontMetrics = this.getFontMetrics(this.getFont()); - Insets insets = this.getInsets(); - int currentLine = -1; - try { - currentLine = Util.getLineNumber(this.editor, this.editor.getCaretPosition()); - } catch (BadLocationException ex) { - // this won't happen, even if it does, we can ignore it and we will not have - // a current line to worry about... - } + final FontMetrics fontMetrics = this.getFontMetrics(this.getFont()); + final Insets insets = this.getInsets(); + final int currentLine = getLineNumber(this.editor, this.editor.getCaretPosition()); - int lh = fontMetrics.getHeight(); - int maxLines = Util.getLineCount(this.editor); + final int lineHeight = fontMetrics.getHeight(); + final int maxLines = getLineCount(this.editor); SyntaxView.setRenderingHits((Graphics2D) g); - Rectangle clip = g.getClip().getBounds(); - int topLine = (int) (clip.getY() / lh); - int bottomLine = Math.min(maxLines, (int) (clip.getHeight() + lh - 1) / lh + topLine + 1); + final Rectangle clip = g.getClip().getBounds(); + final int topLine = (int) (clip.getY() / lineHeight); + final int bottomLine = Math.min(maxLines, (int) (clip.getHeight() + lineHeight - 1) / lineHeight + topLine + 1); for (int line = topLine; line < bottomLine; line++) { - String lineNumber = String.format(this.numbersFormat, line + 1); - int y = line * lh + insets.top; - int yt = y + fontMetrics.getAscent(); + final String lineNumber = String.format(this.numbersFormat, line + 1 + this.lineOffset); + final int top = line * lineHeight + insets.top; + final int stringBottom = top + fontMetrics.getAscent(); if (line == currentLine) { g.setColor(this.currentLineColor); - g.fillRect(0, y, this.getWidth(), lh); + g.fillRect(0, top, this.getWidth(), lineHeight); g.setColor(this.getForeground()); - g.drawString(lineNumber, insets.left, yt); + g.drawString(lineNumber, insets.left, stringBottom); } else { - g.drawString(lineNumber, insets.left, yt); + g.drawString(lineNumber, insets.left, stringBottom); } } } @@ -244,20 +254,7 @@ private void documentChanged() { */ @Override public void propertyChange(PropertyChangeEvent evt) { - String prop = evt.getPropertyName(); - if (prop.equals("document")) { - if (evt.getOldValue() instanceof SyntaxDocument) { - SyntaxDocument syntaxDocument = (SyntaxDocument) evt.getOldValue(); - syntaxDocument.removeDocumentListener(this); - } - - if (evt.getNewValue() instanceof SyntaxDocument && this.status.equals(Status.INSTALLING)) { - SyntaxDocument syntaxDocument = (SyntaxDocument) evt.getNewValue(); - syntaxDocument.addDocumentListener(this); - this.setPreferredWidth(false); - this.repaint(); - } - } else if (prop.equals("font") && evt.getNewValue() instanceof Font) { + if (evt.getPropertyName().equals("font") && evt.getNewValue() instanceof Font) { this.setFont((Font) evt.getNewValue()); this.setPreferredWidth(true); } diff --git a/src/main/java/org/quiltmc/syntaxpain/Markers.java b/src/main/java/org/quiltmc/syntaxpain/Markers.java deleted file mode 100644 index b27aba1..0000000 --- a/src/main/java/org/quiltmc/syntaxpain/Markers.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com - * Copyright 2011-2022 Hanns Holger Rutz. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License - * at http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.quiltmc.syntaxpain; - -import javax.swing.text.BadLocationException; -import javax.swing.text.DefaultHighlighter; -import javax.swing.text.Highlighter; -import javax.swing.text.JTextComponent; -import java.awt.Color; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This class contains static utility methods to make highlighting in text - * components easier. - * - * @author Ayman Al-Sairafi, Hanns Holger Rutz - */ -public class Markers { - // This subclass is used in our highlighting code - public static class SimpleMarker extends DefaultHighlighter.DefaultHighlightPainter { - public SimpleMarker(Color color) { - super(color); - } - } - - /** - * Removes only our private highlights - * This is public so that we can remove the highlights when the editorKit - * is unregistered. SimpleMarker can be null, in which case all instances of - * our Markers are removed. - * @param component the text component whose markers are to be removed - * @param marker the SimpleMarker to remove - */ - public static void removeMarkers(JTextComponent component, SimpleMarker marker) { - Highlighter hilite = component.getHighlighter(); - Highlighter.Highlight[] hilites = hilite.getHighlights(); - - for (Highlighter.Highlight highlight : hilites) { - if (highlight.getPainter() instanceof SimpleMarker hMarker) { - if (marker == null || hMarker.equals(marker)) { - hilite.removeHighlight(highlight); - } - } - } - } - - /** - * Adds highlights for the given Token on the given pane - */ - public static void markToken(JTextComponent pane, Token token, SimpleMarker marker) { - markText(pane, token.start, token.end(), marker); - } - - /** - * Adds highlights for the given region on the given pane - */ - public static void markText(JTextComponent pane, int start, int end, SimpleMarker marker) { - try { - Highlighter highlighter = pane.getHighlighter(); - int selStart = pane.getSelectionStart(); - int selEnd = pane.getSelectionEnd(); - // if there is no selection or selection does not overlap - if (selStart == selEnd || end < selStart || start > selStart) { - highlighter.addHighlight(start, end, marker); - return; - } - - // selection starts within the highlight, highlight before selection - if (selStart > start && selStart < end) { - highlighter.addHighlight(start, selStart, marker); - } - - // selection ends within the highlight, highlight remaining - if (selEnd > start && selEnd < end) { - highlighter.addHighlight(selEnd, end, marker); - } - } catch (BadLocationException ex) { - // nothing we can do if the request is out of bound - LOG.log(Level.SEVERE, null, ex); - } - } - - private static final Logger LOG = Logger.getLogger(Markers.class.getName()); -} diff --git a/src/main/java/org/quiltmc/syntaxpain/PairsMarker.java b/src/main/java/org/quiltmc/syntaxpain/PairsMarker.java index 361ceb7..78059d4 100644 --- a/src/main/java/org/quiltmc/syntaxpain/PairsMarker.java +++ b/src/main/java/org/quiltmc/syntaxpain/PairsMarker.java @@ -14,13 +14,10 @@ package org.quiltmc.syntaxpain; -import javax.swing.JEditorPane; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.text.JTextComponent; import java.awt.Color; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; /** * This class highlights any pairs of the given language. Pairs are defined @@ -28,25 +25,34 @@ * * @author Ayman Al-Sairafi */ -public class PairsMarker implements CaretListener, SyntaxComponent, PropertyChangeListener { - private JTextComponent pane; - private Markers.SimpleMarker marker; - private Status status; +public class PairsMarker implements CaretListener { + public static M install(M marker) { + marker.pane.addCaretListener(marker); - public PairsMarker() { + return marker; + } + + protected final JTextComponent pane; + protected final SimpleMarker marker; + + public PairsMarker(JTextComponent pane, Color color) { + this.pane = pane; + this.marker = new SimpleMarker(color); } @Override public void caretUpdate(CaretEvent e) { this.removeMarkers(); int pos = e.getDot(); - SyntaxDocument doc = Util.getSyntaxDocument(this.pane); - Token token = doc.getTokenAt(pos); - if (token != null && token.pairValue != 0) { - Markers.markToken(this.pane, token, this.marker); - Token other = doc.getPairFor(token); - if (other != null) { - Markers.markToken(this.pane, other, this.marker); + SyntaxDocument doc = SyntaxDocument.getFrom(this.pane); + if (doc != null) { + Token token = doc.getTokenAt(pos); + if (token != null && token.pairValue != 0) { + this.marker.markToken(this.pane, token); + Token other = doc.getPairFor(token); + if (other != null) { + this.marker.markToken(this.pane, other); + } } } } @@ -56,37 +62,6 @@ public void caretUpdate(CaretEvent e) { * when the editor-kit is removed. */ public void removeMarkers() { - Markers.removeMarkers(this.pane, this.marker); - } - - @Override - public void configure() { - Color markerColor = new Color(0xffbb77); - this.marker = new Markers.SimpleMarker(markerColor); - } - - @Override - public void install(JEditorPane editor) { - this.pane = editor; - this.pane.addCaretListener(this); - this.status = Status.INSTALLING; - } - - @Override - public void deinstall(JEditorPane editor) { - this.status = Status.DEINSTALLING; - this.pane.removeCaretListener(this); - this.removeMarkers(); - } - - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (evt.getPropertyName().equals("document")) { - this.pane.removeCaretListener(this); - if (this.status.equals(Status.INSTALLING)) { - this.pane.addCaretListener(this); - this.removeMarkers(); - } - } + this.marker.removeMarkers(this.pane); } } diff --git a/src/main/java/org/quiltmc/syntaxpain/QuickFindDialog.java b/src/main/java/org/quiltmc/syntaxpain/QuickFindDialog.java deleted file mode 100644 index 1b15efe..0000000 --- a/src/main/java/org/quiltmc/syntaxpain/QuickFindDialog.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.quiltmc.syntaxpain; - -import javax.swing.GroupLayout; -import javax.swing.JDialog; -import javax.swing.SwingUtilities; -import javax.swing.WindowConstants; -import javax.swing.text.JTextComponent; -import java.awt.Color; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Point; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.util.function.Function; - -/** - * A dialog containing a {@link QuickFindToolBar}. - * - * @see SyntaxpainConfiguration#setQuickFindDialogFactory(Function) - */ -public class QuickFindDialog extends JDialog implements EscapeListener { - protected static final int PREFERRED_TOOLBAR_WIDTH = 684; - - protected QuickFindToolBar quickFindToolBar; - - public QuickFindDialog(JTextComponent target) { - super(SwingUtilities.getWindowAncestor(target), ModalityType.MODELESS); - - this.quickFindToolBar = new QuickFindToolBar(); - this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - this.setBackground(Color.DARK_GRAY); - this.setResizable(false); - this.setUndecorated(true); - - GroupLayout layout = new GroupLayout(this.getContentPane()); - this.getContentPane().setLayout(layout); - layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(this.quickFindToolBar, GroupLayout.DEFAULT_SIZE, PREFERRED_TOOLBAR_WIDTH, Short.MAX_VALUE)); - layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(this.quickFindToolBar, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)); - - final String simpleName = this.getClass().getSimpleName(); - this.setName(simpleName.isEmpty() ? QuickFindDialog.class.getSimpleName() : simpleName); - - Util.addEscapeListener(this); - } - - public void showFor(JTextComponent target) { - Container view = target.getParent(); - Dimension size = this.getSize(); - - // Set the width of the dialog to the width of the target - size.width = target.getVisibleRect().width; - this.setSize(size); - - // Put the dialog at the bottom of the target - Point loc = new Point(0, view.getHeight() - size.height); - this.setLocationRelativeTo(view); - SwingUtilities.convertPointToScreen(loc, view); - this.setLocation(loc); - - // Close the dialog when clicking outside it - this.addWindowFocusListener(new WindowAdapter() { - @Override - public void windowLostFocus(WindowEvent e) { - QuickFindDialog.this.removeWindowListener(this); - QuickFindDialog.this.setVisible(false); - } - }); - - this.quickFindToolBar.showFor(target); - - this.setVisible(true); - } - - @Override - public void escapePressed() { - this.setVisible(false); - } -} diff --git a/src/main/java/org/quiltmc/syntaxpain/QuickFindDialogAction.java b/src/main/java/org/quiltmc/syntaxpain/QuickFindDialogAction.java deleted file mode 100644 index 5cc34cb..0000000 --- a/src/main/java/org/quiltmc/syntaxpain/QuickFindDialogAction.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.quiltmc.syntaxpain; - -import javax.swing.text.JTextComponent; -import java.awt.event.ActionEvent; - -public final class QuickFindDialogAction extends DefaultSyntaxAction { - public QuickFindDialogAction() { - super("quick-find-dialog"); - } - - @Override - public void actionPerformed(JTextComponent target, SyntaxDocument document, int dot, ActionEvent event) { - Data data = Data.get(target); - data.showFindDialog(target); - } - - private static class Data { - private static final String KEY = "enigma-find-data"; - private QuickFindDialog findDialog; - - private Data() { - } - - public static Data get(JTextComponent target) { - Object o = target.getDocument().getProperty(KEY); - if (o instanceof Data) { - return (Data) o; - } - - Data data = new Data(); - target.getDocument().putProperty(KEY, data); - return data; - } - - public void showFindDialog(JTextComponent target) { - if (SyntaxpainConfiguration.isQuickFindDialogEnabled()) { - if (this.findDialog == null) { - this.findDialog = SyntaxpainConfiguration.getQuickFindDialog(target); - } - - this.findDialog.showFor(target); - } - } - } -} diff --git a/src/main/java/org/quiltmc/syntaxpain/QuickFindToolBar.java b/src/main/java/org/quiltmc/syntaxpain/QuickFindToolBar.java index 82269c8..790d837 100644 --- a/src/main/java/org/quiltmc/syntaxpain/QuickFindToolBar.java +++ b/src/main/java/org/quiltmc/syntaxpain/QuickFindToolBar.java @@ -31,16 +31,14 @@ /** * A toolbar used to find instances of specific strings in a {@link JTextComponent}. * Designed to be extensible. - * - * @see QuickFindDialog */ +@SuppressWarnings("unused") public class QuickFindToolBar extends JToolBar implements DocumentListener, ActionListener { protected static final int SEARCH_FIELD_MAX_WIDTH = 200; protected static final int SEARCH_FIELD_MAX_HEIGHT = 24; protected static final int SEARCH_FIELD_MIN_WIDTH = 60; private static final int SEARCH_FIELD_MIN_HEIGHT = 24; - protected final Markers.SimpleMarker marker = new Markers.SimpleMarker(Color.PINK); protected WeakReference target = new WeakReference<>(null); protected WeakReference searchData = new WeakReference<>(null); protected int prevCaretPos; @@ -196,7 +194,6 @@ protected void dismiss() { this.setVisible(false); final JTextComponent target = this.target.get(); if (target != null) { - Markers.removeMarkers(target, this.marker); target.requestFocus(); } } diff --git a/src/main/java/org/quiltmc/syntaxpain/SimpleMarker.java b/src/main/java/org/quiltmc/syntaxpain/SimpleMarker.java new file mode 100644 index 0000000..3f5a43d --- /dev/null +++ b/src/main/java/org/quiltmc/syntaxpain/SimpleMarker.java @@ -0,0 +1,75 @@ +package org.quiltmc.syntaxpain; + +import javax.swing.text.BadLocationException; +import javax.swing.text.DefaultHighlighter; +import javax.swing.text.Highlighter; +import javax.swing.text.JTextComponent; +import java.awt.Color; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * @author Ayman Al-Sairafi, Hanns Holger Rutz + */ +public class SimpleMarker extends DefaultHighlighter.DefaultHighlightPainter { + public SimpleMarker(Color color) { + super(color); + } + + /** + * Removes only our private highlights + * This is public so that we can remove the highlights when the editorKit + * is unregistered. SimpleMarker can be null, in which case all instances of + * our Markers are removed. + * + * @param component the text component whose markers are to be removed + */ + public void removeMarkers(JTextComponent component) { + Highlighter hilite = component.getHighlighter(); + Highlighter.Highlight[] hilites = hilite.getHighlights(); + + for (Highlighter.Highlight highlight : hilites) { + if (this.equals(highlight.getPainter())) { + hilite.removeHighlight(highlight); + } + } + } + + /** + * Adds highlights for the given Token on the given pane + */ + public void markToken(JTextComponent pane, Token token) { + this.markText(pane, token.start, token.end()); + } + + /** + * Adds highlights for the given region on the given pane + */ + public void markText(JTextComponent pane, int start, int end) { + try { + Highlighter highlighter = pane.getHighlighter(); + int selStart = pane.getSelectionStart(); + int selEnd = pane.getSelectionEnd(); + // if there is no selection or selection does not overlap + if (selStart == selEnd || end < selStart || start > selStart) { + highlighter.addHighlight(start, end, this); + return; + } + + // selection starts within the highlight, highlight before selection + if (selStart > start && selStart < end) { + highlighter.addHighlight(start, selStart, this); + } + + // selection ends within the highlight, highlight remaining + if (selEnd > start && selEnd < end) { + highlighter.addHighlight(selEnd, end, this); + } + } catch (BadLocationException ex) { + // nothing we can do if the request is out of bound + LOG.log(Level.SEVERE, null, ex); + } + } + + private static final Logger LOG = Logger.getLogger(SimpleMarker.class.getName()); +} diff --git a/src/main/java/org/quiltmc/syntaxpain/SyntaxComponent.java b/src/main/java/org/quiltmc/syntaxpain/SyntaxComponent.java deleted file mode 100644 index 518ec23..0000000 --- a/src/main/java/org/quiltmc/syntaxpain/SyntaxComponent.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License - * at http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.quiltmc.syntaxpain; - -import javax.swing.JEditorPane; - -/** - * A Component that is installed to the EditorKit to perform GUI operations - * on the Editor. - * - * @author Ayman Al-Sairafi - */ -public interface SyntaxComponent { - /** - * Configure the component using the given properties. The keys - * needed for configuration will be prefixed by the given prefix - */ - void configure(); - - /** - * Called to install the component on an editor - */ - void install(JEditorPane editor); - - /** - * Called when the component is to be removed from the editor - */ - void deinstall(JEditorPane editor); - - /** - * The status is used to have proper propertyChange support. We need to know if we are INSTALLING - * the component or DE-INSTALLING it - */ - enum Status { - INSTALLING, - DEINSTALLING - } -} diff --git a/src/main/java/org/quiltmc/syntaxpain/SyntaxDocument.java b/src/main/java/org/quiltmc/syntaxpain/SyntaxDocument.java index c1cb41e..11fa002 100644 --- a/src/main/java/org/quiltmc/syntaxpain/SyntaxDocument.java +++ b/src/main/java/org/quiltmc/syntaxpain/SyntaxDocument.java @@ -26,7 +26,9 @@ import java.util.regex.Pattern; import javax.swing.event.DocumentEvent; import javax.swing.text.BadLocationException; +import javax.swing.text.Document; import javax.swing.text.Element; +import javax.swing.text.JTextComponent; import javax.swing.text.PlainDocument; import javax.swing.text.Segment; @@ -38,6 +40,24 @@ * @author Ayman Al-Sairafi, Hanns Holger Rutz */ public class SyntaxDocument extends PlainDocument { + /** + * A helper function that will return the SyntaxDocument attached to the + * given text component. Return null if the document is not a + * SyntaxDocument, or if the text component is null + */ + public static SyntaxDocument getFrom(JTextComponent component) { + if (component == null) { + return null; + } + + Document doc = component.getDocument(); + if (doc instanceof SyntaxDocument) { + return (SyntaxDocument) doc; + } else { + return null; + } + } + private final Lexer lexer; private List tokens; diff --git a/src/main/java/org/quiltmc/syntaxpain/SyntaxStyle.java b/src/main/java/org/quiltmc/syntaxpain/SyntaxStyle.java index fdb4d6d..deae634 100644 --- a/src/main/java/org/quiltmc/syntaxpain/SyntaxStyle.java +++ b/src/main/java/org/quiltmc/syntaxpain/SyntaxStyle.java @@ -16,11 +16,8 @@ package org.quiltmc.syntaxpain; import java.awt.Color; -import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; -import java.util.HashMap; -import java.util.Map; import javax.swing.text.Segment; import javax.swing.text.TabExpander; import javax.swing.text.Utilities; @@ -32,46 +29,6 @@ * @author Ayman Al-Sairafi, Hanns Holger Rutz */ public record SyntaxStyle(Color color, int fontStyle) { - private static final Map styles = new HashMap<>(); - - static { - styles.put(TokenType.KEYWORD, new SyntaxStyle(SyntaxpainConfiguration.getHighlightColor(), Font.PLAIN)); - styles.put(TokenType.KEYWORD2, new SyntaxStyle(SyntaxpainConfiguration.getHighlightColor(), Font.BOLD + Font.ITALIC)); - styles.put(TokenType.STRING, new SyntaxStyle(SyntaxpainConfiguration.getStringColor(), Font.PLAIN)); - styles.put(TokenType.STRING2, new SyntaxStyle(SyntaxpainConfiguration.getStringColor(), Font.BOLD)); - styles.put(TokenType.NUMBER, new SyntaxStyle(SyntaxpainConfiguration.getNumberColor(), Font.PLAIN)); - styles.put(TokenType.OPERATOR, new SyntaxStyle(SyntaxpainConfiguration.getOperatorColor(), Font.PLAIN)); - styles.put(TokenType.DELIMITER, new SyntaxStyle(SyntaxpainConfiguration.getDelimiterColor(), Font.BOLD)); - styles.put(TokenType.TYPE, new SyntaxStyle(SyntaxpainConfiguration.getTypeColor(), Font.ITALIC)); - styles.put(TokenType.TYPE2, new SyntaxStyle(SyntaxpainConfiguration.getTypeColor(), Font.BOLD)); - styles.put(TokenType.TYPE3, new SyntaxStyle(SyntaxpainConfiguration.getTypeColor(), Font.BOLD + Font.ITALIC)); - styles.put(TokenType.IDENTIFIER, new SyntaxStyle(SyntaxpainConfiguration.getIdentifierColor(), Font.PLAIN)); - styles.put(TokenType.COMMENT, new SyntaxStyle(SyntaxpainConfiguration.getCommentColour(), Font.ITALIC)); - styles.put(TokenType.COMMENT2, new SyntaxStyle(SyntaxpainConfiguration.getCommentColour(), Font.BOLD + Font.ITALIC)); - styles.put(TokenType.DEFAULT, new SyntaxStyle(SyntaxpainConfiguration.getTextColor(), Font.PLAIN)); - styles.put(TokenType.WARNING, new SyntaxStyle(SyntaxpainConfiguration.getTextColor(), Font.PLAIN)); - styles.put(TokenType.ERROR, new SyntaxStyle(SyntaxpainConfiguration.getTextColor(), Font.BOLD + Font.ITALIC)); - styles.put(TokenType.REGEX, new SyntaxStyle(SyntaxpainConfiguration.getRegexColor(), Font.PLAIN)); - styles.put(TokenType.REGEX2, new SyntaxStyle(SyntaxpainConfiguration.getRegexColor(), Font.BOLD)); - } - - /** - * Returns the style for the given TokenType - */ - public static SyntaxStyle getStyle(TokenType type) { - return styles.get(type); - } - - /** - * Draws the given Token. This will simply find the proper SyntaxStyle for - * the TokenType and then asks the proper Style to draw the text of the - * Token. - */ - public static float drawText(Segment segment, float x, float y, Graphics2D graphics, TabExpander e, Token token) { - SyntaxStyle s = getStyle(token.type); - return s.drawText(segment, x, y, graphics, e, token.start); - } - /** * Draw text. This can directly call the Utilities.drawTabbedText. * Subclasses can override this method to provide any other decorations. diff --git a/src/main/java/org/quiltmc/syntaxpain/SyntaxStyleMap.java b/src/main/java/org/quiltmc/syntaxpain/SyntaxStyleMap.java new file mode 100644 index 0000000..485a42e --- /dev/null +++ b/src/main/java/org/quiltmc/syntaxpain/SyntaxStyleMap.java @@ -0,0 +1,56 @@ +package org.quiltmc.syntaxpain; + +import javax.swing.text.Segment; +import javax.swing.text.TabExpander; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.util.Map; + +public class SyntaxStyleMap { + private final Map styles; + + public SyntaxStyleMap( + Color highlight, Color string, Color number, Color operator, Color delimiter, + Color type, Color identifier, Color comment, Color text, Color regex + ) { + this.styles = Map.ofEntries( + Map.entry(TokenType.KEYWORD, new SyntaxStyle(highlight, Font.PLAIN)), + Map.entry(TokenType.KEYWORD2, new SyntaxStyle(highlight, Font.BOLD + Font.ITALIC)), + Map.entry(TokenType.STRING, new SyntaxStyle(string, Font.PLAIN)), + Map.entry(TokenType.STRING2, new SyntaxStyle(string, Font.BOLD)), + Map.entry(TokenType.NUMBER, new SyntaxStyle(number, Font.PLAIN)), + Map.entry(TokenType.OPERATOR, new SyntaxStyle(operator, Font.PLAIN)), + Map.entry(TokenType.DELIMITER, new SyntaxStyle(delimiter, Font.BOLD)), + Map.entry(TokenType.TYPE, new SyntaxStyle(type, Font.ITALIC)), + Map.entry(TokenType.TYPE2, new SyntaxStyle(type, Font.BOLD)), + Map.entry(TokenType.TYPE3, new SyntaxStyle(type, Font.BOLD + Font.ITALIC)), + Map.entry(TokenType.IDENTIFIER, new SyntaxStyle(identifier, Font.PLAIN)), + Map.entry(TokenType.COMMENT, new SyntaxStyle(comment, Font.ITALIC)), + Map.entry(TokenType.COMMENT2, new SyntaxStyle(comment, Font.BOLD + Font.ITALIC)), + Map.entry(TokenType.DEFAULT, new SyntaxStyle(text, Font.PLAIN)), + Map.entry(TokenType.WARNING, new SyntaxStyle(text, Font.PLAIN)), + Map.entry(TokenType.ERROR, new SyntaxStyle(text, Font.BOLD + Font.ITALIC)), + Map.entry(TokenType.REGEX, new SyntaxStyle(regex, Font.PLAIN)), + Map.entry(TokenType.REGEX2, new SyntaxStyle(regex, Font.BOLD)) + ); + } + + public SyntaxStyle getStyle(TokenType type) { + return this.styles.get(type); + } + + /** + * Draws the given Token. This will simply find the proper SyntaxStyle for + * the TokenType and then asks the proper Style to draw the text of the Token. + */ + public float drawText(Segment segment, float x, float y, Graphics2D graphics, TabExpander e, Token token) { + return this.drawText(token.type, segment, x, y, graphics, e, token.start); + } + + public float drawText( + TokenType type, Segment segment, float x, float y, Graphics2D graphics, TabExpander e, int startOffset + ) { + return this.getStyle(type).drawText(segment, x, y, graphics, e, startOffset); + } +} diff --git a/src/main/java/org/quiltmc/syntaxpain/SyntaxView.java b/src/main/java/org/quiltmc/syntaxpain/SyntaxView.java index b7be425..62d50e7 100644 --- a/src/main/java/org/quiltmc/syntaxpain/SyntaxView.java +++ b/src/main/java/org/quiltmc/syntaxpain/SyntaxView.java @@ -34,22 +34,11 @@ public class SyntaxView extends PlainView { private static final Logger log = Logger.getLogger(SyntaxView.class.getName()); - private int rightMarginColumn; - private Color rightMarginColor; - private SyntaxStyle defaultStyle; + private final SyntaxStyleMap styles; - /** - * Construct a new view using the given configuration and prefix given - */ - public SyntaxView(Element element) { + public SyntaxView(Element element, SyntaxStyleMap styles) { super(element); - this.configure(); - } - - private void configure() { - this.rightMarginColor = new Color(0xFF7777); - this.rightMarginColumn = 0; - this.defaultStyle = SyntaxStyle.getStyle(TokenType.DEFAULT); + this.styles = styles; } @Override @@ -59,14 +48,6 @@ protected float drawUnselectedText(Graphics2D graphics, float x, float y, int p0 Color saveColor = graphics.getColor(); SyntaxDocument doc = (SyntaxDocument) this.getDocument(); Segment segment = this.getLineBuffer(); - // Draw the right margin first, if needed. This way the text overlays - // the margin - if (this.rightMarginColumn > 0) { - int m_x = this.rightMarginColumn * graphics.getFontMetrics().charWidth('m'); - int h = graphics.getFontMetrics().getHeight(); - graphics.setColor(this.rightMarginColor); - graphics.drawLine(m_x, (int) y, m_x, (int) y - h); - } try { // Colour the parts @@ -79,7 +60,7 @@ protected float drawUnselectedText(Graphics2D graphics, float x, float y, int p0 // it in the default type if (start < t.start) { doc.getText(start, t.start - start, segment); - x = this.defaultStyle.drawText(segment, (int) x, (int) y, graphics, this, start); + x = this.styles.drawText(TokenType.DEFAULT, segment, (int) x, (int) y, graphics, this, start); } // t and s are the actual start and length of what we should @@ -100,14 +81,14 @@ protected float drawUnselectedText(Graphics2D graphics, float x, float y, int p0 } doc.getText(s, l, segment); - x = SyntaxStyle.drawText(segment, x, y, graphics, this, t); + x = this.styles.drawText(segment, x, y, graphics, this, t); start = t.end(); } // now for any remaining text not tokenized: if (start < p1) { doc.getText(start, p1 - start, segment); - x = this.defaultStyle.drawText(segment, x, y, graphics, this, start); + x = this.styles.drawText(TokenType.DEFAULT, segment, x, y, graphics, this, start); } } catch (BadLocationException ex) { log.log(Level.SEVERE, "Requested: " + ex.offsetRequested(), ex); @@ -121,13 +102,6 @@ protected float drawUnselectedText(Graphics2D graphics, float x, float y, int p0 @Override protected float drawSelectedText(Graphics2D graphics, float x, float y, int p0, int p1) throws BadLocationException { - if (this.rightMarginColumn > 0) { - int m_x = this.rightMarginColumn * graphics.getFontMetrics().charWidth('m'); - int h = graphics.getFontMetrics().getHeight(); - graphics.setColor(this.rightMarginColor); - graphics.drawLine(m_x, (int) y, m_x, (int) (y - h)); - } - return super.drawSelectedText(graphics, x, y, p0, p1); } diff --git a/src/main/java/org/quiltmc/syntaxpain/SyntaxpainConfiguration.java b/src/main/java/org/quiltmc/syntaxpain/SyntaxpainConfiguration.java deleted file mode 100644 index 9d1f522..0000000 --- a/src/main/java/org/quiltmc/syntaxpain/SyntaxpainConfiguration.java +++ /dev/null @@ -1,166 +0,0 @@ -package org.quiltmc.syntaxpain; - -import javax.swing.JEditorPane; -import javax.swing.text.JTextComponent; -import java.awt.Color; -import java.awt.Font; -import java.util.function.Function; - -@SuppressWarnings("unused") -public class SyntaxpainConfiguration { - private static Color highlightColor = new Color(0x3333EE); - private static Color stringColor = new Color(0xCC6600); - private static Color numberColor = new Color(0x999933); - private static Color operatorColor = new Color(0x000000); - private static Color delimiterColor = new Color(0x000000); - private static Color typeColor = new Color(0x000000); - private static Color identifierColor = new Color(0x000000); - private static Color commentColour = new Color(0x339933); - private static Color textColor = new Color(0x000000); - private static Color regexColor = new Color(0xcc6600); - - private static Color lineRulerPrimaryColor = new Color(0x333300); - private static Color lineRulerSecondaryColor = new Color(0xEEEEFF); - private static Color lineRulerSelectionColor = new Color(0xCCCCEE); - - private static Font editorFont = Font.decode(Font.DIALOG); - private static Function quickFindDialogFactory = QuickFindDialog::new; - - public static Color getHighlightColor() { - return highlightColor; - } - - public static void setHighlightColor(Color highlightColor) { - SyntaxpainConfiguration.highlightColor = highlightColor; - } - - public static Color getStringColor() { - return stringColor; - } - - public static void setStringColor(Color stringColor) { - SyntaxpainConfiguration.stringColor = stringColor; - } - - public static Color getNumberColor() { - return numberColor; - } - - public static void setNumberColor(Color numberColor) { - SyntaxpainConfiguration.numberColor = numberColor; - } - - public static Color getOperatorColor() { - return operatorColor; - } - - public static void setOperatorColor(Color operatorColor) { - SyntaxpainConfiguration.operatorColor = operatorColor; - } - - public static Color getDelimiterColor() { - return delimiterColor; - } - - public static void setDelimiterColor(Color delimiterColor) { - SyntaxpainConfiguration.delimiterColor = delimiterColor; - } - - public static Color getTypeColor() { - return typeColor; - } - - public static void setTypeColor(Color typeColor) { - SyntaxpainConfiguration.typeColor = typeColor; - } - - public static Color getIdentifierColor() { - return identifierColor; - } - - public static void setIdentifierColor(Color identifierColor) { - SyntaxpainConfiguration.identifierColor = identifierColor; - } - - public static Color getCommentColour() { - return commentColour; - } - - public static void setCommentColour(Color commentColour) { - SyntaxpainConfiguration.commentColour = commentColour; - } - - public static Color getTextColor() { - return textColor; - } - - public static void setTextColor(Color textColor) { - SyntaxpainConfiguration.textColor = textColor; - } - - public static Color getRegexColor() { - return regexColor; - } - - public static void setRegexColor(Color regexColor) { - SyntaxpainConfiguration.regexColor = regexColor; - } - - public static Color getLineRulerPrimaryColor() { - return lineRulerPrimaryColor; - } - - public static void setLineRulerPrimaryColor(Color lineRulerPrimaryColor) { - SyntaxpainConfiguration.lineRulerPrimaryColor = lineRulerPrimaryColor; - } - - public static Color getLineRulerSecondaryColor() { - return lineRulerSecondaryColor; - } - - public static void setLineRulerSecondaryColor(Color lineRulerSecondaryColor) { - SyntaxpainConfiguration.lineRulerSecondaryColor = lineRulerSecondaryColor; - } - - public static Color getLineRulerSelectionColor() { - return lineRulerSelectionColor; - } - - public static void setLineRulerSelectionColor(Color lineRulerSelectionColor) { - SyntaxpainConfiguration.lineRulerSelectionColor = lineRulerSelectionColor; - } - - public static Font getEditorFont() { - return editorFont; - } - - public static void setEditorFont(Font font) { - editorFont = font; - JavaSyntaxKit.setFont(font); - } - - /** - * @return whether automatic installation of {@link QuickFindDialog}s in {@link JEditorPane}s is enabled - */ - public static boolean isQuickFindDialogEnabled() { - return quickFindDialogFactory != null; - } - - /** - * @return a new dialog, or {@code null} if {@linkplain #isQuickFindDialogEnabled dialogs are disabled} - */ - public static QuickFindDialog getQuickFindDialog(JTextComponent component) { - return quickFindDialogFactory == null ? null : quickFindDialogFactory.apply(component); - } - - /** - * Set's the factory method used by {@link #getQuickFindDialog(JTextComponent)} to create new dialogs. - * - *

Pass {@code null} to disable automatic installation of {@link QuickFindDialog}s in {@link JEditorPane}s. - * - * @param dialogFactory the dialog factory; may be {@code null}, but a factory must not return {@code null} - */ - public static void setQuickFindDialogFactory(Function dialogFactory) { - quickFindDialogFactory = dialogFactory; - } -} diff --git a/src/main/java/org/quiltmc/syntaxpain/Util.java b/src/main/java/org/quiltmc/syntaxpain/Util.java deleted file mode 100644 index 71253eb..0000000 --- a/src/main/java/org/quiltmc/syntaxpain/Util.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com - * Copyright 2011-2022 Hanns Holger Rutz. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License - * at http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.quiltmc.syntaxpain; - -import javax.swing.JComponent; -import javax.swing.KeyStroke; -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; -import javax.swing.text.JTextComponent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * General utility methods for use around the internals. - */ -public class Util { - private Util() { - } - - /** - * A helper function that will return the SyntaxDocument attached to the - * given text component. Return null if the document is not a - * SyntaxDocument, or if the text component is null - */ - public static SyntaxDocument getSyntaxDocument(JTextComponent component) { - if (component == null) { - return null; - } - - Document doc = component.getDocument(); - if (doc instanceof SyntaxDocument) { - return (SyntaxDocument) doc; - } else { - return null; - } - } - - /** - * Gets the Line Number at the give position of the editor component. - * The first line number is ZERO - * - * @return line number - */ - public static int getLineNumber(JTextComponent editor, int pos) throws BadLocationException { - if (getSyntaxDocument(editor) != null) { - SyntaxDocument sdoc = getSyntaxDocument(editor); - return sdoc.getLineNumberAt(pos); - } else { - Document doc = editor.getDocument(); - return doc.getDefaultRootElement().getElementIndex(pos); - } - } - - public static int getLineCount(JTextComponent pane) { - final SyntaxDocument sdoc = getSyntaxDocument(pane); - if (sdoc != null) { - return sdoc.getLineCount(); - } - - int count = 0; - try { - int p = pane.getDocument().getLength() - 1; - if (p > 0) { - count = getLineNumber(pane, p); - } - } catch (BadLocationException ex) { - Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex); - } - - return count; - } - - public static void addEscapeListener(EscapeListener dialog) { - ActionListener escListener = e -> dialog.escapePressed(); - - dialog.getRootPane().registerKeyboardAction(escListener, - KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), - JComponent.WHEN_IN_FOCUSED_WINDOW); - } -}