
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
public class UIContainer extends JBPanel<UIContainer> {
private static final EditorColorsManager editorColorsManager = EditorColorsManager.getInstance(); private static EditorColorsScheme scheme = editorColorsManager.getGlobalScheme(); private static final ColorKey notificationColor = ColorKey.createColorKey("NOTIFICATION_BACKGROUND");
public MessageComponent() { // TODO init some actions...
Color color = scheme.getColor(notificationColor); setBackground(color) }}
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
public class UIContainer extends JBPanel<UIContainer> implements Disposable, EditorColorsListener { {... rest of code}}
Add Message Event
public class UIContainer extends JBPanel<UIContainer> implements Disposable, EditorColorsListener {
private static final EditorColorsManager editorColorsManager = EditorColorsManager.getInstance(); private static EditorColorsScheme scheme = editorColorsManager.getGlobalScheme(); private static final ColorKey notificationColor = ColorKey.createColorKey("NOTIFICATION_BACKGROUND");
public MessageComponent() { // TODO init some actions...
Color color = scheme.getColor(notificationColor); setBackground(color)
MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(this); connection.subscribe(EditorColorsManager.TOPIC, this); }}
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.
public class UIContainer extends JBPanel<UIContainer> implements Disposable, EditorColorsListener {
{... rest of code}
@Override public void globalSchemeChange(@Nullable EditorColorsScheme currentColorsScheme) { Color color = currentColorsScheme == null ? scheme.getColor(notificationColor) : currentColorsScheme.getColor(notificationColor); setBackground(color); revalidate(); repaint(); }}
Implements dispose
public class UIContainer extends JBPanel<UIContainer> implements Disposable, EditorColorsListener {
{... rest of code}
@Override public void dispose() { Disposer.dispose(this); }}
Finally Code
So, The final code is as follows
public class UIContainer extends JBPanel<UIContainer> implements Disposable, EditorColorsListener {
private static final EditorColorsManager editorColorsManager = EditorColorsManager.getInstance(); private static EditorColorsScheme scheme = editorColorsManager.getGlobalScheme(); private static final ColorKey notificationColor = ColorKey.createColorKey("NOTIFICATION_BACKGROUND");
public MessageComponent() { // TODO init some actions...
Color color = scheme.getColor(notificationColor); setBackground(color)
MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(this); connection.subscribe(EditorColorsManager.TOPIC, this); }
@Override public void globalSchemeChange(@Nullable EditorColorsScheme currentColorsScheme) { if (currentColorsScheme == null) { return; } Color color = scheme.getColor(notificationColor); setBackground(color); revalidate(); repaint(); }
@Override public void dispose() { Disposer.dispose(this); }}
Now when you switch themes, the color of the component will automatically change with the color of the theme. Hope this helps.