| /* |
| * Copyright 2000-2012 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.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(new Color(0x2fd432), new Color(0x287528)); |
| public static final Color RED = new Color(0xd2451e); |
| public static final Color BLUE = new JBColor(new Color(1, 68, 208), JBColor.blue); |
| public static final Color YELLOW = new Color(0xd4b721); |
| |
| 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); |
| } |
| } |