Intellij Adaptive Color Scheme

Wuzi

August 2024, 22

3 min read

Intellij Adaptive Color Scheme

Intellij Adaptive Color Scheme

This article describes how to make the colors of user interface components in IntelliJ adaptable to changes in the IDE theme.

Create a UI Component

Suppose we now have a component like this

1
public class UIContainer extends JBPanel<UIContainer> {
2
3
private static final EditorColorsManager editorColorsManager = EditorColorsManager.getInstance();
4
private static EditorColorsScheme scheme = editorColorsManager.getGlobalScheme();
5
private static final ColorKey notificationColor = ColorKey.createColorKey("NOTIFICATION_BACKGROUND");
6
7
public MessageComponent() {
8
// TODO init some actions...
9
10
Color color = scheme.getColor(notificationColor);
11
setBackground(color)
12
}
13
}

We set a background color for the UIContainer that comes from the current ColorsScheme’s NOTIFICATION_BACKGROUND, but it’s clear that in this case, when we switch themes, the color of the UIContainer doesn’t switch with the theme’s color.

UIContainer color doesn’t switch with the theme’s color when we switch themes in this case. However, in most cases, this may cause the UI to have similar colors and fonts, so that the displayed content is not visible.

So, how can we make the background color of UIContainer change automatically as the theme changes?

Adaptive to IDE theme

Implements Interfaces

Make UIContainer implements Disposable and EditorColorsListener

UIContainer.java
1
public class UIContainer extends JBPanel<UIContainer> implements Disposable, EditorColorsListener {
2
{... rest of code}
3
}

Add Message Event

UIContainer.java
1
public class UIContainer extends JBPanel<UIContainer> implements Disposable, EditorColorsListener {
2
3
private static final EditorColorsManager editorColorsManager = EditorColorsManager.getInstance();
4
private static EditorColorsScheme scheme = editorColorsManager.getGlobalScheme();
5
private static final ColorKey notificationColor = ColorKey.createColorKey("NOTIFICATION_BACKGROUND");
6
7
public MessageComponent() {
8
// TODO init some actions...
9
10
Color color = scheme.getColor(notificationColor);
11
setBackground(color)
12
13
MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(this);
14
connection.subscribe(EditorColorsManager.TOPIC, this);
15
}
16
}

Implements globalSchemeChange

When theme changed, the globalSchemeChange method will be called.

currentColorsScheme will be the selected theme, so we regain the notificationColor from currentColorsScheme and reset the color for the component.

UIContainer.java
1
public class UIContainer extends JBPanel<UIContainer> implements Disposable, EditorColorsListener {
2
3
{... rest of code}
4
5
@Override
6
public void globalSchemeChange(@Nullable EditorColorsScheme currentColorsScheme) {
7
Color color = currentColorsScheme == null ? scheme.getColor(notificationColor) :
8
currentColorsScheme.getColor(notificationColor);
9
setBackground(color);
10
revalidate();
11
repaint();
12
}
13
}

Implements dispose

UIContainer.java
1
public class UIContainer extends JBPanel<UIContainer> implements Disposable, EditorColorsListener {
2
3
{... rest of code}
4
5
@Override
6
public void dispose() {
7
Disposer.dispose(this);
8
}
9
}

Finally Code

So, The final code is as follows

1
public class UIContainer extends JBPanel<UIContainer> implements Disposable, EditorColorsListener {
2
3
private static final EditorColorsManager editorColorsManager = EditorColorsManager.getInstance();
4
private static EditorColorsScheme scheme = editorColorsManager.getGlobalScheme();
5
private static final ColorKey notificationColor = ColorKey.createColorKey("NOTIFICATION_BACKGROUND");
6
7
public MessageComponent() {
8
// TODO init some actions...
9
10
Color color = scheme.getColor(notificationColor);
11
setBackground(color)
12
13
MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(this);
14
connection.subscribe(EditorColorsManager.TOPIC, this);
15
}
16
17
@Override
18
public void globalSchemeChange(@Nullable EditorColorsScheme currentColorsScheme) {
19
if (currentColorsScheme == null) {
20
return;
21
}
22
Color color = scheme.getColor(notificationColor);
23
setBackground(color);
24
revalidate();
25
repaint();
26
}
27
28
@Override
29
public void dispose() {
30
Disposer.dispose(this);
31
}
32
}

Now when you switch themes, the color of the component will automatically change with the color of the theme. Hope this helps.

Share to X