Skip to content

Commit 9cb0e1d

Browse files
committed
Added dark mode theme.
1 parent f8aa221 commit 9cb0e1d

25 files changed

+1944
-96
lines changed

protege-editor-core/src/main/java/org/protege/editor/core/ProtegeApplication.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -320,13 +320,8 @@ private void initializeLookAndFeel() {
320320
// Force the Look & Feel to be instantiated.
321321
UIDefaults defaults = UIManager.getDefaults();
322322
if (lafClsName.equals(PlasticLookAndFeel.class.getName())) {
323-
// Truly strange. If we don't do this then the LAF cannot be found.
324-
PlasticLookAndFeel.setCurrentTheme(new ProtegePlasticTheme());
325-
UIManager.put("ClassLoader", PlasticLookAndFeel.class.getClassLoader());
326-
// For plastic this needs to be instantiated here - otherwise SwingUtilities uses the wrong class
327-
// loaded.
328-
LookAndFeel lookAndFeel = (LookAndFeel) Class.forName(lafClsName).newInstance();
329-
UIManager.setLookAndFeel(lookAndFeel);
323+
// Use ThemeManager to apply the correct theme (light or dark)
324+
org.protege.editor.core.ui.util.ThemeManager.loadTheme();
330325
}
331326
else {
332327
// Now set the class loader for Component UI loading to this one. Works for non Plastic LAFs.

protege-editor-core/src/main/java/org/protege/editor/core/log/TextForegroundPreviewPanel.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ public class TextForegroundPreviewPanel extends JPanel
2929
public TextForegroundPreviewPanel(JColorChooser chooser) {
3030
chooser.getSelectionModel().addChangeListener(this);
3131
setForeground(color);
32-
setBackground(Color.WHITE);
32+
Color panelBg = javax.swing.UIManager.getColor("Panel.background");
33+
if (panelBg == null) {
34+
panelBg = Color.WHITE;
35+
}
36+
setBackground(panelBg);
3337
setOpaque(true);
3438
setFont(new Font("monospaced", Font.PLAIN, 12));
3539
text.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

protege-editor-core/src/main/java/org/protege/editor/core/ui/list/MList.java

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,39 @@ public class MList extends JList {
3333

3434
private Font sectionHeaderFont = new Font("Lucida Grande", Font.PLAIN, 10);
3535

36-
private static final Color itemBackgroundColor = Color.WHITE;
36+
private static final Color DEFAULT_LIST_DIVIDER_COLOR = new Color(240, 240, 240);
3737

38+
private Color getListBackgroundColor() {
39+
Color bg = getBackground();
40+
if (bg == null) {
41+
bg = UIManager.getColor("MList.background");
42+
}
43+
if (bg == null) {
44+
bg = UIManager.getColor("List.background");
45+
}
46+
if (bg == null) {
47+
bg = UIManager.getColor("Panel.background");
48+
}
49+
if (bg == null) {
50+
bg = UIManager.getColor("control");
51+
}
52+
return bg != null ? bg : Color.WHITE;
53+
}
54+
55+
private Color resolveBackground(Color candidate) {
56+
return candidate != null ? candidate : getListBackgroundColor();
57+
}
58+
59+
private Color getListDividerColor() {
60+
Color divider = UIManager.getColor("Separator.foreground");
61+
if (divider == null) {
62+
divider = UIManager.getColor("controlShadow");
63+
}
64+
if (divider == null) {
65+
divider = DEFAULT_LIST_DIVIDER_COLOR;
66+
}
67+
return divider;
68+
}
3869

3970
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4071

@@ -266,7 +297,7 @@ protected List<MListButton> getListItemButtons(MListItem item) {
266297
}
267298

268299
protected Color getItemBackgroundColor(MListItem item) {
269-
return itemBackgroundColor;
300+
return getListBackgroundColor();
270301
}
271302

272303
public class MListCellRenderer implements ListCellRenderer {
@@ -336,7 +367,7 @@ protected Border createPaddingBorder(JList list, Object value, int index, boolea
336367
bottomMargin = getRowHeightPadding(index);
337368
}
338369
}
339-
return BorderFactory.createMatteBorder(0, 0, bottomMargin, 0, Color.WHITE);
370+
return BorderFactory.createMatteBorder(0, 0, bottomMargin, 0, resolveBackground(list.getBackground()));
340371
}
341372

342373
private int getRowHeightPadding(int index) {
@@ -349,8 +380,8 @@ private int getRowHeightPadding(int index) {
349380

350381
protected Border createListItemBorder(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
351382
Border internalPadding = BorderFactory.createEmptyBorder(1, 1, 1, 1);
352-
Border line = BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(240, 240, 240));
353-
Border externalBorder = BorderFactory.createMatteBorder(0, 20, 0, 0, list.getBackground());
383+
Border line = BorderFactory.createMatteBorder(0, 0, 1, 0, getListDividerColor());
384+
Border externalBorder = BorderFactory.createMatteBorder(0, 20, 0, 0, resolveBackground(list.getBackground()));
354385
return BorderFactory.createCompoundBorder(
355386
externalBorder,
356387
BorderFactory.createCompoundBorder(line, internalPadding)

protege-editor-core/src/main/java/org/protege/editor/core/ui/preferences/PreferencesDialogPanel.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public class PreferencesDialogPanel extends JPanel implements Disposable {
4747
public PreferencesDialogPanel(EditorKit editorKit) {
4848
this.editorKit = editorKit;
4949
setLayout(new BorderLayout());
50+
setBackground(UIManager.getColor("Panel.background"));
51+
setOpaque(true);
5052
add(tabbedPane);
5153
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
5254
int margin = 300;
@@ -59,6 +61,8 @@ public PreferencesDialogPanel(EditorKit editorKit) {
5961
private void reload() {
6062
dispose();
6163
tabbedPane.removeAll();
64+
tabbedPane.setBackground(UIManager.getColor("Panel.background"));
65+
tabbedPane.setOpaque(true);
6266
PreferencesPanelPluginLoader loader = new PreferencesPanelPluginLoader(editorKit);
6367
Set<PreferencesPanelPlugin> plugins = new TreeSet<>((o1, o2) -> {
6468
String s1 = o1.getLabel();
@@ -73,6 +77,10 @@ private void reload() {
7377
final String label = plugin.getLabel();
7478
final JScrollPane sp = new JScrollPane(panel);
7579
sp.setBorder(new EmptyBorder(0, 0, 0, 0));
80+
sp.setBackground(UIManager.getColor("Panel.background"));
81+
sp.setOpaque(true);
82+
sp.getViewport().setBackground(UIManager.getColor("Panel.background"));
83+
sp.getViewport().setOpaque(true);
7684
map.put(label, panel);
7785
componentMap.put(label, sp);
7886
tabbedPane.addTab(label, sp);
@@ -130,6 +138,8 @@ public static void showPreferencesDialog(String selectedPanel, EditorKit editorK
130138
final PreferencesDialogPanel preferencesPanel = new PreferencesDialogPanel(editorKit);
131139

132140
JPanel holder = new JPanel(new BorderLayout(4, 4));
141+
holder.setBackground(UIManager.getColor("Panel.background"));
142+
holder.setOpaque(true);
133143
holder.add(preferencesPanel);
134144

135145
if (selectedPanel == null){
@@ -139,6 +149,8 @@ public static void showPreferencesDialog(String selectedPanel, EditorKit editorK
139149
preferencesPanel.setSelectedPanel(selectedPanel);
140150

141151
JPanel resetPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
152+
resetPanel.setBackground(UIManager.getColor("Panel.background"));
153+
resetPanel.setOpaque(true);
142154
JButton resetPreferencesButton = new JButton(new AbstractAction("Reset preferences...") {
143155
public void actionPerformed(ActionEvent e) {
144156
handleResetPreferences(preferencesPanel);
@@ -148,7 +160,14 @@ public void actionPerformed(ActionEvent e) {
148160
holder.add(resetPanel, BorderLayout.SOUTH);
149161

150162
JOptionPane op = new JOptionPane(holder, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
163+
op.setBackground(UIManager.getColor("Panel.background"));
164+
op.setOpaque(true);
151165
JDialog dlg = op.createDialog(editorKit.getWorkspace(), "Preferences");
166+
dlg.getContentPane().setBackground(UIManager.getColor("Panel.background"));
167+
168+
// Recursively set background colors on all components in the dialog
169+
setBackgroundRecursive(dlg, UIManager.getColor("Panel.background"));
170+
152171
dlg.setResizable(true);
153172
dlg.setVisible(true);
154173
Object o = op.getValue();
@@ -175,4 +194,30 @@ private static void handleResetPreferences(PreferencesDialogPanel panel) {
175194
panel.reload();
176195
panel.setSelectedPanel(selectedPanel);
177196
}
197+
198+
/**
199+
* Recursively sets the background color on all components in a container.
200+
* This ensures that all nested components use the correct theme background.
201+
*/
202+
private static void setBackgroundRecursive(Container container, Color background) {
203+
if (container == null || background == null) return;
204+
205+
// Set background on the container itself
206+
container.setBackground(background);
207+
if (container instanceof JComponent) {
208+
((JComponent) container).setOpaque(true);
209+
}
210+
211+
// Recursively set background on all child components
212+
for (Component component : container.getComponents()) {
213+
if (component instanceof Container) {
214+
setBackgroundRecursive((Container) component, background);
215+
} else {
216+
component.setBackground(background);
217+
if (component instanceof JComponent) {
218+
((JComponent) component).setOpaque(true);
219+
}
220+
}
221+
}
222+
}
178223
}

protege-editor-core/src/main/java/org/protege/editor/core/ui/preferences/PreferencesLayoutPanel.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,14 @@ public class PreferencesLayoutPanel extends JComponent {
2525
public PreferencesLayoutPanel() {
2626
setLayout(new BorderLayout());
2727
setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
28+
Color panelBg = UIManager.getColor("Panel.background");
29+
if (panelBg == null) {
30+
panelBg = Color.WHITE;
31+
}
32+
setBackground(panelBg);
2833
backingPanel = new JPanel(new GridBagLayout());
34+
backingPanel.setBackground(panelBg);
35+
backingPanel.setOpaque(true);
2936
add(backingPanel, BorderLayout.NORTH);
3037
}
3138

@@ -165,7 +172,11 @@ private void handleComponentAdded(JComponent component) {
165172
public void addHelpText(String helpText) {
166173
JLabel label = new JLabel(helpText);
167174
label.setFont(label.getFont().deriveFont(Font.PLAIN, 10f));
168-
label.setForeground(Color.GRAY);
175+
Color helpFg = UIManager.getColor("Label.disabledForeground");
176+
if (helpFg == null) {
177+
helpFg = Color.GRAY;
178+
}
179+
label.setForeground(helpFg);
169180
label.setBorder(BorderFactory.createEmptyBorder(3, 20, 7, 0));
170181
addGroupComponent(label);
171182

protege-editor-core/src/main/java/org/protege/editor/core/ui/preferences/PreferencesPanel.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ public void setup(String label, EditorKit editorKit) {
2929
this.editorKit = editorKit;
3030
setBorder(BorderFactory.createEmptyBorder(30, 20, 20, 20));
3131
setLayout(new PreferencesPanelLayoutManager(this));
32+
Color panelBg = UIManager.getColor("Panel.background");
33+
if (panelBg == null) {
34+
panelBg = Color.WHITE;
35+
}
36+
setBackground(panelBg);
37+
setOpaque(true);
3238
}
3339

3440

protege-editor-core/src/main/java/org/protege/editor/core/ui/util/ComponentFactory.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,17 @@ public static JComponent createExceptionComponent(String message, Throwable exce
3434

3535
public static JScrollPane createScrollPane(JComponent content) {
3636
JScrollPane sp = new JScrollPane(content);
37-
sp.getViewport().setBackground(Color.WHITE);
37+
Color background = content != null ? content.getBackground() : null;
38+
if (background == null) {
39+
background = UIManager.getColor("ScrollPane.background");
40+
}
41+
if (background == null) {
42+
background = UIManager.getColor("Panel.background");
43+
}
44+
if (background == null) {
45+
background = UIManager.getColor("control");
46+
}
47+
sp.getViewport().setBackground(background != null ? background : Color.WHITE);
3848
return sp;
3949
}
4050

protege-editor-core/src/main/java/org/protege/editor/core/ui/util/LinkLabel.java

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,44 +22,40 @@
2222
public class LinkLabel extends JLabel {
2323

2424
private Color linkColor;
25-
2625
private Color hoverColor;
27-
2826
private Cursor oldCursor;
29-
3027
private ActionListener linkListener;
28+
private boolean hoverMode;
29+
private boolean isClickable;
3130

3231

3332
public LinkLabel(String text, ActionListener linkListener) {
3433
super(text);
3534
this.linkListener = linkListener;
36-
linkColor = Color.BLACK;
37-
hoverColor = Color.BLUE;
38-
39-
setForeground(linkColor);
40-
41-
addMouseListener(new MouseAdapter() {
42-
public void mouseEntered(MouseEvent e) {
43-
setHoverMode(true);
44-
}
45-
46-
47-
public void mouseExited(MouseEvent e) {
48-
setHoverMode(false);
49-
}
50-
51-
52-
public void mouseReleased(MouseEvent e) {
53-
activateLink();
54-
}
55-
});
56-
35+
this.isClickable = linkListener != null;
36+
updateColorsFromUI();
37+
if (isClickable) {
38+
addMouseListener(new MouseAdapter() {
39+
public void mouseEntered(MouseEvent e) {
40+
setHoverMode(true);
41+
}
42+
public void mouseExited(MouseEvent e) {
43+
setHoverMode(false);
44+
}
45+
public void mouseReleased(MouseEvent e) {
46+
activateLink();
47+
}
48+
});
49+
}
5750
setFont(Fonts.getMediumDialogFont().deriveFont(Font.BOLD, 14f));
5851
}
5952

6053

6154
public void setLinkColor(Color color) {
6255
linkColor = color;
56+
if (!hoverMode) {
57+
setForeground(linkColor);
58+
}
6359
}
6460

6561

@@ -70,11 +66,13 @@ public void setHoverColor(Color color) {
7066

7167
private void setHoverMode(boolean b) {
7268
if (b && isEnabled()) {
69+
hoverMode = true;
7370
setForeground(hoverColor);
7471
oldCursor = getCursor();
7572
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
7673
}
7774
else {
75+
hoverMode = false;
7876
setForeground(linkColor);
7977
if (oldCursor != null) {
8078
setCursor(oldCursor);
@@ -89,4 +87,38 @@ private void activateLink() {
8987
linkListener.actionPerformed(new ActionEvent(this, 0, getText()));
9088
}
9189
}
90+
91+
@Override
92+
public void updateUI() {
93+
super.updateUI();
94+
updateColorsFromUI();
95+
}
96+
97+
private void updateColorsFromUI() {
98+
if (isClickable) {
99+
Color uiLink = UIManager.getColor("Link.foreground");
100+
Color uiHover = UIManager.getColor("Link.hoverForeground");
101+
// Theme-aware fallback colors
102+
if (uiLink == null) {
103+
uiLink = ThemeManager.isDarkTheme() ?
104+
new Color(0x80, 0x70, 0xFF) : new Color(0x00, 0x64, 0xC8); // Dark blue for light theme
105+
}
106+
if (uiHover == null) {
107+
uiHover = ThemeManager.isDarkTheme() ?
108+
uiLink.brighter() : uiLink.darker();
109+
}
110+
linkColor = uiLink;
111+
hoverColor = uiHover;
112+
if (!hoverMode) {
113+
setForeground(linkColor);
114+
}
115+
} else {
116+
// Use label foreground for non-clickable labels
117+
Color labelColor = UIManager.getColor("Label.foreground");
118+
if (labelColor == null) {
119+
labelColor = ThemeManager.isDarkTheme() ? Color.WHITE : Color.BLACK;
120+
}
121+
setForeground(labelColor);
122+
}
123+
}
92124
}

0 commit comments

Comments
 (0)