diff --git a/platform/icons/src/ide/errorPoint.png b/platform/icons/src/ide/errorPoint.png
new file mode 100644
index 000000000000..2a08c2ff3763
Binary files /dev/null and b/platform/icons/src/ide/errorPoint.png differ
diff --git a/platform/icons/src/ide/errorSign.png b/platform/icons/src/ide/errorSign.png
new file mode 100644
index 000000000000..d4c199143d96
Binary files /dev/null and b/platform/icons/src/ide/errorSign.png differ
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
index 7c1ff707c62e..1a9a6810b74e 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
@@ -25,6 +25,8 @@ import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.StackingPopupDispatcher;
import com.intellij.openapi.util.*;
+import com.intellij.openapi.wm.IdeGlassPaneUtil;
+import com.intellij.openapi.wm.impl.content.GraphicsConfig;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.UIBundle;
import com.intellij.util.Alarm;
@@ -33,6 +35,7 @@ import com.intellij.util.ui.AwtVisitor;
import com.intellij.util.ui.DialogUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -193,11 +196,11 @@ public abstract class DialogWrapper {
//validation
private final Alarm myValidationAlarm = new Alarm(myDisposable);
private int myValidationDelay = 300;
- private static final String OLD_BORDER = "OLD_BORDER";
- private JComponent myLastErrorComponent = null;
private boolean myDisposed = false;
- private Boolean myLastPaintButtonBorder = null;
private boolean myValidationStarted = false;
+ private Icon ERROR_POINT = IconLoader.getIcon("/ide/errorPoint.png");
+ private Icon ERROR_SIGN = IconLoader.getIcon("/ide/errorSign.png");
+ private final ErrorPainter myErrorPainter = new ErrorPainter();
/**
* Allows to postpone first start of validation
@@ -219,80 +222,30 @@ public abstract class DialogWrapper {
return null;
}
- /**
- * Controls components highlighting
- *
- * @return true for problem components highlighting. false otherwise.
- */
- protected boolean isShowErrorBorder() {
- return true;
- }
-
- /**
- * Specifies border color for error highlighting
- *
- * @return color for error highlighting
- */
- protected Color getErrorColor() {
- return Color.RED;
- }
-
public void setValidationDelay(int delay) {
myValidationDelay = delay;
}
- private void reportProblem(final String message, final JComponent comp) {
+ private void reportProblem(final ValidationInfo info) {
+ myErrorPainter.setValidationInfo(info);
+ if (! info.message.equals(myErrorText.myLabel.getText())) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
- if (myDisposed) return;
- if (isShowErrorBorder()) {
- if (myLastErrorComponent != comp) {
- if (myLastErrorComponent != null) {
- myLastErrorComponent.setBorder((Border)myLastErrorComponent.getClientProperty(OLD_BORDER));
- if (myLastErrorComponent instanceof AbstractButton && myLastPaintButtonBorder != null) {
- ((AbstractButton)myLastErrorComponent).setBorderPainted(myLastPaintButtonBorder);
- }
- }
- myLastErrorComponent = comp;
- if (comp != null) {
- if (comp instanceof AbstractButton) {
- myLastPaintButtonBorder = ((AbstractButton)comp).isBorderPainted();
- ((AbstractButton)comp).setBorderPainted(true);
- }
- final Object border = comp.getClientProperty(OLD_BORDER);
- if (border == null) {
- comp.putClientProperty(OLD_BORDER, comp.getBorder());
- }
- comp.setBorder(BorderFactory.createLineBorder(getErrorColor(), 1));
- }
- }
- }
- setErrorText(message);
+ setErrorText(info.message);
+ myPeer.getRootPane().getGlassPane().repaint();
getOKAction().setEnabled(false);
}
-
});
}
-
+ }
private void clearProblems() {
+ myErrorPainter.setValidationInfo(null);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
- if (myDisposed) return;
setErrorText(null);
+ myPeer.getRootPane().getGlassPane().repaint();
getOKAction().setEnabled(true);
- //if (myLastPeerSize != null) {
- // myPeer.setSize(myLastPeerSize.width, myLastPeerSize.height);
- // myLastPeerSize = null;
- //}
- if (myLastErrorComponent != null) {
- myLastErrorComponent.setBorder((Border)myLastErrorComponent.getClientProperty(OLD_BORDER));
- if (myLastPaintButtonBorder != null && myLastErrorComponent instanceof AbstractButton) {
- ((AbstractButton)myLastErrorComponent).setBorderPainted(myLastPaintButtonBorder);
- }
- myLastErrorComponent = null;
- myLastPaintButtonBorder = null;
- }
}
});
}
@@ -924,7 +877,9 @@ public abstract class DialogWrapper {
final JComponent c = createCenterPanel();
if (c != null) {
- centerSection.add(wrap(c, isCenterStrictedToPreferredSize()), BorderLayout.CENTER);
+ final JComponent wrap = wrap(c, isCenterStrictedToPreferredSize());
+ centerSection.add(wrap, BorderLayout.CENTER);
+ IdeGlassPaneUtil.installPainter(wrap, myErrorPainter, myDisposable);
}
final JPanel southSection = new JPanel(new BorderLayout());
@@ -961,7 +916,7 @@ public abstract class DialogWrapper {
if (result == null) {
clearProblems();
} else {
- reportProblem(result.message, result.component);
+ reportProblem(result);
}
if (!myDisposed) {
@@ -971,17 +926,6 @@ public abstract class DialogWrapper {
}, myValidationDelay, ModalityState.current());
}
- public static final class ValidationInfo {
- public final String message;
- public final JComponent component;
-
- public ValidationInfo(String message, JComponent component) {
- this.message = message;
- this.component = component;
- }
- }
-
-
private static JComponent wrap(final JComponent c, boolean strict) {
if (!strict) return c;
@@ -1521,4 +1465,64 @@ public abstract class DialogWrapper {
String getDoNotShowMessage();
}
+
+ private ErrorPaintingType getErrorPaintingType() {
+ return ErrorPaintingType.SIGN;
+ }
+
+ private class ErrorPainter extends AbstractPainter {
+ private ValidationInfo myInfo;
+
+ @Override
+ public void executePaint(Component component, Graphics2D g) {
+ if (myInfo != null && myInfo.component != null) {
+ final JComponent comp = myInfo.component;
+ final int w = comp.getWidth();
+ final int h = comp.getHeight();
+ Point p;
+ switch (getErrorPaintingType()) {
+ case DOT:
+ p = SwingUtilities.convertPoint(comp, 2, h/2 , component);
+ ERROR_POINT.paintIcon(component, g, p.x, p.y);
+ break;
+ case SIGN:
+ p = SwingUtilities.convertPoint(comp, w, 0, component);
+ ERROR_SIGN.paintIcon(component, g, p.x - 8, p.y - 8);
+ break;
+ case LINE:
+ p = SwingUtilities.convertPoint(comp, 0, h, component);
+ final GraphicsConfig config = new GraphicsConfig(g);
+ g.setColor(new Color(255, 0, 0 , 100));
+ g.fillRoundRect(p.x, p.y-2, w, 4, 2, 2);
+ config.restore();
+ break;
+ }
+ }
+ }
+
+ @Override
+ public boolean needsRepaint() {
+ return true;
+ }
+
+ public void setValidationInfo(ValidationInfo info) {
+ myInfo = info;
+ }
+ }
+
+ private static enum ErrorPaintingType {DOT, SIGN, LINE}
+
+ public static final class ValidationInfo {
+ public final String message;
+ public final JComponent component;
+
+ public ValidationInfo(@NotNull String message, JComponent component) {
+ this.message = message;
+ this.component = component;
+ }
+
+ public ValidationInfo(@NotNull String message) {
+ this(message, null);
+ }
+ }
}