From 94ef12522dd62d88ade0b4f66f43407eecbd28a8 Mon Sep 17 00:00:00 2001 From: Mattia Marelli Date: Sat, 3 May 2025 11:51:30 +0200 Subject: [PATCH 1/7] Search for left/right icons into UIManager to allow customization --- .../autocomplete/AutoCompleteDescWindow.java | 91 +++++++++++-------- 1 file changed, 55 insertions(+), 36 deletions(-) diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java index 71f6675..f873116 100644 --- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java +++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java @@ -4,6 +4,13 @@ */ package org.fife.ui.autocomplete; +import org.fife.ui.rsyntaxtextarea.PopupWindowDecorator; + +import javax.swing.*; +import javax.swing.border.AbstractBorder; +import javax.swing.border.Border; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; import java.awt.*; import java.awt.event.ActionEvent; import java.lang.reflect.InvocationTargetException; @@ -14,26 +21,6 @@ import java.util.ArrayList; import java.util.List; import java.util.ResourceBundle; -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.BorderFactory; -import javax.swing.Icon; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JEditorPane; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JToolBar; -import javax.swing.JWindow; -import javax.swing.SwingUtilities; -import javax.swing.Timer; -import javax.swing.UIManager; -import javax.swing.border.AbstractBorder; -import javax.swing.border.Border; -import javax.swing.event.HyperlinkEvent; -import javax.swing.event.HyperlinkListener; - -import org.fife.ui.rsyntaxtextarea.PopupWindowDecorator; /** @@ -578,23 +565,39 @@ void setCompletion(Completion c, String anchor, class ToolBarBackAction extends AbstractAction { ToolBarBackAction(boolean ltr) { - String img = "org/fife/ui/autocomplete/arrow_" + - (ltr ? "left.png" : "right.png"); - ClassLoader cl = getClass().getClassLoader(); - Icon icon = new ImageIcon(cl.getResource(img)); + setIcon(ltr); + + UIManager.addPropertyChangeListener(evt -> { + if (evt.getPropertyName().equals("lookAndFeel")) { + setIcon(ltr); + } + }); + } + + private void setIcon(boolean ltr) { + Icon icon = UIManager.getIcon("autocomplete.leftArrow"); + + if (icon == null) { + if (ltr) + icon = new ImageIcon(getClass().getResource("arrow_left.png")); + else + icon = new ImageIcon(getClass().getResource("arrow_right.png")); + + UIManager.put("autocomplete.leftArrow", icon); + } + putValue(Action.SMALL_ICON, icon); } @Override public void actionPerformed(ActionEvent e) { - if (historyPos>0) { + if (historyPos > 0) { HistoryEntry pair = history.get(--historyPos); descArea.setText(pair.summary); - if (pair.anchor!=null) { + if (pair.anchor != null) { //System.out.println("Scrolling to: " + pair.anchor); descArea.scrollToReference(pair.anchor); - } - else { + } else { descArea.setCaretPosition(0); } setActionStates(); @@ -610,23 +613,39 @@ public void actionPerformed(ActionEvent e) { class ToolBarForwardAction extends AbstractAction { ToolBarForwardAction(boolean ltr) { - String img = "org/fife/ui/autocomplete/arrow_" + - (ltr ? "right.png" : "left.png"); - ClassLoader cl = getClass().getClassLoader(); - Icon icon = new ImageIcon(cl.getResource(img)); + setIcon(ltr); + + UIManager.addPropertyChangeListener(evt -> { + if (evt.getPropertyName().equals("lookAndFeel")) { + setIcon(ltr); + } + }); + } + + void setIcon(boolean ltr) { + Icon icon = UIManager.getIcon("autocomplete.rightArrow"); + + if (icon == null) { + if (ltr) + icon = new ImageIcon(getClass().getResource("arrow_right.png")); + else + icon = new ImageIcon(getClass().getResource("arrow_left.png")); + + UIManager.put("autocomplete.rightArrow", icon); + } + putValue(Action.SMALL_ICON, icon); } @Override public void actionPerformed(ActionEvent e) { - if (history!=null && historyPos Date: Sat, 3 May 2025 18:01:17 +0200 Subject: [PATCH 2/7] Search for left/right icons into UIManager to allow customization --- .../autocomplete/AutoCompleteDescWindow.java | 90 +++++++++---------- 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java index f873116..9ca987d 100644 --- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java +++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java @@ -22,6 +22,8 @@ import java.util.List; import java.util.ResourceBundle; +import static java.util.Objects.requireNonNull; + /** * The optional "description" window that describes the currently selected @@ -498,7 +500,43 @@ public void updateUI() { TipUtil.tweakTipEditorPane(descArea); scrollPane.setBackground(descArea.getBackground()); scrollPane.getViewport().setBackground(descArea.getBackground()); - ((JPanel)getContentPane()).setBorder(TipUtil.getToolTipBorder()); + ((JPanel) getContentPane()).setBorder(TipUtil.getToolTipBorder()); + + ComponentOrientation orientation = ac.getTextComponentOrientation(); + setIcon(forwardAction, orientation.isLeftToRight(), "forward"); + setIcon(backAction, orientation.isLeftToRight(), "back"); + } + + private static void setIcon(Action action, boolean ltr, String type) { + Icon leftIcon = UIManager.getIcon("autocomplete.leftArrow"); + Icon rightIcon = UIManager.getIcon("autocomplete.rightArrow"); + + if (leftIcon == null) { + String leftIc = ltr ? "arrow_left.png" : "arrow_right.png"; + leftIcon = new ImageIcon(requireNonNull(AutoCompleteDescWindow.class.getResource(leftIc))); + UIManager.put("autocomplete.leftArrow", leftIcon); + } + + if (rightIcon == null) { + String rightIc = ltr ? "arrow_right.png" : "arrow_left.png"; + rightIcon = new ImageIcon(requireNonNull(AutoCompleteDescWindow.class.getResource(rightIc))); + UIManager.put("autocomplete.leftArrow", leftIcon); + } + + + if ("back".equals(type)) { + if (ltr) { + action.putValue(Action.SMALL_ICON, leftIcon); + } else { + action.putValue(Action.SMALL_ICON, rightIcon); + } + } else if ("forward".equals(type)) { + if (ltr) { + action.putValue(Action.SMALL_ICON, rightIcon); + } else { + action.putValue(Action.SMALL_ICON, leftIcon); + } + } } @@ -512,7 +550,7 @@ private static class HistoryEntry { private String anchor; HistoryEntry(Completion completion, String summary, - String anchor) { + String anchor) { this.completion = completion; this.summary = summary; this.anchor = anchor; @@ -565,28 +603,7 @@ void setCompletion(Completion c, String anchor, class ToolBarBackAction extends AbstractAction { ToolBarBackAction(boolean ltr) { - setIcon(ltr); - - UIManager.addPropertyChangeListener(evt -> { - if (evt.getPropertyName().equals("lookAndFeel")) { - setIcon(ltr); - } - }); - } - - private void setIcon(boolean ltr) { - Icon icon = UIManager.getIcon("autocomplete.leftArrow"); - - if (icon == null) { - if (ltr) - icon = new ImageIcon(getClass().getResource("arrow_left.png")); - else - icon = new ImageIcon(getClass().getResource("arrow_right.png")); - - UIManager.put("autocomplete.leftArrow", icon); - } - - putValue(Action.SMALL_ICON, icon); + setIcon(this, ltr, "back"); } @Override @@ -603,7 +620,6 @@ public void actionPerformed(ActionEvent e) { setActionStates(); } } - } @@ -613,28 +629,7 @@ public void actionPerformed(ActionEvent e) { class ToolBarForwardAction extends AbstractAction { ToolBarForwardAction(boolean ltr) { - setIcon(ltr); - - UIManager.addPropertyChangeListener(evt -> { - if (evt.getPropertyName().equals("lookAndFeel")) { - setIcon(ltr); - } - }); - } - - void setIcon(boolean ltr) { - Icon icon = UIManager.getIcon("autocomplete.rightArrow"); - - if (icon == null) { - if (ltr) - icon = new ImageIcon(getClass().getResource("arrow_right.png")); - else - icon = new ImageIcon(getClass().getResource("arrow_left.png")); - - UIManager.put("autocomplete.rightArrow", icon); - } - - putValue(Action.SMALL_ICON, icon); + setIcon(this, ltr, "forward"); } @Override @@ -651,7 +646,6 @@ public void actionPerformed(ActionEvent e) { setActionStates(); } } - } From 8ab0122612525a4e77323c81f0d5ad26b0b2c53a Mon Sep 17 00:00:00 2001 From: Mattia Marelli Date: Sun, 4 May 2025 10:06:20 +0200 Subject: [PATCH 3/7] Some fix --- .../autocomplete/AutoCompleteDescWindow.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java index 9ca987d..aa117b9 100644 --- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java +++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java @@ -58,12 +58,12 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, /** * Action that goes to the previous description displayed. */ - private Action backAction; + private final Action backAction; /** * Action that goes to the next description displayed. */ - private Action forwardAction; + private final Action forwardAction; /** * History of descriptions displayed. @@ -503,27 +503,26 @@ public void updateUI() { ((JPanel) getContentPane()).setBorder(TipUtil.getToolTipBorder()); ComponentOrientation orientation = ac.getTextComponentOrientation(); - setIcon(forwardAction, orientation.isLeftToRight(), "forward"); - setIcon(backAction, orientation.isLeftToRight(), "back"); + setArrowIcon(forwardAction, orientation.isLeftToRight(), "forward"); + setArrowIcon(backAction, orientation.isLeftToRight(), "back"); } - private static void setIcon(Action action, boolean ltr, String type) { + private static void setArrowIcon(Action action, boolean ltr, String type) { Icon leftIcon = UIManager.getIcon("autocomplete.leftArrow"); Icon rightIcon = UIManager.getIcon("autocomplete.rightArrow"); if (leftIcon == null) { - String leftIc = ltr ? "arrow_left.png" : "arrow_right.png"; - leftIcon = new ImageIcon(requireNonNull(AutoCompleteDescWindow.class.getResource(leftIc))); + URL leftIc = AutoCompleteDescWindow.class.getResource("arrow_left.png"); + leftIcon = new ImageIcon(requireNonNull(leftIc)); UIManager.put("autocomplete.leftArrow", leftIcon); } if (rightIcon == null) { - String rightIc = ltr ? "arrow_right.png" : "arrow_left.png"; - rightIcon = new ImageIcon(requireNonNull(AutoCompleteDescWindow.class.getResource(rightIc))); + URL rightIc = AutoCompleteDescWindow.class.getResource("arrow_right.png"); + rightIcon = new ImageIcon(requireNonNull(rightIc)); UIManager.put("autocomplete.leftArrow", leftIcon); } - if ("back".equals(type)) { if (ltr) { action.putValue(Action.SMALL_ICON, leftIcon); @@ -536,7 +535,7 @@ private static void setIcon(Action action, boolean ltr, String type) { } else { action.putValue(Action.SMALL_ICON, leftIcon); } - } + } else throw new IllegalArgumentException(); } @@ -603,7 +602,7 @@ void setCompletion(Completion c, String anchor, class ToolBarBackAction extends AbstractAction { ToolBarBackAction(boolean ltr) { - setIcon(this, ltr, "back"); + setArrowIcon(this, ltr, "back"); } @Override @@ -629,7 +628,7 @@ public void actionPerformed(ActionEvent e) { class ToolBarForwardAction extends AbstractAction { ToolBarForwardAction(boolean ltr) { - setIcon(this, ltr, "forward"); + setArrowIcon(this, ltr, "forward"); } @Override From e1fcc35e0c940748b141b18d568d876eb0cfab82 Mon Sep 17 00:00:00 2001 From: Mattia Marelli <75846162+sesquialtera87@users.noreply.github.com> Date: Sun, 4 May 2025 23:39:09 +0200 Subject: [PATCH 4/7] Fix wrong UI property name --- .../java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java index aa117b9..2cce8c7 100644 --- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java +++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java @@ -520,7 +520,7 @@ private static void setArrowIcon(Action action, boolean ltr, String type) { if (rightIcon == null) { URL rightIc = AutoCompleteDescWindow.class.getResource("arrow_right.png"); rightIcon = new ImageIcon(requireNonNull(rightIc)); - UIManager.put("autocomplete.leftArrow", leftIcon); + UIManager.put("autocomplete.rightArrow", leftIcon); } if ("back".equals(type)) { From 224548a24645baa58f6c35707abb9be41b6c9284 Mon Sep 17 00:00:00 2001 From: Mattia Marelli <75846162+sesquialtera87@users.noreply.github.com> Date: Sun, 4 May 2025 23:43:01 +0200 Subject: [PATCH 5/7] Fix UI property value --- .../java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java index 2cce8c7..bd5cba3 100644 --- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java +++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java @@ -520,7 +520,7 @@ private static void setArrowIcon(Action action, boolean ltr, String type) { if (rightIcon == null) { URL rightIc = AutoCompleteDescWindow.class.getResource("arrow_right.png"); rightIcon = new ImageIcon(requireNonNull(rightIc)); - UIManager.put("autocomplete.rightArrow", leftIcon); + UIManager.put("autocomplete.rightArrow", rightIcon); } if ("back".equals(type)) { From 35b56b004470c2a908404dbae9d5ce0a50ad425f Mon Sep 17 00:00:00 2001 From: sesquialtera87 Date: Mon, 3 Aug 2026 05:08:46 +0200 Subject: [PATCH 6/7] fix: checkstyle issues --- .../autocomplete/AutoCompleteDescWindow.java | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java index bd5cba3..79f3d24 100644 --- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java +++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java @@ -4,13 +4,6 @@ */ package org.fife.ui.autocomplete; -import org.fife.ui.rsyntaxtextarea.PopupWindowDecorator; - -import javax.swing.*; -import javax.swing.border.AbstractBorder; -import javax.swing.border.Border; -import javax.swing.event.HyperlinkEvent; -import javax.swing.event.HyperlinkListener; import java.awt.*; import java.awt.event.ActionEvent; import java.lang.reflect.InvocationTargetException; @@ -21,6 +14,26 @@ import java.util.ArrayList; import java.util.List; import java.util.ResourceBundle; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JEditorPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JToolBar; +import javax.swing.JWindow; +import javax.swing.SwingUtilities; +import javax.swing.Timer; +import javax.swing.UIManager; +import javax.swing.border.AbstractBorder; +import javax.swing.border.Border; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; + +import org.fife.ui.rsyntaxtextarea.PopupWindowDecorator; import static java.util.Objects.requireNonNull; @@ -58,12 +71,12 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, /** * Action that goes to the previous description displayed. */ - private final Action backAction; + private Action backAction; /** * Action that goes to the next description displayed. */ - private final Action forwardAction; + private Action forwardAction; /** * History of descriptions displayed. @@ -535,7 +548,9 @@ private static void setArrowIcon(Action action, boolean ltr, String type) { } else { action.putValue(Action.SMALL_ICON, leftIcon); } - } else throw new IllegalArgumentException(); + } else { + throw new IllegalArgumentException(); + } } @@ -549,7 +564,7 @@ private static class HistoryEntry { private String anchor; HistoryEntry(Completion completion, String summary, - String anchor) { + String anchor) { this.completion = completion; this.summary = summary; this.anchor = anchor; @@ -645,6 +660,7 @@ public void actionPerformed(ActionEvent e) { setActionStates(); } } + } From 6ed5dc6e1a90327a217ef07c0d7ce5c6cd5ae17b Mon Sep 17 00:00:00 2001 From: sesquialtera87 Date: Mon, 17 Aug 2026 23:10:35 +0200 Subject: [PATCH 7/7] refactor: changes in UIManager keys and minimal docs --- .../autocomplete/AutoCompleteDescWindow.java | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java index 79f3d24..912c7ef 100644 --- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java +++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompleteDescWindow.java @@ -35,8 +35,6 @@ import org.fife.ui.rsyntaxtextarea.PopupWindowDecorator; -import static java.util.Objects.requireNonNull; - /** * The optional "description" window that describes the currently selected @@ -520,37 +518,40 @@ public void updateUI() { setArrowIcon(backAction, orientation.isLeftToRight(), "back"); } + /** + * Sets the appropriate arrow icon for the specified navigation action based on + * the component orientation (Left-to-Right or Right-to-Left) and action type. + *

+ * This method first checks the {@link UIManager} for a custom icon registered under + * the semantic key. If absent, it loads the default icon resource from the classpath, + * caches it in the {@link UIManager} for future use, and assigns it to the action. + * + * @param action the menu or toolbar action to update with the icon + * @param ltr {@code true} if the component orientation is Left-to-Right; {@code false} for Right-to-Left + * @param type the type of navigation action, either {@code "back"} or {@code "forward"} + */ private static void setArrowIcon(Action action, boolean ltr, String type) { - Icon leftIcon = UIManager.getIcon("autocomplete.leftArrow"); - Icon rightIcon = UIManager.getIcon("autocomplete.rightArrow"); + // Determine the UIManager key based on action type and text direction + String key = "back".equals(type) ? + (ltr ? "autocomplete.descWindow.backIcon" : "autocomplete.descWindow.forwardIcon") : + (ltr ? "autocomplete.descWindow.forwardIcon" : "autocomplete.descWindow.backIcon"); - if (leftIcon == null) { - URL leftIc = AutoCompleteDescWindow.class.getResource("arrow_left.png"); - leftIcon = new ImageIcon(requireNonNull(leftIc)); - UIManager.put("autocomplete.leftArrow", leftIcon); - } + Icon icon = UIManager.getIcon(key); - if (rightIcon == null) { - URL rightIc = AutoCompleteDescWindow.class.getResource("arrow_right.png"); - rightIcon = new ImageIcon(requireNonNull(rightIc)); - UIManager.put("autocomplete.rightArrow", rightIcon); - } + if (icon == null) { + // Fallback to default classpath resources if not defined in UIManager + String resourceName = key.endsWith("backIcon") ? "arrow_left.png" : "arrow_right.png"; + URL url = AutoCompleteDescWindow.class.getResource(resourceName); - if ("back".equals(type)) { - if (ltr) { - action.putValue(Action.SMALL_ICON, leftIcon); - } else { - action.putValue(Action.SMALL_ICON, rightIcon); - } - } else if ("forward".equals(type)) { - if (ltr) { - action.putValue(Action.SMALL_ICON, rightIcon); + if (url != null) { + icon = new ImageIcon(url); + UIManager.put(key, icon); } else { - action.putValue(Action.SMALL_ICON, leftIcon); + throw new IllegalArgumentException("Icon resource not found on classpath: " + resourceName); } - } else { - throw new IllegalArgumentException(); } + + action.putValue(Action.SMALL_ICON, icon); }