/* * Copyright 2000-2017 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.intellij.openapi.progress.util; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.ui.GraphicsConfig; import com.intellij.ui.ColorUtil; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; import com.intellij.util.ui.GraphicsUtil; import com.intellij.util.ui.UIUtil; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.geom.Rectangle2D; /** * @author Eugene Belyaev */ public class ColorProgressBar extends JComponent { private static final Dimension PREFERRED_SIZE = new Dimension(146, 17); public static final Color GREEN = new JBColor(() -> { UISettings settings = UISettings.getInstance(); return settings == null || null == settings.getColorBlindness() ? new JBColor(new Color(0x6cad74), new Color(0x4a8c53)) : new JBColor(new Color(0x6ca69c), new Color(0x639990)); }); public static final Color RED = new JBColor(() -> { UISettings settings = UISettings.getInstance(); return settings == null || null == settings.getColorBlindness() ? new JBColor(new Color(0xd67b76), new Color(0xe55757)) : new JBColor(new Color(0xcc7447), new Color(0xcc7447)); }); public static final Color RED_TEXT = new JBColor(new Color(0xb81708), new Color(0xdb5c5c)); public static final Color BLUE = new JBColor(new Color(1, 68, 208), JBColor.blue); public static final Color YELLOW = new JBColor(new Color(0xa67a21), new Color(0x91703a)); private static final Color SHADOW1 = new JBColor(Gray._190, UIUtil.getBorderColor()) ; private static final Color SHADOW2 = Gray._105; private static final int BRICK_WIDTH = 6; private static final int BRICK_SPACE = 1; private static final int INDETERMINATE_BRICKS_DRAW = 5; private static final double INDETERMINATE_INC_OFFSET = 0.02; private double myFraction = 0.0; private Color myColor = BLUE; private double myIndeterminateInc = INDETERMINATE_INC_OFFSET; private boolean myIndeterminate = false; public boolean isIndeterminate() { return myIndeterminate; } public void setIndeterminate(boolean indeterminate) { this.myIndeterminate = indeterminate; } public ColorProgressBar() { updateUI(); } public void setColor(Color color) { myColor = color; if (isDisplayable()) repaint(); } public double getFraction() { return myFraction; } public void setFraction(double fraction) { if (Double.isNaN(fraction)) { fraction = 1.0; } if (myIndeterminate) { if (myFraction >= 1.0) { myIndeterminateInc = -INDETERMINATE_INC_OFFSET; } else if (myFraction <= 0) { myIndeterminateInc = INDETERMINATE_INC_OFFSET; } final boolean changed = myFraction == 0 || getBricksToDraw(myFraction) != getBricksToDraw(myFraction + myIndeterminateInc); myFraction += myIndeterminateInc; if (changed) { repaint(); } } else { boolean changed = myFraction == 0 || getBricksToDraw(myFraction) != getBricksToDraw(fraction); myFraction = fraction; if (changed) { repaint(); } } } private int getBricksToDraw(double fraction) { int bricksTotal = (getWidth() - 8) / (BRICK_WIDTH + BRICK_SPACE); return (int)(bricksTotal * fraction) + 1; } protected void paintComponent(Graphics g) { super.paintComponent(g); final GraphicsConfig config = GraphicsUtil.setupAAPainting(g); Graphics2D g2 = (Graphics2D)g; if (myFraction > 1) { myFraction = 1; } Dimension size = getSize(); g2.setPaint(UIUtil.getListBackground()); Rectangle2D rect = new Rectangle2D.Double(2, 2, size.width - 4, size.height - 4); g2.fill(rect); g2.setPaint(new JBColor(SHADOW1, UIUtil.getBorderColor())); rect.setRect(1, 1, size.width - 2, size.height - 2); g2.drawRoundRect(1, 1, size.width - 2, size.height - 2, 5, 5); g2.setPaint(SHADOW2); g2.drawRoundRect(0, 0, size.width - 2, size.height - 2, 5, 5); int y_center = size.height / 2; int y_steps = size.height / 2 - 3; int alpha_step = y_steps > 0 ? (255 - 70) / y_steps : 255 - 70; int x_offset = 4; g.setClip(4, 3, size.width - 8, size.height - 6); int bricksToDraw = myFraction == 0 ? 0 : getBricksToDraw(myFraction); if (myIndeterminate) { int startFrom = bricksToDraw < INDETERMINATE_BRICKS_DRAW ? 0 : bricksToDraw - INDETERMINATE_BRICKS_DRAW; int endTo = bricksToDraw + INDETERMINATE_BRICKS_DRAW < getBricksToDraw(1) ? bricksToDraw + INDETERMINATE_BRICKS_DRAW : getBricksToDraw(1); for (int i = startFrom; i <= endTo; i++) { g2.setPaint(myColor); int startXOffset = x_offset + (BRICK_WIDTH + BRICK_SPACE) * i; UIUtil.drawLine(g2, startXOffset, y_center, startXOffset + BRICK_WIDTH - 1, y_center); for (int j = 0; j < y_steps; j++) { Color color = ColorUtil.toAlpha(myColor, 255 - alpha_step * (j + 1)); g2.setPaint(color); UIUtil.drawLine(g2, startXOffset, y_center - 1 - j, startXOffset + BRICK_WIDTH - 1, y_center - 1 - j); if (!(y_center % 2 != 0 && j == y_steps - 1)) { UIUtil.drawLine(g2, startXOffset, y_center + 1 + j, startXOffset + BRICK_WIDTH - 1, y_center + 1 + j); } } g2.setColor( ColorUtil.toAlpha(myColor, 255 - alpha_step * (y_steps / 2 + 1))); g2.drawRect(startXOffset, y_center - y_steps, BRICK_WIDTH - 1, size.height - 7); } } else { for (int i = 0; i < bricksToDraw; i++) { g2.setPaint(myColor); UIUtil.drawLine(g2, x_offset, y_center, x_offset + BRICK_WIDTH - 1, y_center); for (int j = 0; j < y_steps; j++) { Color color = ColorUtil.toAlpha(myColor, 255 - alpha_step * (j + 1)); g2.setPaint(color); UIUtil.drawLine(g2, x_offset, y_center - 1 - j, x_offset + BRICK_WIDTH - 1, y_center - 1 - j); if (!(y_center % 2 != 0 && j == y_steps - 1)) { UIUtil.drawLine(g2, x_offset, y_center + 1 + j, x_offset + BRICK_WIDTH - 1, y_center + 1 + j); } } g2.setColor( ColorUtil.toAlpha(myColor, 255 - alpha_step * (y_steps / 2 + 1))); g2.drawRect(x_offset, y_center - y_steps, BRICK_WIDTH - 1, size.height - 7); x_offset += BRICK_WIDTH + BRICK_SPACE; } } config.restore(); } public Dimension getPreferredSize() { return PREFERRED_SIZE; } public Dimension getMaximumSize() { Dimension dimension = getPreferredSize(); dimension.width = Short.MAX_VALUE; return dimension; } public Dimension getMinimumSize() { Dimension dimension = getPreferredSize(); dimension.width = 13; return dimension; } public Color getColor() { return myColor; } @SuppressWarnings({"HardCodedStringLiteral"}) public static void main(String[] args) { JFrame frame = new JFrame("ColorProgressBar Test"); frame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); frame.setSize(800, 600); frame.setLocation(0, 0); Container contentPane = frame.getContentPane(); contentPane.setLayout(new BorderLayout()); final ColorProgressBar colorProgressBar = new ColorProgressBar(); colorProgressBar.setFraction(0.5); colorProgressBar.setIndeterminate(true); contentPane.add(colorProgressBar, BorderLayout.NORTH); frame.setVisible(true); JButton b = new JButton ("X"); b.addActionListener(new ActionListener () { public void actionPerformed(ActionEvent e) { colorProgressBar.setFraction(1); } }); contentPane.add(b, BorderLayout.SOUTH); } }