package com.intellij.diagnostic; import com.intellij.concurrency.JobScheduler; import com.intellij.icons.AllIcons; import com.intellij.ui.ClickListener; import com.intellij.ui.LayeredIcon; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; /** * @author ksafonov */ public class IdeFatalErrorsIcon extends JLabel { public enum State {UnreadErrors, ReadErrors, NoErrors} private final LayeredIcon myIcon; private final ActionListener myListener; private Future myBlinker; private State myState; public IdeFatalErrorsIcon(ActionListener aListener) { myListener = aListener; setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 1)); new ClickListener() { @Override public boolean onClick(@NotNull MouseEvent e, int clickCount) { if (myState != State.NoErrors) { myListener.actionPerformed(null); return true; } return false; } }.installOn(this); myIcon = new LayeredIcon(AllIcons.Ide.FatalError, AllIcons.Ide.FatalError_read, AllIcons.Ide.EmptyFatalError) { @Override public synchronized void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); } @Override public synchronized void setLayerEnabled(int layer, boolean enabled) { super.setLayerEnabled(layer, enabled); } }; setIcon(myIcon); } public void setState(State state) { myState = state; switch (state) { case UnreadErrors: myIcon.setLayerEnabled(0, true); myIcon.setLayerEnabled(1, false); myIcon.setLayerEnabled(2, false); startBlinker(); setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); setToolTipText(IdeMessagePanel.INTERNAL_ERROR_NOTICE); break; case ReadErrors: stopBlinker(); myIcon.setLayerEnabled(0, false); myIcon.setLayerEnabled(1, true); myIcon.setLayerEnabled(2, false); setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); setToolTipText(IdeMessagePanel.INTERNAL_ERROR_NOTICE); break; case NoErrors: // let's keep all this layers stuff for the case if we decide not to hide the icon stopBlinker(); myIcon.setLayerEnabled(0, false); myIcon.setLayerEnabled(1, false); myIcon.setLayerEnabled(2, true); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); setToolTipText(DiagnosticBundle.message("error.notification.empty.text")); break; default: assert false; } repaint(); } private synchronized void startBlinker() { if (myBlinker != null) { return; } myBlinker = JobScheduler.getScheduler().scheduleWithFixedDelay(new Runnable() { boolean enabled = false; @Override public void run() { myIcon.setLayerEnabled(0, enabled); myIcon.setLayerEnabled(1, false); myIcon.setLayerEnabled(2, !enabled); repaint(); enabled = !enabled; } }, 1, 1, TimeUnit.SECONDS); } private synchronized void stopBlinker() { if (myBlinker != null) { myBlinker.cancel(true); myBlinker = null; } } }