LayoutManager
.
+ *
+ * @param root Root pane.
+ */
+ private void uninstallLayout(JRootPane root) {
+ if (myOldLayout != null) {
+ root.setLayout(myOldLayout);
+ myOldLayout = null;
+ }
+ }
+
+ /**
+ * Installs the necessary state onto the JRootPane to render client
+ * decorations. This is ONLY invoked if the JRootPane
has a
+ * decoration style other than JRootPane.NONE
.
+ *
+ * @param root Root pane.
+ */
+ private void installClientDecorations(JRootPane root) {
+ installBorder(root);
+
+ JComponent titlePane = createTitlePane(root);
+
+ setTitlePane(root, titlePane);
+ installWindowListeners(root, root.getParent());
+ installLayout(root);
+ if (myWindow != null) {
+ root.revalidate();
+ root.repaint();
+ }
+ }
+
+ private void uninstallClientDecorations(JRootPane root) {
+ uninstallBorder(root);
+ uninstallWindowListeners(root);
+ setTitlePane(root, null);
+ uninstallLayout(root);
+ int style = root.getWindowDecorationStyle();
+ if (style == JRootPane.NONE) {
+ root.repaint();
+ root.revalidate();
+ }
+
+ if (myWindow != null) {
+ myWindow.setCursor(Cursor
+ .getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+ myWindow = null;
+ }
+
+ protected JComponent createTitlePane(JRootPane root) {
+ return new DarculaTitlePane(root, this);
+ }
+
+ private MouseInputListener createWindowMouseInputListener(JRootPane root) {
+ return new MouseInputHandler();
+ }
+
+ protected LayoutManager createLayoutManager() {
+ return new SubstanceRootLayout();
+ }
+
+ private void setTitlePane(JRootPane root, JComponent titlePane) {
+ JLayeredPane layeredPane = root.getLayeredPane();
+ JComponent oldTitlePane = getTitlePane();
+
+ if (oldTitlePane != null) {
+ layeredPane.remove(oldTitlePane);
+ }
+ if (titlePane != null) {
+ layeredPane.add(titlePane, JLayeredPane.FRAME_CONTENT_LAYER);
+ titlePane.setVisible(true);
+ }
+ myTitlePane = titlePane;
+ }
+
+ public void setMaximized() {
+ Component tla = myRootPane.getTopLevelAncestor();
+ GraphicsConfiguration gc = (currentRootPaneGC != null) ? currentRootPaneGC
+ : tla.getGraphicsConfiguration();
+ Rectangle screenBounds = gc.getBounds();
+ screenBounds.x = 0;
+ screenBounds.y = 0;
+ Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
+ Rectangle maxBounds = new Rectangle(
+ (screenBounds.x + screenInsets.left),
+ (screenBounds.y + screenInsets.top), screenBounds.width
+ - ((screenInsets.left + screenInsets.right)),
+ screenBounds.height
+ - ((screenInsets.top + screenInsets.bottom)));
+ if (tla instanceof JFrame) {
+ ((JFrame)tla).setMaximizedBounds(maxBounds);
+ }
+ }
+
+ public JComponent getTitlePane() {
+ return myTitlePane;
+ }
+
+ protected JRootPane getRootPane() {
+ return myRootPane;
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent e) {
+ super.propertyChange(e);
+
+ String propertyName = e.getPropertyName();
+ if (propertyName == null) {
+ return;
+ }
+
+ if (propertyName.equals("windowDecorationStyle")) {
+ JRootPane root = (JRootPane)e.getSource();
+ int style = root.getWindowDecorationStyle();
+
+ uninstallClientDecorations(root);
+ if (style != JRootPane.NONE) {
+ installClientDecorations(root);
+ }
+ }
+ if (propertyName.equals("ancestor")) {
+ uninstallWindowListeners(myRootPane);
+ if (((JRootPane)e.getSource()).getWindowDecorationStyle() != JRootPane.NONE) {
+ installWindowListeners(myRootPane, myRootPane.getParent());
+ }
+ }
+ }
+
+ protected class SubstanceRootLayout implements LayoutManager2 {
+ public Dimension preferredLayoutSize(Container parent) {
+ Dimension cpd, mbd, tpd;
+ int cpWidth = 0;
+ int cpHeight = 0;
+ int mbWidth = 0;
+ int mbHeight = 0;
+ int tpWidth = 0;
+ int tpHeight = 0;
+ Insets i = parent.getInsets();
+ JRootPane root = (JRootPane)parent;
+
+ if (root.getContentPane() != null) {
+ cpd = root.getContentPane().getPreferredSize();
+ }
+ else {
+ cpd = root.getSize();
+ }
+ if (cpd != null) {
+ cpWidth = cpd.width;
+ cpHeight = cpd.height;
+ }
+
+ if (root.getJMenuBar() != null) {
+ mbd = root.getJMenuBar().getPreferredSize();
+ if (mbd != null) {
+ mbWidth = mbd.width;
+ mbHeight = mbd.height;
+ }
+ }
+
+ if ((root.getWindowDecorationStyle() != JRootPane.NONE)
+ && (root.getUI() instanceof DarculaRootPaneUI)) {
+ JComponent titlePane = ((DarculaRootPaneUI)root.getUI()).getTitlePane();
+ if (titlePane != null) {
+ tpd = titlePane.getPreferredSize();
+ if (tpd != null) {
+ tpWidth = tpd.width;
+ tpHeight = tpd.height;
+ }
+ }
+ }
+
+ return new Dimension(Math.max(Math.max(cpWidth, mbWidth), tpWidth)
+ + i.left + i.right, cpHeight + mbHeight + tpHeight + i.top
+ + i.bottom);
+ }
+
+ public Dimension minimumLayoutSize(Container parent) {
+ Dimension cpd, mbd, tpd;
+ int cpWidth = 0;
+ int cpHeight = 0;
+ int mbWidth = 0;
+ int mbHeight = 0;
+ int tpWidth = 0;
+ int tpHeight = 0;
+ Insets i = parent.getInsets();
+ JRootPane root = (JRootPane)parent;
+
+ if (root.getContentPane() != null) {
+ cpd = root.getContentPane().getMinimumSize();
+ }
+ else {
+ cpd = root.getSize();
+ }
+ if (cpd != null) {
+ cpWidth = cpd.width;
+ cpHeight = cpd.height;
+ }
+
+ if (root.getJMenuBar() != null) {
+ mbd = root.getJMenuBar().getMinimumSize();
+ if (mbd != null) {
+ mbWidth = mbd.width;
+ mbHeight = mbd.height;
+ }
+ }
+ if ((root.getWindowDecorationStyle() != JRootPane.NONE)
+ && (root.getUI() instanceof DarculaRootPaneUI)) {
+ JComponent titlePane = ((DarculaRootPaneUI)root.getUI())
+ .getTitlePane();
+ if (titlePane != null) {
+ tpd = titlePane.getMinimumSize();
+ if (tpd != null) {
+ tpWidth = tpd.width;
+ tpHeight = tpd.height;
+ }
+ }
+ }
+
+ return new Dimension(Math.max(Math.max(cpWidth, mbWidth), tpWidth)
+ + i.left + i.right, cpHeight + mbHeight + tpHeight + i.top
+ + i.bottom);
+ }
+
+ public Dimension maximumLayoutSize(Container target) {
+ Dimension cpd, mbd, tpd;
+ int cpWidth = Integer.MAX_VALUE;
+ int cpHeight = Integer.MAX_VALUE;
+ int mbWidth = Integer.MAX_VALUE;
+ int mbHeight = Integer.MAX_VALUE;
+ int tpWidth = Integer.MAX_VALUE;
+ int tpHeight = Integer.MAX_VALUE;
+ Insets i = target.getInsets();
+ JRootPane root = (JRootPane)target;
+
+ if (root.getContentPane() != null) {
+ cpd = root.getContentPane().getMaximumSize();
+ if (cpd != null) {
+ cpWidth = cpd.width;
+ cpHeight = cpd.height;
+ }
+ }
+
+ if (root.getJMenuBar() != null) {
+ mbd = root.getJMenuBar().getMaximumSize();
+ if (mbd != null) {
+ mbWidth = mbd.width;
+ mbHeight = mbd.height;
+ }
+ }
+
+ if ((root.getWindowDecorationStyle() != JRootPane.NONE)
+ && (root.getUI() instanceof DarculaRootPaneUI)) {
+ JComponent titlePane = ((DarculaRootPaneUI)root.getUI())
+ .getTitlePane();
+ if (titlePane != null) {
+ tpd = titlePane.getMaximumSize();
+ if (tpd != null) {
+ tpWidth = tpd.width;
+ tpHeight = tpd.height;
+ }
+ }
+ }
+
+ int maxHeight = Math.max(Math.max(cpHeight, mbHeight), tpHeight);
+ if (maxHeight != Integer.MAX_VALUE) {
+ maxHeight = cpHeight + mbHeight + tpHeight + i.top + i.bottom;
+ }
+
+ int maxWidth = Math.max(Math.max(cpWidth, mbWidth), tpWidth);
+
+ if (maxWidth != Integer.MAX_VALUE) {
+ maxWidth += i.left + i.right;
+ }
+
+ return new Dimension(maxWidth, maxHeight);
+ }
+
+ public void layoutContainer(Container parent) {
+ JRootPane root = (JRootPane)parent;
+ Rectangle b = root.getBounds();
+ Insets i = root.getInsets();
+ int nextY = 0;
+ int w = b.width - i.right - i.left;
+ int h = b.height - i.top - i.bottom;
+
+ if (root.getLayeredPane() != null) {
+ root.getLayeredPane().setBounds(i.left, i.top, w, h);
+ }
+ if (root.getGlassPane() != null) {
+ root.getGlassPane().setBounds(i.left, i.top, w, h);
+ }
+
+ if ((root.getWindowDecorationStyle() != JRootPane.NONE)
+ && (root.getUI() instanceof DarculaRootPaneUI)) {
+ JComponent titlePane = ((DarculaRootPaneUI)root.getUI())
+ .getTitlePane();
+ if (titlePane != null) {
+ Dimension tpd = titlePane.getPreferredSize();
+ if (tpd != null) {
+ int tpHeight = tpd.height;
+ titlePane.setBounds(0, 0, w, tpHeight);
+ nextY += tpHeight;
+ }
+ }
+ }
+ if (root.getJMenuBar() != null) {
+ Dimension mbd = root.getJMenuBar().getPreferredSize();
+ root.getJMenuBar().setBounds(0, nextY, w, mbd.height);
+ nextY += mbd.height;
+ }
+ if (root.getContentPane() != null) {
+
+ root.getContentPane().setBounds(0, nextY, w, h < nextY ? 0 : h - nextY);
+ }
+ }
+
+ public void addLayoutComponent(String name, Component comp) {
+ }
+
+ public void removeLayoutComponent(Component comp) {
+ }
+
+ public void addLayoutComponent(Component comp, Object constraints) {
+ }
+
+ public float getLayoutAlignmentX(Container target) {
+ return 0.0f;
+ }
+
+ public float getLayoutAlignmentY(Container target) {
+ return 0.0f;
+ }
+
+ public void invalidateLayout(Container target) {
+ }
+ }
+
+ private static final int[] cursorMapping = new int[]{
+ Cursor.NW_RESIZE_CURSOR, Cursor.NW_RESIZE_CURSOR,
+ Cursor.N_RESIZE_CURSOR, Cursor.NE_RESIZE_CURSOR,
+ Cursor.NE_RESIZE_CURSOR, Cursor.NW_RESIZE_CURSOR, 0, 0, 0,
+ Cursor.NE_RESIZE_CURSOR, Cursor.W_RESIZE_CURSOR, 0, 0, 0,
+ Cursor.E_RESIZE_CURSOR, Cursor.SW_RESIZE_CURSOR, 0, 0, 0,
+ Cursor.SE_RESIZE_CURSOR, Cursor.SW_RESIZE_CURSOR,
+ Cursor.SW_RESIZE_CURSOR, Cursor.S_RESIZE_CURSOR,
+ Cursor.SE_RESIZE_CURSOR, Cursor.SE_RESIZE_CURSOR};
+
+ private class MouseInputHandler implements MouseInputListener {
+ private boolean isMovingWindow;
+ private int dragCursor;
+ private int dragOffsetX;
+ private int dragOffsetY;
+ private int dragWidth;
+ private int dragHeight;
+
+ @SuppressWarnings("unchecked")
+ private final PrivilegedExceptionAction getLocationAction = new PrivilegedExceptionAction() {
+ public Object run() throws HeadlessException {
+ return MouseInfo.getPointerInfo().getLocation();
+ }
+ };
+
+ public void mousePressed(MouseEvent ev) {
+ JRootPane rootPane = getRootPane();
+
+ if (rootPane.getWindowDecorationStyle() == JRootPane.NONE) {
+ return;
+ }
+ Point dragWindowOffset = ev.getPoint();
+ Window w = (Window)ev.getSource();
+ if (w != null) {
+ w.toFront();
+ }
+ Point convertedDragWindowOffset = SwingUtilities.convertPoint(w, dragWindowOffset, getTitlePane());
+
+ Frame f = null;
+ Dialog d = null;
+
+ if (w instanceof Frame) {
+ f = (Frame)w;
+ }
+ else if (w instanceof Dialog) {
+ d = (Dialog)w;
+ }
+
+ int frameState = (f != null) ? f.getExtendedState() : 0;
+
+ if ((getTitlePane() != null)
+ && getTitlePane().contains(
+ convertedDragWindowOffset)) {
+ if ((((f != null) && ((frameState & Frame.MAXIMIZED_BOTH) == 0)) || (d != null))
+ && (dragWindowOffset.y >= BORDER_DRAG_THICKNESS)
+ && (dragWindowOffset.x >= BORDER_DRAG_THICKNESS)
+ && (dragWindowOffset.x < w.getWidth() - BORDER_DRAG_THICKNESS)) {
+ isMovingWindow = true;
+ dragOffsetX = dragWindowOffset.x;
+ dragOffsetY = dragWindowOffset.y;
+ }
+ }
+ else if (((f != null) && f.isResizable() && ((frameState & Frame.MAXIMIZED_BOTH) == 0))
+ || ((d != null) && d.isResizable())) {
+ dragOffsetX = dragWindowOffset.x;
+ dragOffsetY = dragWindowOffset.y;
+ dragWidth = w.getWidth();
+ dragHeight = w.getHeight();
+ dragCursor = getCursor(calculateCorner(w,
+ dragWindowOffset.x, dragWindowOffset.y));
+ }
+ }
+
+ public void mouseReleased(MouseEvent ev) {
+ if ((dragCursor != 0)
+ && (myWindow != null)
+ && !myWindow.isValid()) {
+ myWindow.validate();
+ getRootPane().repaint();
+ }
+ isMovingWindow = false;
+ dragCursor = 0;
+ }
+
+ public void mouseMoved(MouseEvent ev) {
+ JRootPane root = getRootPane();
+
+ if (root.getWindowDecorationStyle() == JRootPane.NONE) {
+ return;
+ }
+
+ Window w = (Window)ev.getSource();
+
+ Frame f = null;
+ Dialog d = null;
+
+ if (w instanceof Frame) {
+ f = (Frame)w;
+ }
+ else if (w instanceof Dialog) {
+ d = (Dialog)w;
+ }
+
+ int cursor = getCursor(calculateCorner(w, ev.getX(), ev.getY()));
+
+ if ((cursor != 0)
+ && (((f != null) && (f.isResizable() && ((f.getExtendedState() & Frame.MAXIMIZED_BOTH) == 0)))
+ || ((d != null) && d.isResizable()))) {
+ w.setCursor(Cursor.getPredefinedCursor(cursor));
+ }
+ else {
+ w.setCursor(myLastCursor);
+ }
+ }
+
+ private void adjust(Rectangle bounds, Dimension min, int deltaX,
+ int deltaY, int deltaWidth, int deltaHeight) {
+ bounds.x += deltaX;
+ bounds.y += deltaY;
+ bounds.width += deltaWidth;
+ bounds.height += deltaHeight;
+ if (min != null) {
+ if (bounds.width < min.width) {
+ int correction = min.width - bounds.width;
+ if (deltaX != 0) {
+ bounds.x -= correction;
+ }
+ bounds.width = min.width;
+ }
+ if (bounds.height < min.height) {
+ int correction = min.height - bounds.height;
+ if (deltaY != 0) {
+ bounds.y -= correction;
+ }
+ bounds.height = min.height;
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void mouseDragged(MouseEvent ev) {
+ Window w = (Window)ev.getSource();
+ Point pt = ev.getPoint();
+
+ if (isMovingWindow) {
+ Point windowPt;
+ try {
+ windowPt = (Point)AccessController
+ .doPrivileged(getLocationAction);
+ windowPt.x = windowPt.x - dragOffsetX;
+ windowPt.y = windowPt.y - dragOffsetY;
+ w.setLocation(windowPt);
+ }
+ catch (PrivilegedActionException e) {
+ }
+ }
+ else if (dragCursor != 0) {
+ Rectangle r = w.getBounds();
+ Rectangle startBounds = new Rectangle(r);
+ Dimension min = w.getMinimumSize();
+
+ switch (dragCursor) {
+ case Cursor.E_RESIZE_CURSOR:
+ adjust(r, min, 0, 0, pt.x
+ + (dragWidth - dragOffsetX) - r.width, 0);
+ break;
+ case Cursor.S_RESIZE_CURSOR:
+ adjust(r, min, 0, 0, 0, pt.y
+ + (dragHeight - dragOffsetY) - r.height);
+ break;
+ case Cursor.N_RESIZE_CURSOR:
+ adjust(r, min, 0, pt.y - dragOffsetY, 0,
+ -(pt.y - dragOffsetY));
+ break;
+ case Cursor.W_RESIZE_CURSOR:
+ adjust(r, min, pt.x - dragOffsetX, 0,
+ -(pt.x - dragOffsetX), 0);
+ break;
+ case Cursor.NE_RESIZE_CURSOR:
+ adjust(r, min, 0, pt.y - dragOffsetY, pt.x
+ + (dragWidth - dragOffsetX) - r.width,
+ -(pt.y - dragOffsetY));
+ break;
+ case Cursor.SE_RESIZE_CURSOR:
+ adjust(r, min, 0, 0, pt.x
+ + (dragWidth - dragOffsetX) - r.width,
+ pt.y + (dragHeight - dragOffsetY)
+ - r.height);
+ break;
+ case Cursor.NW_RESIZE_CURSOR:
+ adjust(r, min, pt.x - dragOffsetX, pt.y
+ - dragOffsetY, -(pt.x - dragOffsetX),
+ -(pt.y - dragOffsetY));
+ break;
+ case Cursor.SW_RESIZE_CURSOR:
+ adjust(r, min, pt.x - dragOffsetX, 0,
+ -(pt.x - dragOffsetX), pt.y
+ + (dragHeight - dragOffsetY)
+ - r.height);
+ break;
+ default:
+ break;
+ }
+ if (!r.equals(startBounds)) {
+ w.setBounds(r);
+ if (Toolkit.getDefaultToolkit().isDynamicLayoutActive()) {
+ w.validate();
+ getRootPane().repaint();
+ }
+ }
+ }
+ }
+
+ private CursorState cursorState = CursorState.NIL;
+
+ public void mouseEntered(MouseEvent ev) {
+ Window w = (Window)ev.getSource();
+ if (cursorState == CursorState.EXITED || cursorState == CursorState.NIL) {
+ myLastCursor = w.getCursor();
+ }
+ cursorState = CursorState.ENTERED;
+ mouseMoved(ev);
+ }
+
+ public void mouseExited(MouseEvent ev) {
+ Window w = (Window)ev.getSource();
+ w.setCursor(myLastCursor);
+ cursorState = CursorState.EXITED;
+ }
+
+ public void mouseClicked(MouseEvent ev) {
+ Window w = (Window)ev.getSource();
+ Frame f;
+
+ if (w instanceof Frame) {
+ f = (Frame)w;
+ }
+ else {
+ return;
+ }
+
+ JComponent windowTitlePane = getTitlePane();
+ if (windowTitlePane == null) {
+ return;
+ }
+
+ Point convertedPoint = SwingUtilities.convertPoint(w, ev.getPoint(), windowTitlePane);
+
+ int state = f.getExtendedState();
+ if (windowTitlePane.contains(convertedPoint)) {
+ if (((ev.getClickCount() % 2) == 0)
+ && ((ev.getModifiers() & InputEvent.BUTTON1_MASK) != 0)) {
+ if (f.isResizable()) {
+ if ((state & Frame.MAXIMIZED_BOTH) != 0) {
+ setMaximized();
+ f.setExtendedState(state & ~Frame.MAXIMIZED_BOTH);
+ }
+ else {
+ setMaximized();
+ f.setExtendedState(state | Frame.MAXIMIZED_BOTH);
+ }
+ }
+ }
+ }
+ }
+
+ private int calculateCorner(Window w, int x, int y) {
+ Insets insets = w.getInsets();
+ int xPosition = calculatePosition(x - insets.left, w
+ .getWidth()
+ - insets.left - insets.right);
+ int yPosition = calculatePosition(y - insets.top, w
+ .getHeight()
+ - insets.top - insets.bottom);
+
+ if ((xPosition == -1) || (yPosition == -1)) {
+ return -1;
+ }
+ return yPosition * 5 + xPosition;
+ }
+
+ private int getCursor(int corner) {
+ if (corner == -1) {
+ return 0;
+ }
+ return cursorMapping[corner];
+ }
+
+ private int calculatePosition(int spot, int width) {
+ if (spot < BORDER_DRAG_THICKNESS) {
+ return 0;
+ }
+ if (spot < CORNER_DRAG_WIDTH) {
+ return 1;
+ }
+ if (spot >= (width - BORDER_DRAG_THICKNESS)) {
+ return 4;
+ }
+ if (spot >= (width - CORNER_DRAG_WIDTH)) {
+ return 3;
+ }
+ return 2;
+ }
+ }
+
+ private class TitleMouseInputHandler extends MouseInputAdapter {
+ private Point dragOffset = new Point(0, 0);
+
+ @Override
+ public void mousePressed(MouseEvent ev) {
+ JRootPane rootPane = getRootPane();
+
+ if (rootPane.getWindowDecorationStyle() == JRootPane.NONE) {
+ return;
+ }
+
+ Point dragWindowOffset = ev.getPoint();
+ Component source = (Component)ev.getSource();
+
+ Point convertedDragWindowOffset = SwingUtilities.convertPoint(
+ source, dragWindowOffset, getTitlePane());
+
+ dragWindowOffset = SwingUtilities.convertPoint(source, dragWindowOffset, myWindow);
+
+ if (getTitlePane() != null && getTitlePane().contains(convertedDragWindowOffset)) {
+ if (myWindow != null) {
+ myWindow.toFront();
+ dragOffset = dragWindowOffset;
+ }
+ }
+ }
+
+ @Override
+ public void mouseDragged(MouseEvent ev) {
+ Component source = (Component)ev.getSource();
+
+ Point eventLocationOnScreen = ev.getLocationOnScreen();
+ if (eventLocationOnScreen == null) {
+ eventLocationOnScreen = new Point(ev.getX() + source.getLocationOnScreen().x, ev.getY() + source.getLocationOnScreen().y);
+ }
+ if (myWindow instanceof Frame) {
+ Frame f = (Frame)myWindow;
+ int frameState = f.getExtendedState();
+
+ if (((frameState & Frame.MAXIMIZED_BOTH) == 0)) {
+ myWindow.setLocation(eventLocationOnScreen.x - dragOffset.x, eventLocationOnScreen.y - dragOffset.y);
+ }
+ }
+ else {
+ myWindow.setLocation(eventLocationOnScreen.x - dragOffset.x, eventLocationOnScreen.y - dragOffset.y);
+ }
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ Frame f;
+
+ if (myWindow instanceof Frame) {
+ f = (Frame)myWindow;
+ }
+ else {
+ return;
+ }
+
+ Point convertedPoint = SwingUtilities.convertPoint(myWindow, e.getPoint(), getTitlePane());
+
+ int state = f.getExtendedState();
+ if ((getTitlePane() != null) && getTitlePane().contains(convertedPoint)) {
+ if (((e.getClickCount() % 2) == 0) && ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0)) {
+ if (f.isResizable()) {
+ if ((state & Frame.MAXIMIZED_BOTH) != 0) {
+ setMaximized();
+ f.setExtendedState(state & ~Frame.MAXIMIZED_BOTH);
+ }
+ else {
+ setMaximized();
+ f.setExtendedState(state | Frame.MAXIMIZED_BOTH);
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/bulenkov/darcula/ui/DarculaScrollBarUI.java b/src/com/bulenkov/darcula/ui/DarculaScrollBarUI.java
old mode 100644
new mode 100755
index a9a1732..dfbc71e
--- a/src/com/bulenkov/darcula/ui/DarculaScrollBarUI.java
+++ b/src/com/bulenkov/darcula/ui/DarculaScrollBarUI.java
@@ -16,9 +16,12 @@
package com.bulenkov.darcula.ui;
import com.bulenkov.darcula.util.Animator;
-import com.bulenkov.darcula.util.Gray;
+import com.bulenkov.iconloader.util.DoubleColor;
+import com.bulenkov.iconloader.util.Gray;
+import com.bulenkov.iconloader.util.UIUtil;
import javax.swing.*;
+import javax.swing.event.ChangeEvent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicScrollBarUI;
import java.awt.*;
@@ -34,303 +37,321 @@ public class DarculaScrollBarUI extends BasicScrollBarUI {
return new DarculaScrollBarUI();
}
+ public static DoubleColor getGradientLightColor() {
+ return new DoubleColor(Gray._251, Gray._95);
+ }
+ public static DoubleColor getGradientDarkColor() {
+ return new DoubleColor(Gray._215, Gray._80);
+ }
- public static Color getGradientLightColor() {
- return Gray._90;
- }
+ private static DoubleColor getGradientThumbBorderColor() {
+ return new DoubleColor(Gray._201, Gray._85);
+ }
- public static Color getGradientDarkColor() {
- return Gray._70;
- }
+ public static DoubleColor getTrackBackground() {
+ return new DoubleColor(Gray._245, UIUtil.getListBackground());
+ }
- private static Color getGradientThumbBorderColor() {
- return Gray._75;
- }
+ public static DoubleColor getTrackBorderColor() {
+ return new DoubleColor(Gray._230, UIUtil.getListBackground());
+ }
- public static Color getTrackBackground() {
- return UIManager.getColor("control");
- }
+ private static final BasicStroke BORDER_STROKE = new BasicStroke();
- public static Color getTrackBorderColor() {
- return UIManager.getColor("control");
- }
+ private static int getAnimationColorShift() {
+ return UIUtil.isUnderDarcula() ? 20 : 40;
+ }
- private static final BasicStroke BORDER_STROKE = new BasicStroke();
- public static final int ANIMATION_COLOR_SHIFT = 20;
+ private final AdjustmentListener myAdjustmentListener;
+ private final MouseMotionAdapter myMouseMotionListener;
+ private final MouseAdapter myMouseListener;
- private final AdjustmentListener myAdjustmentListener;
- private final MouseMotionAdapter myMouseMotionListener;
- private final MouseAdapter myMouseListener;
+ private Animator myAnimator;
- private Animator myAnimator;
+ private int myAnimationColorShift = 0;
+ private boolean myMouseIsOverThumb = false;
+ public static final int DELAY_FRAMES = 4;
+ public static final int FRAMES_COUNT = 10 + DELAY_FRAMES;
- private int myAnimationColorShift = 0;
- private boolean myMouseIsOverThumb = false;
- public static final int DELAY_FRAMES = 4;
- public static final int FRAMES_COUNT = 10 + DELAY_FRAMES;
+ protected DarculaScrollBarUI() {
+ myAdjustmentListener = new AdjustmentListener() {
+ @Override
+ public void adjustmentValueChanged(AdjustmentEvent e) {
+ resetAnimator();
+ }
+ };
- protected DarculaScrollBarUI() {
- myAdjustmentListener = new AdjustmentListener() {
- @Override
- public void adjustmentValueChanged(AdjustmentEvent e) {
+ myMouseMotionListener = new MouseMotionAdapter() {
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ boolean inside = isOverThumb(e.getPoint());
+ if (inside != myMouseIsOverThumb) {
+ myMouseIsOverThumb = inside;
resetAnimator();
}
- };
-
- myMouseMotionListener = new MouseMotionAdapter() {
- @Override
- public void mouseMoved(MouseEvent e) {
- boolean inside = isOverThumb(e.getPoint());
- if (inside != myMouseIsOverThumb) {
- myMouseIsOverThumb = inside;
- resetAnimator();
- }
- }
- };
-
- myMouseListener = new MouseAdapter() {
- @Override
- public void mouseExited(MouseEvent e) {
- if (myMouseIsOverThumb) {
- myMouseIsOverThumb = false;
- resetAnimator();
- }
+ }
+ };
+
+ myMouseListener = new MouseAdapter() {
+ @Override
+ public void mouseExited(MouseEvent e) {
+ if (myMouseIsOverThumb) {
+ myMouseIsOverThumb = false;
+ resetAnimator();
}
- };
+ }
+ };
+ }
+
+ @Override
+ public void layoutContainer(Container scrollbarContainer) {
+ try {
+ super.layoutContainer(scrollbarContainer);
+ } catch (NullPointerException ignore) {
+ //installUI is not performed yet or uninstallUI has set almost every field to null. Just ignore it //IDEA-89674
}
+ }
- @Override
- public void layoutContainer(Container scrollbarContainer) {
- try {
- super.layoutContainer(scrollbarContainer);
- } catch (NullPointerException ignore) {
- //installUI is not performed yet or uninstallUI has set almost every field to null. Just ignore it //IDEA-89674
+ @Override
+ protected ModelListener createModelListener() {
+ return new ModelListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ if (scrollbar != null) {
+ super.stateChanged(e);
+ }
}
- }
+ };
+ }
+
+ public int getDecrementButtonHeight() {
+ return decrButton.getHeight();
+ }
+ public int getIncrementButtonHeight() {
+ return incrButton.getHeight();
+ }
- public int getDecrementButtonHeight() {
- return decrButton.getHeight();
+ private void resetAnimator() {
+ myAnimator.reset();
+ if (scrollbar != null && scrollbar.getValueIsAdjusting() || myMouseIsOverThumb) {
+ myAnimator.suspend();
+ myAnimationColorShift = getAnimationColorShift();
}
- public int getIncrementButtonHeight() {
- return incrButton.getHeight();
+ else {
+ myAnimator.resume();
}
+ }
- private void resetAnimator() {
- myAnimator.reset();
- if (scrollbar != null && scrollbar.getValueIsAdjusting() || myMouseIsOverThumb) {
- myAnimator.suspend();
- myAnimationColorShift = ANIMATION_COLOR_SHIFT;
- }
- else {
- myAnimator.resume();
- }
- }
+ public static BasicScrollBarUI createNormal() {
+ return new DarculaScrollBarUI();
+ }
+ @Override
+ public void installUI(JComponent c) {
+ super.installUI(c);
+ scrollbar.setFocusable(false);
+ }
- @Override
- public void installUI(JComponent c) {
- super.installUI(c);
- scrollbar.setFocusable(false);
+ @Override
+ protected void installDefaults() {
+ final int incGap = UIManager.getInt("ScrollBar.incrementButtonGap");
+ final int decGap = UIManager.getInt("ScrollBar.decrementButtonGap");
+ try {
+ UIManager.put("ScrollBar.incrementButtonGap", 0);
+ UIManager.put("ScrollBar.decrementButtonGap", 0);
+ super.installDefaults();
}
+ finally {
+ UIManager.put("ScrollBar.incrementButtonGap", incGap);
+ UIManager.put("ScrollBar.decrementButtonGap", decGap);
+ }
+ }
- @Override
- protected void installDefaults() {
- final int incGap = UIManager.getInt("ScrollBar.incrementButtonGap");
- final int decGap = UIManager.getInt("ScrollBar.decrementButtonGap");
- try {
- UIManager.put("ScrollBar.incrementButtonGap", 0);
- UIManager.put("ScrollBar.decrementButtonGap", 0);
- super.installDefaults();
- }
- finally {
- UIManager.put("ScrollBar.incrementButtonGap", incGap);
- UIManager.put("ScrollBar.decrementButtonGap", decGap);
- }
+ @Override
+ protected void installListeners() {
+ if (myAnimator == null || myAnimator.isDisposed()) {
+ myAnimator = createAnimator();
}
- @Override
- protected void installListeners() {
- if (myAnimator == null || myAnimator.isDisposed()) {
- myAnimator = createAnimator();
- }
+ super.installListeners();
+ scrollbar.addAdjustmentListener(myAdjustmentListener);
+ scrollbar.addMouseListener(myMouseListener);
+ scrollbar.addMouseMotionListener(myMouseMotionListener);
+ }
- super.installListeners();
- scrollbar.addAdjustmentListener(myAdjustmentListener);
- scrollbar.addMouseListener(myMouseListener);
- scrollbar.addMouseMotionListener(myMouseMotionListener);
- }
+ private Animator createAnimator() {
+ return new Animator("Adjustment fadeout", FRAMES_COUNT, FRAMES_COUNT * 50, false) {
+ @Override
+ public void paintNow(int frame, int totalFrames, int cycle) {
+ myAnimationColorShift = getAnimationColorShift();
+ if (frame > DELAY_FRAMES) {
+ myAnimationColorShift *= 1 - ((double)(frame - DELAY_FRAMES)) / ((double)(totalFrames - DELAY_FRAMES));
+ }
- private Animator createAnimator() {
- return new Animator("Adjustment fadeout", FRAMES_COUNT, FRAMES_COUNT * 50, false) {
- @Override
- public void paintNow(int frame, int totalFrames, int cycle) {
- myAnimationColorShift = ANIMATION_COLOR_SHIFT;
- if (frame > DELAY_FRAMES) {
- myAnimationColorShift *= 1 - ((double)(frame - DELAY_FRAMES)) / ((double)(totalFrames - DELAY_FRAMES));
- }
-
- if (scrollbar != null) {
- scrollbar.repaint(((DarculaScrollBarUI)scrollbar.getUI()).getThumbBounds());
- }
+ if (scrollbar != null) {
+ scrollbar.repaint(((DarculaScrollBarUI)scrollbar.getUI()).getThumbBounds());
}
- };
- }
+ }
+ };
+ }
- private boolean isOverThumb(Point p) {
- final Rectangle bounds = getThumbBounds();
- return bounds != null && bounds.contains(p);
- }
+ private boolean isOverThumb(Point p) {
+ final Rectangle bounds = getThumbBounds();
+ return bounds != null && bounds.contains(p);
+ }
- @Override
- public Rectangle getThumbBounds() {
- return super.getThumbBounds();
- }
+ @Override
+ public Rectangle getThumbBounds() {
+ return super.getThumbBounds();
+ }
- @Override
- protected void uninstallListeners() {
- if (scrollTimer != null) {
- // it is already called otherwise
- super.uninstallListeners();
- }
- scrollbar.removeAdjustmentListener(myAdjustmentListener);
+ @Override
+ protected void uninstallListeners() {
+ if (scrollTimer != null) {
+ // it is already called otherwise
+ super.uninstallListeners();
}
+ scrollbar.removeAdjustmentListener(myAdjustmentListener);
+ myAnimator.dispose();
+ }
- @Override
- protected void paintTrack(Graphics g, JComponent c, Rectangle bounds) {
- g.setColor(getTrackBackground());
- g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
+ @Override
+ protected void paintTrack(Graphics g, JComponent c, Rectangle bounds) {
+ g.setColor(getTrackBackground());
+ g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
- g.setColor(getTrackBorderColor());
- if (isVertical()) {
- g.drawLine(bounds.x, bounds.y, bounds.x, bounds.y + bounds.height);
- }
- else {
- g.drawLine(bounds.x, bounds.y, bounds.x + bounds.width, bounds.y);
- }
+ g.setColor(getTrackBorderColor());
+ if (isVertical()) {
+ g.drawLine(bounds.x, bounds.y, bounds.x, bounds.y + bounds.height);
}
-
- @Override
- protected Dimension getMinimumThumbSize() {
- final int thickness = getThickness();
- return isVertical() ? new Dimension(thickness, thickness * 2) : new Dimension(thickness * 2, thickness);
+ else {
+ g.drawLine(bounds.x, bounds.y, bounds.x + bounds.width, bounds.y);
}
+ }
- protected int getThickness() {
- return 13;
- }
+ @Override
+ protected Dimension getMinimumThumbSize() {
+ final int thickness = getThickness();
+ return isVertical() ? new Dimension(thickness, thickness * 2) : new Dimension(thickness * 2, thickness);
+ }
- @Override
- public Dimension getMaximumSize(JComponent c) {
- int thickness = getThickness();
- return new Dimension(thickness, thickness);
- }
+ protected int getThickness() {
+ return 13;
+ }
- @Override
- public Dimension getMinimumSize(JComponent c) {
- return getMaximumSize(c);
- }
+ @Override
+ public Dimension getMaximumSize(JComponent c) {
+ int thickness = getThickness();
+ return new Dimension(thickness, thickness);
+ }
- @Override
- public Dimension getPreferredSize(JComponent c) {
- return getMaximumSize(c);
+ @Override
+ public Dimension getMinimumSize(JComponent c) {
+ return getMaximumSize(c);
+ }
+
+ @Override
+ public Dimension getPreferredSize(JComponent c) {
+ return getMaximumSize(c);
+ }
+
+ @Override
+ protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
+ if (thumbBounds.isEmpty() || !scrollbar.isEnabled()) {
+ return;
}
- @Override
- protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
- if (thumbBounds.isEmpty() || !scrollbar.isEnabled()) {
- return;
- }
+ g.translate(thumbBounds.x, thumbBounds.y);
+ paintMaxiThumb((Graphics2D)g, thumbBounds);
+ g.translate(-thumbBounds.x, -thumbBounds.y);
+ }
+
+ private void paintMaxiThumb(Graphics2D g, Rectangle thumbBounds) {
+ final boolean vertical = isVertical();
+ int hGap = vertical ? 2 : 1;
+ int vGap = vertical ? 1 : 2;
- g.translate(thumbBounds.x, thumbBounds.y);
- paintMaxiThumb((Graphics2D)g, thumbBounds);
- g.translate(-thumbBounds.x, -thumbBounds.y);
+ int w = adjustThumbWidth(thumbBounds.width - hGap * 2);
+ int h = thumbBounds.height - vGap * 2;
+
+ // leave one pixel between thumb and right or bottom edge
+ if (vertical) {
+ h -= 1;
+ }
+ else {
+ w -= 1;
}
- private void paintMaxiThumb(Graphics2D g, Rectangle thumbBounds) {
- final boolean vertical = isVertical();
- int hGap = vertical ? 2 : 1;
- int vGap = vertical ? 1 : 2;
+ final Paint paint;
+ final Color start = adjustColor(getGradientLightColor());
+ final Color end = adjustColor(getGradientDarkColor());
- int w = adjustThumbWidth(thumbBounds.width - hGap * 2);
- int h = thumbBounds.height - vGap * 2;
+ if (vertical) {
+ paint = new GradientPaint(1, 0, start, w + 1, 0, end);
+ }
+ else {
+ paint = new GradientPaint(0, 1, start, 0, h + 1, end);
+ }
- // leave one pixel between thumb and right or bottom edge
- if (vertical) {
- h -= 1;
- }
- else {
- w -= 1;
- }
+ g.setPaint(paint);
+ g.fillRect(hGap + 1, vGap + 1, w - 1, h - 1);
- final Paint paint;
- final Color start = adjustColor(getGradientLightColor());
- final Color end = adjustColor(getGradientDarkColor());
+ final Stroke stroke = g.getStroke();
+ g.setStroke(BORDER_STROKE);
+ g.setColor(getGradientThumbBorderColor());
+ g.drawRoundRect(hGap, vGap, w, h, 3, 3);
+ g.setStroke(stroke);
+ }
- if (vertical) {
- paint = new GradientPaint(1, 0, start, w + 1, 0, end);
- }
- else {
- paint = new GradientPaint(0, 1, start, 0, h + 1, end);
- }
+ @Override
+ public boolean getSupportsAbsolutePositioning() {
+ return true;
+ }
- g.setPaint(paint);
- g.fillRect(hGap + 1, vGap + 1, w - 1, h - 1);
+ protected int adjustThumbWidth(int width) {
+ return width;
+ }
- final Stroke stroke = g.getStroke();
- g.setStroke(BORDER_STROKE);
- g.setColor(getGradientThumbBorderColor());
- g.drawRoundRect(hGap, vGap, w, h, 3, 3);
- g.setStroke(stroke);
- }
+ protected Color adjustColor(Color c) {
+ if (myAnimationColorShift == 0) return c;
+ final int sign = UIUtil.isUnderDarcula() ? -1 : 1;
+ return Gray.get(Math.max(0, Math.min(255, c.getRed() - sign * myAnimationColorShift)));
+ }
- @Override
- public boolean getSupportsAbsolutePositioning() {
- return true;
- }
+ private boolean isVertical() {
+ return scrollbar.getOrientation() == Adjustable.VERTICAL;
+ }
- protected int adjustThumbWidth(int width) {
- return width;
- }
+ @Override
+ protected JButton createIncreaseButton(int orientation) {
+ return new EmptyButton();
+ }
- protected Color adjustColor(Color c) {
- if (myAnimationColorShift == 0) return c;
- return Gray.get(c.getRed() + myAnimationColorShift);
- }
+ @Override
+ protected JButton createDecreaseButton(int orientation) {
+ return new EmptyButton();
+ }
- private boolean isVertical() {
- return scrollbar.getOrientation() == Adjustable.VERTICAL;
+ private static class EmptyButton extends JButton {
+ private EmptyButton() {
+ setFocusable(false);
+ setRequestFocusEnabled(false);
}
@Override
- protected JButton createIncreaseButton(int orientation) {
- return new EmptyButton();
+ public Dimension getMaximumSize() {
+ return new Dimension(0, 0);
}
@Override
- protected JButton createDecreaseButton(int orientation) {
- return new EmptyButton();
+ public Dimension getPreferredSize() {
+ return getMaximumSize();
}
- private static class EmptyButton extends JButton {
- private EmptyButton() {
- setFocusable(false);
- setRequestFocusEnabled(false);
- }
-
- @Override
- public Dimension getMaximumSize() {
- return new Dimension(0, 0);
- }
-
- @Override
- public Dimension getPreferredSize() {
- return getMaximumSize();
- }
-
- @Override
- public Dimension getMinimumSize() {
- return getMaximumSize();
- }
+ @Override
+ public Dimension getMinimumSize() {
+ return getMaximumSize();
}
- }
\ No newline at end of file
+ }
+}
diff --git a/src/com/bulenkov/darcula/ui/DarculaSpinnerBorder.java b/src/com/bulenkov/darcula/ui/DarculaSpinnerBorder.java
old mode 100644
new mode 100755
index a68729e..92bc69e
--- a/src/com/bulenkov/darcula/ui/DarculaSpinnerBorder.java
+++ b/src/com/bulenkov/darcula/ui/DarculaSpinnerBorder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,15 @@
package com.bulenkov.darcula.ui;
import com.bulenkov.darcula.DarculaUIUtil;
-import com.bulenkov.darcula.util.GraphicsConfig;
-import com.bulenkov.darcula.util.GraphicsUtil;
-import com.bulenkov.darcula.util.Gray;
-import com.bulenkov.darcula.util.UIUtil;
+import com.bulenkov.iconloader.util.*;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.plaf.InsetsUIResource;
import javax.swing.plaf.UIResource;
import java.awt.*;
+import java.awt.geom.Area;
+import java.awt.geom.RoundRectangle2D;
/**
* @author Konstantin Bulenkov
@@ -36,26 +35,31 @@ public class DarculaSpinnerBorder implements Border, UIResource {
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
final JSpinner spinner = (JSpinner)c;
final JFormattedTextField editor = UIUtil.findComponentOfType(spinner, JFormattedTextField.class);
- final int x1 = x + 3;
+ final int x1 = x + 1;
final int y1 = y + 3;
- final int width1 = width - 8;
+ final int width1 = width - 2;
final int height1 = height - 6;
final boolean focused = c.isEnabled() && c.isVisible() && editor != null && editor.hasFocus();
final GraphicsConfig config = GraphicsUtil.setupAAPainting(g);
if (c.isOpaque()) {
- g.setColor(UIManager.getColor("Panel.background"));
+ g.setColor(UIUtil.getPanelBackground());
g.fillRect(x, y, width, height);
}
- g.setColor(UIManager.getColor("TextField.background"));
+ g.setColor(UIUtil.getTextFieldBackground());
g.fillRoundRect(x1, y1, width1, height1, 5, 5);
- g.setColor(UIManager.getColor("Panel.background"));
+ g.setColor(UIManager.getColor(spinner.isEnabled() ? "Spinner.darcula.enabledButtonColor" : "Spinner.darcula.disabledButtonColor"));
if (editor != null) {
- final int off = editor.getBounds().x + editor.getWidth() + ((JSpinner)c).getInsets().left;
- g.fillRect(off, y1, 17, height1);
- g.setColor(Gray._100);
- g.drawLine(off, y1, off, height1+2);
+ final int off = editor.getBounds().x + editor.getWidth() + ((JSpinner)c).getInsets().left + 1;
+ final Area rect = new Area(new RoundRectangle2D.Double(x1, y1, width1, height1, 5, 5));
+ final Area blueRect = new Area(new Rectangle(off, y1, 22, height1));
+ rect.intersect(blueRect);
+ ((Graphics2D)g).fill(rect);
+ if (UIUtil.isUnderDarcula()) {
+ g.setColor(Gray._100);
+ g.drawLine(off, y1, off, height1 + 2);
+ }
}
if (!c.isEnabled()) {
@@ -63,9 +67,9 @@ public class DarculaSpinnerBorder implements Border, UIResource {
}
if (focused) {
- DarculaUIUtil.paintFocusRing(g, x1, y1, width1, height1);
+ DarculaUIUtil.paintFocusRing(g, x1 + 2, y1, width1 - 3, height1);
} else {
- g.setColor(Gray._100);
+ g.setColor(new DoubleColor(Gray._149,Gray._100));
g.drawRoundRect(x1, y1, width1, height1, 5, 5);
}
config.restore();
@@ -73,7 +77,7 @@ public class DarculaSpinnerBorder implements Border, UIResource {
@Override
public Insets getBorderInsets(Component c) {
- return new InsetsUIResource(6, 7, 6, 7);
+ return new InsetsUIResource(5, 7, 5, 7);
}
@Override
diff --git a/src/com/bulenkov/darcula/ui/DarculaSpinnerUI.java b/src/com/bulenkov/darcula/ui/DarculaSpinnerUI.java
old mode 100644
new mode 100755
index 1a5b680..70fdc40
--- a/src/com/bulenkov/darcula/ui/DarculaSpinnerUI.java
+++ b/src/com/bulenkov/darcula/ui/DarculaSpinnerUI.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,7 @@
*/
package com.bulenkov.darcula.ui;
-import com.bulenkov.darcula.util.GraphicsConfig;
-import com.bulenkov.darcula.util.GraphicsUtil;
+import com.bulenkov.iconloader.util.*;
import javax.swing.*;
import javax.swing.border.Border;
@@ -113,13 +112,14 @@ public class DarculaSpinnerUI extends BasicSpinnerUI {
}
private JButton createArrow(int direction) {
- final Color shadow = UIManager.getColor("Panel.background");
- final Color darkShadow = UIManager.getColor("Label.foreground");
- JButton b = new BasicArrowButton(direction, shadow, shadow, darkShadow, shadow) {
+ final Color shadow = UIUtil.getPanelBackground();
+ final Color enabledColor = new DoubleColor(Gray._255, UIUtil.getLabelForeground());
+ final Color disabledColor = new DoubleColor(Gray._200, UIUtil.getLabelForeground().darker());
+ JButton b = new BasicArrowButton(direction, shadow, shadow, enabledColor, shadow) {
@Override
public void paint(Graphics g) {
int y = direction == NORTH ? getHeight() - 6 : 2;
- paintTriangle(g, 0, y, 0, direction, DarculaSpinnerUI.this.spinner.isEnabled());
+ paintTriangle(g, (getWidth() - 8)/2 - 1, y, 0, direction, DarculaSpinnerUI.this.spinner.isEnabled());
}
@Override
@@ -135,7 +135,7 @@ public class DarculaSpinnerUI extends BasicSpinnerUI {
final int h = 6;
mid = w / 2;
- g.setColor(isEnabled ? darkShadow : darkShadow.darker());
+ g.setColor(isEnabled ? enabledColor : disabledColor);
g.translate(x, y);
switch (direction) {
diff --git a/src/com/bulenkov/darcula/ui/DarculaTabbedPaneUI.java b/src/com/bulenkov/darcula/ui/DarculaTabbedPaneUI.java
old mode 100644
new mode 100755
diff --git a/src/com/bulenkov/darcula/ui/DarculaTest.form b/src/com/bulenkov/darcula/ui/DarculaTest.form
new file mode 100644
index 0000000..296f5ad
--- /dev/null
+++ b/src/com/bulenkov/darcula/ui/DarculaTest.form
@@ -0,0 +1,607 @@
+
+
diff --git a/src/com/bulenkov/darcula/ui/DarculaTextBorder.java b/src/com/bulenkov/darcula/ui/DarculaTextBorder.java
old mode 100644
new mode 100755
index bdca685..ff656a3
--- a/src/com/bulenkov/darcula/ui/DarculaTextBorder.java
+++ b/src/com/bulenkov/darcula/ui/DarculaTextBorder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,10 @@
package com.bulenkov.darcula.ui;
import com.bulenkov.darcula.DarculaUIUtil;
-import com.bulenkov.darcula.util.GraphicsConfig;
-import com.bulenkov.darcula.util.Gray;
+import com.bulenkov.iconloader.util.GraphicsConfig;
+import com.bulenkov.iconloader.util.Gray;
+import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.plaf.InsetsUIResource;
import javax.swing.plaf.UIResource;
@@ -31,7 +32,17 @@ import java.awt.*;
public class DarculaTextBorder implements Border, UIResource {
@Override
public Insets getBorderInsets(Component c) {
- return new InsetsUIResource(4, 7, 4, 7);
+ int vOffset = c instanceof JPasswordField ? 3 : 4;
+ if (DarculaTextFieldUI.isSearchField(c)) {
+ vOffset += 2;
+ }
+ if (DarculaTextFieldUI.isSearchFieldWithHistoryPopup(c)) {
+ return new InsetsUIResource(vOffset, 7 + 16 + 3, vOffset, 7 + 16);
+ } else if (DarculaTextFieldUI.isSearchField(c)) {
+ return new InsetsUIResource(vOffset, 4 + 16 + 3, vOffset, 7 + 16);
+ } else {
+ return new InsetsUIResource(vOffset, 7, vOffset, 7);
+ }
}
@Override
@@ -41,6 +52,7 @@ public class DarculaTextBorder implements Border, UIResource {
@Override
public void paintBorder(Component c, Graphics g2, int x, int y, int width, int height) {
+ if (DarculaTextFieldUI.isSearchField(c)) return;
Graphics2D g = ((Graphics2D)g2);
final GraphicsConfig config = new GraphicsConfig(g);
g.translate(x, y);
diff --git a/src/com/bulenkov/darcula/ui/DarculaTextFieldUI.java b/src/com/bulenkov/darcula/ui/DarculaTextFieldUI.java
old mode 100644
new mode 100755
index 171f780..ecd6f5e
--- a/src/com/bulenkov/darcula/ui/DarculaTextFieldUI.java
+++ b/src/com/bulenkov/darcula/ui/DarculaTextFieldUI.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,10 @@
*/
package com.bulenkov.darcula.ui;
-import com.bulenkov.darcula.util.GraphicsConfig;
+import com.bulenkov.darcula.DarculaUIUtil;
+import com.bulenkov.iconloader.util.GraphicsConfig;
+import com.bulenkov.iconloader.util.Gray;
+import com.bulenkov.iconloader.IconLoader;
import javax.swing.*;
import javax.swing.border.Border;
@@ -23,16 +26,29 @@ import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTextFieldUI;
import javax.swing.text.JTextComponent;
import java.awt.*;
-import java.awt.event.FocusAdapter;
-import java.awt.event.FocusEvent;
+import java.awt.event.*;
/**
* @author Konstantin Bulenkov
*/
public class DarculaTextFieldUI extends BasicTextFieldUI {
+ private static final Icon SEARCH_ICON = IconLoader.findIcon("/com/intellij/ide/ui/laf/darcula/icons/search.png", DarculaTextFieldUI.class, true);
+ private static final Icon SEARCH_WITH_HISTORY_ICON = IconLoader.findIcon("/com/intellij/ide/ui/laf/darcula/icons/searchWithHistory.png", DarculaTextFieldUI.class, true);
+ private static final Icon CLEAR_ICON = IconLoader.findIcon("/com/intellij/ide/ui/laf/darcula/icons/clear.png", DarculaTextFieldUI.class, true);
+
+ private enum SearchAction {POPUP, CLEAR}
+
+ private final JTextField myTextField;
+ protected JLabel myClearIcon;
+ protected JLabel myRecentIcon;
+
+ public DarculaTextFieldUI(JTextField textField) {
+ myTextField = textField;
+ }
@SuppressWarnings("MethodOverridesStaticMethodOfSuperclass")
public static ComponentUI createUI(final JComponent c) {
+ final DarculaTextFieldUI ui = new DarculaTextFieldUI((JTextField)c);
c.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
@@ -44,7 +60,78 @@ public class DarculaTextFieldUI extends BasicTextFieldUI {
c.repaint();
}
});
- return new DarculaTextFieldUI();
+ c.addMouseMotionListener(new MouseMotionAdapter() {
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ if (ui.getComponent() != null && isSearchField(c)) {
+ if (ui.getActionUnder(e) != null) {
+ c.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ } else {
+ c.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
+ }
+ }
+ }
+ });
+ c.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (isSearchField(c)) {
+ final SearchAction action = ui.getActionUnder(e);
+ if (action != null) {
+ switch (action) {
+ case POPUP:
+ ui.showSearchPopup();
+ break;
+ case CLEAR:
+ ((JTextField)c).setText("");
+ break;
+ }
+ e.consume();
+ }
+ }
+ }
+ });
+ return ui;
+ }
+
+ protected void showSearchPopup() {
+ final Object value = getComponent().getClientProperty("JTextField.Search.FindPopup");
+ if (value instanceof JPopupMenu) {
+ final JPopupMenu popup = (JPopupMenu)value;
+ popup.show(getComponent(), getSearchIconCoord().x, getComponent().getHeight());
+ }
+ }
+
+ private SearchAction getActionUnder(MouseEvent e) {
+ final Point cPoint = getClearIconCoord();
+ final Point sPoint = getSearchIconCoord();
+ cPoint.x+=8;
+ cPoint.y+=8;
+ sPoint.x+=8;
+ sPoint.y+=8;
+ final Point ePoint = e.getPoint();
+ return cPoint.distance(ePoint) <= 8 ? SearchAction.CLEAR : sPoint.distance(ePoint) <= 8 ? SearchAction.POPUP : null;
+ }
+
+ protected Rectangle getDrawingRect() {
+ final JTextComponent c = myTextField;
+ final Insets i = c.getInsets();
+ final int x = i.right - 4 - 16;
+ final int y = i.top - 3;
+ final int w = c.getWidth() - i.left - i.right + 16*2 +7*2 - 5;
+ int h = c.getBounds().height - i.top - i.bottom + 4*2 - 3;
+ if (h%2==1) h++;
+ return new Rectangle(x, y, w, h);
+ }
+
+ protected Point getSearchIconCoord() {
+ final Rectangle r = getDrawingRect();
+ return new Point(r.x + 3, r.y + (r.height - 16) / 2 + 1);
+ }
+
+ protected Point getClearIconCoord() {
+ final Rectangle r = getDrawingRect();
+ return new Point(r.x + r.width - 16 - 1, r.y + (r.height - 16) / 2);
}
@Override
@@ -52,12 +139,44 @@ public class DarculaTextFieldUI extends BasicTextFieldUI {
Graphics2D g = (Graphics2D)graphics;
final JTextComponent c = getComponent();
final Container parent = c.getParent();
- if (parent != null) {
+ final Rectangle r = getDrawingRect();
+ if (c.isOpaque() && parent != null) {
g.setColor(parent.getBackground());
g.fillRect(0, 0, c.getWidth(), c.getHeight());
}
+ final GraphicsConfig config = new GraphicsConfig(g);
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
+
final Border border = c.getBorder();
- if (border instanceof DarculaTextBorder) {
+ if (isSearchField(c)) {
+ g.setColor(c.getBackground());
+
+ int radius = r.height-1;
+ g.fillRoundRect(r.x, r.y, r.width, r.height-1, radius, radius);
+ g.setColor(c.isEnabled() ? Gray._100 : new Color(0x535353));
+ if (c.getClientProperty("JTextField.Search.noBorderRing") != Boolean.TRUE) {
+ if (c.hasFocus()) {
+ DarculaUIUtil.paintSearchFocusRing(g, r);
+ } else {
+ g.drawRoundRect(r.x, r.y, r.width, r.height-1, radius, radius);
+ }
+ }
+ Point p = getSearchIconCoord();
+ Icon searchIcon = getComponent().getClientProperty("JTextField.Search.FindPopup") instanceof JPopupMenu ? UIManager.getIcon("TextField.darcula.searchWithHistory.icon") : UIManager.getIcon("TextField.darcula.search.icon");
+ if (searchIcon == null) {
+ searchIcon = IconLoader.findIcon("/com/intellij/ide/ui/laf/icons/search.png", DarculaTextFieldUI.class, true);
+ }
+ searchIcon.paintIcon(null, g, p.x, p.y);
+ if (getComponent().hasFocus() && getComponent().getText().length() > 0) {
+ p = getClearIconCoord();
+ Icon clearIcon = UIManager.getIcon("TextField.darcula.clear.icon");
+ if (clearIcon == null) {
+ clearIcon = IconLoader.findIcon("/com/intellij/ide/ui/laf/icons/clear.png", DarculaTextFieldUI.class, true);
+ }
+ clearIcon.paintIcon(null, g, p.x, p.y);
+ }
+ } else if (border instanceof DarculaTextBorder) {
if (c.isEnabled() && c.isEditable()) {
g.setColor(c.getBackground());
}
@@ -65,17 +184,27 @@ public class DarculaTextFieldUI extends BasicTextFieldUI {
final int height = c.getHeight();
final Insets i = border.getBorderInsets(c);
if (c.hasFocus()) {
- final GraphicsConfig config = new GraphicsConfig(g);
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
-
g.fillRoundRect(i.left - 5, i.top - 2, width - i.right - i.left + 10, height - i.top - i.bottom + 6, 5, 5);
- config.restore();
} else {
g.fillRect(i.left - 5, i.top - 2, width - i.right - i.left + 12, height - i.top - i.bottom + 6);
}
} else {
super.paintBackground(g);
}
+ config.restore();
+ }
+
+ @Override
+ protected void paintSafely(Graphics g) {
+ paintBackground(g);
+ super.paintSafely(g);
+ }
+
+ public static boolean isSearchField(Component c) {
+ return c instanceof JTextField && "search".equals(((JTextField)c).getClientProperty("JTextField.variant"));
+ }
+
+ public static boolean isSearchFieldWithHistoryPopup(Component c) {
+ return isSearchField(c) && ((JTextField)c).getClientProperty("JTextField.Search.FindPopup") instanceof JPopupMenu;
}
}
diff --git a/src/com/bulenkov/darcula/ui/DarculaTitlePane.java b/src/com/bulenkov/darcula/ui/DarculaTitlePane.java
new file mode 100644
index 0000000..fb7aaec
--- /dev/null
+++ b/src/com/bulenkov/darcula/ui/DarculaTitlePane.java
@@ -0,0 +1,729 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.bulenkov.darcula.ui;
+
+import sun.awt.SunToolkit;
+import sun.swing.SwingUtilities2;
+
+import javax.accessibility.AccessibleContext;
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import javax.swing.plaf.UIResource;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.List;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class DarculaTitlePane extends JComponent {
+ private static final int IMAGE_HEIGHT = 16;
+ private static final int IMAGE_WIDTH = 16;
+
+ private PropertyChangeListener myPropertyChangeListener;
+ private JMenuBar myMenuBar;
+ private Action myCloseAction;
+ private Action myIconifyAction;
+ private Action myRestoreAction;
+ private Action myMaximizeAction;
+ private JButton myToggleButton;
+ private JButton myIconifyButton;
+ private JButton myCloseButton;
+ private Icon myMaximizeIcon;
+ private Icon myMinimizeIcon;
+ private Image mySystemIcon;
+ private WindowListener myWindowListener;
+ private Window myWindow;
+ private JRootPane myRootPane;
+ private int myState;
+ private DarculaRootPaneUI rootPaneUI;
+
+
+ private Color myInactiveBackground = UIManager.getColor("inactiveCaption");
+ private Color myInactiveForeground = UIManager.getColor("inactiveCaptionText");
+ private Color myInactiveShadow = UIManager.getColor("inactiveCaptionBorder");
+ private Color myActiveBackground = null;
+ private Color myActiveForeground = null;
+ private Color myActiveShadow = null;
+
+ public DarculaTitlePane(JRootPane root, DarculaRootPaneUI ui) {
+ this.myRootPane = root;
+ rootPaneUI = ui;
+
+ myState = -1;
+
+ installSubcomponents();
+ determineColors();
+ installDefaults();
+
+ setLayout(createLayout());
+ }
+
+ private void uninstall() {
+ uninstallListeners();
+ myWindow = null;
+ removeAll();
+ }
+
+ private void installListeners() {
+ if (myWindow != null) {
+ myWindowListener = createWindowListener();
+ myWindow.addWindowListener(myWindowListener);
+ myPropertyChangeListener = createWindowPropertyChangeListener();
+ myWindow.addPropertyChangeListener(myPropertyChangeListener);
+ }
+ }
+
+ private void uninstallListeners() {
+ if (myWindow != null) {
+ myWindow.removeWindowListener(myWindowListener);
+ myWindow.removePropertyChangeListener(myPropertyChangeListener);
+ }
+ }
+
+ private WindowListener createWindowListener() {
+ return new WindowHandler();
+ }
+
+ private PropertyChangeListener createWindowPropertyChangeListener() {
+ return new PropertyChangeHandler();
+ }
+
+ public JRootPane getRootPane() {
+ return myRootPane;
+ }
+
+ private int getWindowDecorationStyle() {
+ return getRootPane().getWindowDecorationStyle();
+ }
+
+ public void addNotify() {
+ super.addNotify();
+
+ uninstallListeners();
+
+ myWindow = SwingUtilities.getWindowAncestor(this);
+ if (myWindow != null) {
+ if (myWindow instanceof Frame) {
+ setState(((Frame)myWindow).getExtendedState());
+ }
+ else {
+ setState(0);
+ }
+ setActive(myWindow.isActive());
+ installListeners();
+ updateSystemIcon();
+ }
+ }
+
+ public void removeNotify() {
+ super.removeNotify();
+
+ uninstallListeners();
+ myWindow = null;
+ }
+
+ private void installSubcomponents() {
+ int decorationStyle = getWindowDecorationStyle();
+ if (decorationStyle == JRootPane.FRAME) {
+ createActions();
+ myMenuBar = createMenuBar();
+ add(myMenuBar);
+ createButtons();
+ add(myIconifyButton);
+ add(myToggleButton);
+ add(myCloseButton);
+ }
+ else if (decorationStyle == JRootPane.PLAIN_DIALOG ||
+ decorationStyle == JRootPane.INFORMATION_DIALOG ||
+ decorationStyle == JRootPane.ERROR_DIALOG ||
+ decorationStyle == JRootPane.COLOR_CHOOSER_DIALOG ||
+ decorationStyle == JRootPane.FILE_CHOOSER_DIALOG ||
+ decorationStyle == JRootPane.QUESTION_DIALOG ||
+ decorationStyle == JRootPane.WARNING_DIALOG) {
+ createActions();
+ createButtons();
+ add(myCloseButton);
+ }
+ }
+
+ private void determineColors() {
+ switch (getWindowDecorationStyle()) {
+ case JRootPane.FRAME:
+ myActiveBackground = UIManager.getColor("activeCaption");
+ myActiveForeground = UIManager.getColor("activeCaptionText");
+ myActiveShadow = UIManager.getColor("activeCaptionBorder");
+ break;
+ case JRootPane.ERROR_DIALOG:
+ myActiveBackground = UIManager.getColor("OptionPane.errorDialog.titlePane.background");
+ myActiveForeground = UIManager.getColor("OptionPane.errorDialog.titlePane.foreground");
+ myActiveShadow = UIManager.getColor("OptionPane.errorDialog.titlePane.shadow");
+ break;
+ case JRootPane.QUESTION_DIALOG:
+ case JRootPane.COLOR_CHOOSER_DIALOG:
+ case JRootPane.FILE_CHOOSER_DIALOG:
+ myActiveBackground = UIManager.getColor("OptionPane.questionDialog.titlePane.background");
+ myActiveForeground = UIManager.getColor("OptionPane.questionDialog.titlePane.foreground");
+ myActiveShadow = UIManager.getColor("OptionPane.questionDialog.titlePane.shadow");
+ break;
+ case JRootPane.WARNING_DIALOG:
+ myActiveBackground = UIManager.getColor("OptionPane.warningDialog.titlePane.background");
+ myActiveForeground = UIManager.getColor("OptionPane.warningDialog.titlePane.foreground");
+ myActiveShadow = UIManager.getColor("OptionPane.warningDialog.titlePane.shadow");
+ break;
+ case JRootPane.PLAIN_DIALOG:
+ case JRootPane.INFORMATION_DIALOG:
+ default:
+ myActiveBackground = UIManager.getColor("activeCaption");
+ myActiveForeground = UIManager.getColor("activeCaptionText");
+ myActiveShadow = UIManager.getColor("activeCaptionBorder");
+ break;
+ }
+ }
+
+ private void installDefaults() {
+ setFont(UIManager.getFont("InternalFrame.titleFont", getLocale()));
+ }
+
+
+ protected JMenuBar createMenuBar() {
+ myMenuBar = new SystemMenuBar();
+ myMenuBar.setFocusable(false);
+ myMenuBar.setBorderPainted(true);
+ myMenuBar.add(createMenu());
+ return myMenuBar;
+ }
+
+ private void close() {
+ Window window = getWindow();
+
+ if (window != null) {
+ window.dispatchEvent(new WindowEvent(
+ window, WindowEvent.WINDOW_CLOSING));
+ }
+ }
+
+ private void iconify() {
+ Frame frame = getFrame();
+ if (frame != null) {
+ frame.setExtendedState(myState | Frame.ICONIFIED);
+ }
+ }
+
+ private void maximize() {
+ Frame frame = getFrame();
+ if (frame != null) {
+ frame.setExtendedState(myState | Frame.MAXIMIZED_BOTH);
+ }
+ }
+
+ private void restore() {
+ Frame frame = getFrame();
+
+ if (frame == null) {
+ return;
+ }
+
+ if ((myState & Frame.ICONIFIED) != 0) {
+ frame.setExtendedState(myState & ~Frame.ICONIFIED);
+ }
+ else {
+ frame.setExtendedState(myState & ~Frame.MAXIMIZED_BOTH);
+ }
+ }
+
+ private void createActions() {
+ myCloseAction = new CloseAction();
+ if (getWindowDecorationStyle() == JRootPane.FRAME) {
+ myIconifyAction = new IconifyAction();
+ myRestoreAction = new RestoreAction();
+ myMaximizeAction = new MaximizeAction();
+ }
+ }
+
+ private JMenu createMenu() {
+ JMenu menu = new JMenu("");
+ if (getWindowDecorationStyle() == JRootPane.FRAME) {
+ addMenuItems(menu);
+ }
+ return menu;
+ }
+
+ private void addMenuItems(JMenu menu) {
+ menu.add(myRestoreAction);
+ menu.add(myIconifyAction);
+ if (Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) {
+ menu.add(myMaximizeAction);
+ }
+
+ menu.add(new JSeparator());
+
+ menu.add(myCloseAction);
+ }
+
+ private static JButton createButton(String accessibleName, Icon icon, Action action) {
+ JButton button = new JButton();
+ button.setFocusPainted(false);
+ button.setFocusable(false);
+ button.setOpaque(true);
+ button.putClientProperty("paintActive", Boolean.TRUE);
+ button.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, accessibleName);
+ button.setBorder(new EmptyBorder(0, 0, 0, 0));
+ button.setText(null);
+ button.setAction(action);
+ button.setIcon(icon);
+ return button;
+ }
+
+ private void createButtons() {
+ myCloseButton = createButton("Close", UIManager.getIcon("InternalFrame.closeIcon"), myCloseAction);
+
+ if (getWindowDecorationStyle() == JRootPane.FRAME) {
+ myMaximizeIcon = UIManager.getIcon("InternalFrame.maximizeIcon");
+ myMinimizeIcon = UIManager.getIcon("InternalFrame.minimizeIcon");
+
+ myIconifyButton = createButton("Iconify", UIManager.getIcon("InternalFrame.iconifyIcon"), myIconifyAction);
+ myToggleButton = createButton("Maximize", myMaximizeIcon, myRestoreAction);
+ }
+ }
+
+ private LayoutManager createLayout() {
+ return new TitlePaneLayout();
+ }
+
+ private void setActive(boolean active) {
+ myCloseButton.putClientProperty("paintActive", Boolean.valueOf(active));
+
+ if (getWindowDecorationStyle() == JRootPane.FRAME) {
+ myIconifyButton.putClientProperty("paintActive", Boolean.valueOf(active));
+ myToggleButton.putClientProperty("paintActive", Boolean.valueOf(active));
+ }
+
+ getRootPane().repaint();
+ }
+
+ private void setState(int state) {
+ setState(state, false);
+ }
+
+ private void setState(int state, boolean updateRegardless) {
+ Window wnd = getWindow();
+
+ if (wnd != null && getWindowDecorationStyle() == JRootPane.FRAME) {
+ if (myState == state && !updateRegardless) {
+ return;
+ }
+ Frame frame = getFrame();
+
+ if (frame != null) {
+ JRootPane rootPane = getRootPane();
+
+ if (((state & Frame.MAXIMIZED_BOTH) != 0) &&
+ (rootPane.getBorder() == null ||
+ (rootPane.getBorder() instanceof UIResource)) &&
+ frame.isShowing()) {
+ rootPane.setBorder(null);
+ }
+ else if ((state & Frame.MAXIMIZED_BOTH) == 0) {
+ // This is a croak, if state becomes bound, this can
+ // be nuked.
+ rootPaneUI.installBorder(rootPane);
+ }
+ if (frame.isResizable()) {
+ if ((state & Frame.MAXIMIZED_BOTH) != 0) {
+ updateToggleButton(myRestoreAction, myMinimizeIcon);
+ myMaximizeAction.setEnabled(false);
+ myRestoreAction.setEnabled(true);
+ }
+ else {
+ updateToggleButton(myMaximizeAction, myMaximizeIcon);
+ myMaximizeAction.setEnabled(true);
+ myRestoreAction.setEnabled(false);
+ }
+ if (myToggleButton.getParent() == null ||
+ myIconifyButton.getParent() == null) {
+ add(myToggleButton);
+ add(myIconifyButton);
+ revalidate();
+ repaint();
+ }
+ myToggleButton.setText(null);
+ }
+ else {
+ myMaximizeAction.setEnabled(false);
+ myRestoreAction.setEnabled(false);
+ if (myToggleButton.getParent() != null) {
+ remove(myToggleButton);
+ revalidate();
+ repaint();
+ }
+ }
+ }
+ else {
+ // Not contained in a Frame
+ myMaximizeAction.setEnabled(false);
+ myRestoreAction.setEnabled(false);
+ myIconifyAction.setEnabled(false);
+ remove(myToggleButton);
+ remove(myIconifyButton);
+ revalidate();
+ repaint();
+ }
+ myCloseAction.setEnabled(true);
+ myState = state;
+ }
+ }
+
+ private void updateToggleButton(Action action, Icon icon) {
+ myToggleButton.setAction(action);
+ myToggleButton.setIcon(icon);
+ myToggleButton.setText(null);
+ }
+
+ private Frame getFrame() {
+ Window window = getWindow();
+
+ if (window instanceof Frame) {
+ return (Frame)window;
+ }
+ return null;
+ }
+
+ private Window getWindow() {
+ return myWindow;
+ }
+
+ private String getTitle() {
+ Window w = getWindow();
+
+ if (w instanceof Frame) {
+ return ((Frame)w).getTitle();
+ }
+ else if (w instanceof Dialog) {
+ return ((Dialog)w).getTitle();
+ }
+ return null;
+ }
+
+ public void paintComponent(Graphics g) {
+ if (getFrame() != null) {
+ setState(getFrame().getExtendedState());
+ }
+ JRootPane rootPane = getRootPane();
+ Window window = getWindow();
+ boolean leftToRight = (window == null) ?
+ rootPane.getComponentOrientation().isLeftToRight() :
+ window.getComponentOrientation().isLeftToRight();
+ boolean isSelected = (window == null) ? true : window.isActive();
+ int width = getWidth();
+ int height = getHeight();
+
+ Color background;
+ Color foreground;
+ Color darkShadow;
+
+ if (isSelected) {
+ background = myActiveBackground;
+ foreground = myActiveForeground;
+ darkShadow = myActiveShadow;
+ }
+ else {
+ background = myInactiveBackground;
+ foreground = myInactiveForeground;
+ darkShadow = myInactiveShadow;
+ }
+
+ g.setColor(background);
+ g.fillRect(0, 0, width, height);
+
+ g.setColor(darkShadow);
+ g.drawLine(0, height - 1, width, height - 1);
+ g.drawLine(0, 0, 0, 0);
+ g.drawLine(width - 1, 0, width - 1, 0);
+
+ int xOffset = leftToRight ? 5 : width - 5;
+
+ if (getWindowDecorationStyle() == JRootPane.FRAME) {
+ xOffset += leftToRight ? IMAGE_WIDTH + 5 : -IMAGE_WIDTH - 5;
+ }
+
+ String theTitle = getTitle();
+ if (theTitle != null) {
+ FontMetrics fm = SwingUtilities2.getFontMetrics(rootPane, g);
+
+ g.setColor(foreground);
+
+ int yOffset = ((height - fm.getHeight()) / 2) + fm.getAscent();
+
+ Rectangle rect = new Rectangle(0, 0, 0, 0);
+ if (myIconifyButton != null && myIconifyButton.getParent() != null) {
+ rect = myIconifyButton.getBounds();
+ }
+ int titleW;
+
+ if (leftToRight) {
+ if (rect.x == 0) {
+ rect.x = window.getWidth() - window.getInsets().right - 2;
+ }
+ titleW = rect.x - xOffset - 4;
+ theTitle = SwingUtilities2.clipStringIfNecessary(
+ rootPane, fm, theTitle, titleW);
+ }
+ else {
+ titleW = xOffset - rect.x - rect.width - 4;
+ theTitle = SwingUtilities2.clipStringIfNecessary(
+ rootPane, fm, theTitle, titleW);
+ xOffset -= SwingUtilities2.stringWidth(rootPane, fm, theTitle);
+ }
+ int titleLength = SwingUtilities2.stringWidth(rootPane, fm, theTitle);
+ SwingUtilities2.drawString(rootPane, g, theTitle, xOffset, yOffset);
+ xOffset += leftToRight ? titleLength + 5 : -5;
+ }
+ }
+
+ private class CloseAction extends AbstractAction {
+ public CloseAction() {
+ super(UIManager.getString("DarculaTitlePane.closeTitle", getLocale()));
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ close();
+ }
+ }
+
+
+ private class IconifyAction extends AbstractAction {
+ public IconifyAction() {
+ super(UIManager.getString("DarculaTitlePane.iconifyTitle", getLocale()));
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ iconify();
+ }
+ }
+
+
+ private class RestoreAction extends AbstractAction {
+ public RestoreAction() {
+ super(UIManager.getString
+ ("DarculaTitlePane.restoreTitle", getLocale()));
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ restore();
+ }
+ }
+
+
+ private class MaximizeAction extends AbstractAction {
+ public MaximizeAction() {
+ super(UIManager.getString("DarculaTitlePane.maximizeTitle", getLocale()));
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ maximize();
+ }
+ }
+
+
+ private class SystemMenuBar extends JMenuBar {
+ public void paint(Graphics g) {
+ if (isOpaque()) {
+ g.setColor(getBackground());
+ g.fillRect(0, 0, getWidth(), getHeight());
+ }
+
+ if (mySystemIcon != null) {
+ g.drawImage(mySystemIcon, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null);
+ }
+ else {
+ Icon icon = UIManager.getIcon("InternalFrame.icon");
+
+ if (icon != null) {
+ icon.paintIcon(this, g, 0, 0);
+ }
+ }
+ }
+
+ public Dimension getMinimumSize() {
+ return getPreferredSize();
+ }
+
+ public Dimension getPreferredSize() {
+ Dimension size = super.getPreferredSize();
+
+ return new Dimension(Math.max(IMAGE_WIDTH, size.width),
+ Math.max(size.height, IMAGE_HEIGHT));
+ }
+ }
+
+ private class TitlePaneLayout implements LayoutManager {
+ public void addLayoutComponent(String name, Component c) {
+ }
+
+ public void removeLayoutComponent(Component c) {
+ }
+
+ public Dimension preferredLayoutSize(Container c) {
+ int height = computeHeight();
+ //noinspection SuspiciousNameCombination
+ return new Dimension(height, height);
+ }
+
+ public Dimension minimumLayoutSize(Container c) {
+ return preferredLayoutSize(c);
+ }
+
+ private int computeHeight() {
+ FontMetrics fm = myRootPane.getFontMetrics(getFont());
+ int fontHeight = fm.getHeight();
+ fontHeight += 7;
+ int iconHeight = 0;
+ if (getWindowDecorationStyle() == JRootPane.FRAME) {
+ iconHeight = IMAGE_HEIGHT;
+ }
+
+ return Math.max(fontHeight, iconHeight);
+ }
+
+ public void layoutContainer(Container c) {
+ boolean leftToRight = (myWindow == null) ?
+ getRootPane().getComponentOrientation().isLeftToRight() :
+ myWindow.getComponentOrientation().isLeftToRight();
+
+ int w = getWidth();
+ int x;
+ int y = 3;
+ int spacing;
+ int buttonHeight;
+ int buttonWidth;
+
+ if (myCloseButton != null && myCloseButton.getIcon() != null) {
+ buttonHeight = myCloseButton.getIcon().getIconHeight();
+ buttonWidth = myCloseButton.getIcon().getIconWidth();
+ }
+ else {
+ buttonHeight = IMAGE_HEIGHT;
+ buttonWidth = IMAGE_WIDTH;
+ }
+
+
+ x = leftToRight ? w : 0;
+
+ spacing = 5;
+ x = leftToRight ? spacing : w - buttonWidth - spacing;
+ if (myMenuBar != null) {
+ myMenuBar.setBounds(x, y, buttonWidth, buttonHeight);
+ }
+
+ x = leftToRight ? w : 0;
+ spacing = 4;
+ x += leftToRight ? -spacing - buttonWidth : spacing;
+ if (myCloseButton != null) {
+ myCloseButton.setBounds(x, y, buttonWidth, buttonHeight);
+ }
+
+ if (!leftToRight) x += buttonWidth;
+
+ if (getWindowDecorationStyle() == JRootPane.FRAME) {
+ if (Toolkit.getDefaultToolkit().isFrameStateSupported(
+ Frame.MAXIMIZED_BOTH)) {
+ if (myToggleButton.getParent() != null) {
+ spacing = 10;
+ x += leftToRight ? -spacing - buttonWidth : spacing;
+ myToggleButton.setBounds(x, y, buttonWidth, buttonHeight);
+ if (!leftToRight) {
+ x += buttonWidth;
+ }
+ }
+ }
+
+ if (myIconifyButton != null && myIconifyButton.getParent() != null) {
+ spacing = 2;
+ x += leftToRight ? -spacing - buttonWidth : spacing;
+ myIconifyButton.setBounds(x, y, buttonWidth, buttonHeight);
+ if (!leftToRight) {
+ x += buttonWidth;
+ }
+ }
+ }
+ }
+ }
+
+
+ private class PropertyChangeHandler implements PropertyChangeListener {
+ public void propertyChange(PropertyChangeEvent pce) {
+ String name = pce.getPropertyName();
+
+ if ("resizable".equals(name) || "state".equals(name)) {
+ Frame frame = getFrame();
+
+ if (frame != null) {
+ setState(frame.getExtendedState(), true);
+ }
+ if ("resizable".equals(name)) {
+ getRootPane().repaint();
+ }
+ }
+ else if ("title".equals(name)) {
+ repaint();
+ }
+ else if ("componentOrientation" == name) {
+ revalidate();
+ repaint();
+ }
+ else if ("iconImage" == name) {
+ updateSystemIcon();
+ revalidate();
+ repaint();
+ }
+ }
+ }
+
+ private void updateSystemIcon() {
+ Window window = getWindow();
+ if (window == null) {
+ mySystemIcon = null;
+ return;
+ }
+
+ Listboring, one line descriptions, the Swing! team
is happy to shatter your illusions.
In Swing, they can use HTML to
boring, one line descriptions, the Swing! team
is happy to shatter your illusions.
In Swing, they can use HTML to