2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.openapi
.progress
.util
;
18 import com
.intellij
.util
.ui
.UIUtil
;
22 import java
.awt
.event
.ActionEvent
;
23 import java
.awt
.event
.ActionListener
;
24 import java
.awt
.event
.WindowAdapter
;
25 import java
.awt
.event
.WindowEvent
;
26 import java
.awt
.geom
.Rectangle2D
;
29 * @author Eugene Belyaev
31 public class ColorProgressBar
extends JComponent
{
32 private static final Dimension PREFERRED_SIZE
= new Dimension(146, 17);
34 public static final Color GREEN
= new Color(47, 212, 50);
35 public static final Color RED
= new Color(210, 69, 30);
36 public static final Color BLUE
= new Color(1, 68, 208);
37 public static final Color YELLOW
= new Color(212, 183, 33);
39 private static final Color SHADOW1
= new Color(190, 190, 188);
40 private static final Color SHADOW2
= new Color(105, 103, 106);
42 private static final int BRICK_WIDTH
= 6;
43 private static final int BRICK_SPACE
= 1;
45 private static final int INDETERMINATE_BRICKS_DRAW
= 5;
46 private static final double INDETERMINATE_INC_OFFSET
= 0.02;
48 private double myFraction
= 0.0;
49 private Color myColor
= BLUE
;
51 private double myIndeterminateInc
= INDETERMINATE_INC_OFFSET
;
52 private boolean myIndeterminate
= false;
54 public boolean isIndeterminate() {
55 return myIndeterminate
;
58 public void setIndeterminate(boolean indeterminate
) {
59 this.myIndeterminate
= indeterminate
;
62 public ColorProgressBar() {
66 public void setColor(Color color
) {
68 if (isDisplayable()) repaint();
71 public double getFraction() {
75 public void setFraction(double fraction
) {
76 if (Double
.isNaN(fraction
)) {
80 if (myIndeterminate
) {
81 if (myFraction
>= 1.0) {
82 myIndeterminateInc
= -INDETERMINATE_INC_OFFSET
;
84 else if (myFraction
<= 0) {
85 myIndeterminateInc
= INDETERMINATE_INC_OFFSET
;
88 final boolean changed
= myFraction
== 0 || getBricksToDraw(myFraction
) != getBricksToDraw(myFraction
+ myIndeterminateInc
);
89 myFraction
+= myIndeterminateInc
;
96 boolean changed
= myFraction
== 0 || getBricksToDraw(myFraction
) != getBricksToDraw(fraction
);
97 myFraction
= fraction
;
104 private int getBricksToDraw(double fraction
) {
105 int bricksTotal
= (getWidth() - 8) / (BRICK_WIDTH
+ BRICK_SPACE
);
106 return (int)(bricksTotal
* fraction
) + 1;
109 protected void paintComponent(Graphics g
) {
110 super.paintComponent(g
);
111 if (myFraction
== 0) return;
113 Graphics2D g2
= (Graphics2D
)g
;
114 Object oldAntialiasing
= g2
.getRenderingHint(RenderingHints
.KEY_ANTIALIASING
);
115 g2
.setRenderingHint(RenderingHints
.KEY_ANTIALIASING
, RenderingHints
.VALUE_ANTIALIAS_ON
);
117 if (myFraction
> 1) {
121 Dimension size
= getSize();
123 g2
.setPaint(Color
.WHITE
);
124 Rectangle2D rect
= new Rectangle2D
.Double(2, 2, size
.width
- 4, size
.height
- 4);
127 g2
.setPaint(SHADOW1
);
128 rect
.setRect(1, 1, size
.width
- 3, size
.height
- 3);
130 UIUtil
.drawLine(g2
, 2, 2, 2, 2);
131 UIUtil
.drawLine(g2
, 2, size
.height
- 2, 2, size
.height
- 2);
132 UIUtil
.drawLine(g2
, size
.width
- 2, 2, size
.width
- 2, 2);
133 UIUtil
.drawLine(g2
, 0, 2, 0, 2);
134 UIUtil
.drawLine(g2
, 2, 0, 2, 0);
136 g2
.setPaint(SHADOW2
);
137 UIUtil
.drawLine(g2
, 0, 2, 0, size
.height
- 4);
138 UIUtil
.drawLine(g2
, 1, 1, 1, 1);
139 UIUtil
.drawLine(g2
, 2, 0, size
.width
- 3, 0);
140 UIUtil
.drawLine(g2
, 1, size
.height
- 3, 1, size
.height
- 3);
141 UIUtil
.drawLine(g2
, 2, size
.height
- 2, size
.width
- 3, size
.height
- 2);
142 UIUtil
.drawLine(g2
, size
.width
- 2, 1, size
.width
- 2, 1);
143 UIUtil
.drawLine(g2
, size
.width
- 1, 2, size
.width
- 1, size
.height
- 4);
144 UIUtil
.drawLine(g2
, size
.width
- 2, size
.height
- 3, size
.width
- 2, size
.height
- 3);
146 int y_center
= size
.height
/ 2;
147 int y_steps
= size
.height
/ 2 - 3;
148 int alpha_step
= y_steps
> 0 ?
(255 - 70) / y_steps
: 255 - 70;
151 g
.setClip(4, 3, size
.width
- 8, size
.height
- 6);
153 int bricksToDraw
= getBricksToDraw(myFraction
);
155 if (myIndeterminate
) {
157 int startFrom
= bricksToDraw
< INDETERMINATE_BRICKS_DRAW ?
0 : bricksToDraw
- INDETERMINATE_BRICKS_DRAW
;
158 int endTo
= bricksToDraw
+ INDETERMINATE_BRICKS_DRAW
< getBricksToDraw(1) ? bricksToDraw
+ INDETERMINATE_BRICKS_DRAW
: getBricksToDraw(1);
160 for (int i
= startFrom
; i
<= endTo
; i
++) {
161 g2
.setPaint(myColor
);
163 int startXOffset
= x_offset
+ (BRICK_WIDTH
+ BRICK_SPACE
) * i
;
164 UIUtil
.drawLine(g2
, startXOffset
, y_center
, startXOffset
+ BRICK_WIDTH
- 1, y_center
);
166 for (int j
= 0; j
< y_steps
; j
++) {
167 Color color
= new Color(myColor
.getRed(), myColor
.getGreen(), myColor
.getBlue(), 255 - alpha_step
* (j
+ 1));
169 UIUtil
.drawLine(g2
, startXOffset
, y_center
- 1 - j
, startXOffset
+ BRICK_WIDTH
- 1, y_center
- 1 - j
);
171 if (!(y_center
% 2 != 0 && j
== y_steps
- 1)) {
172 UIUtil
.drawLine(g2
, startXOffset
, y_center
+ 1 + j
, startXOffset
+ BRICK_WIDTH
- 1, y_center
+ 1 + j
);
176 new Color(myColor
.getRed(), myColor
.getGreen(), myColor
.getBlue(), 255 - alpha_step
* (y_steps
/ 2 + 1)));
177 g2
.drawRect(startXOffset
, y_center
- y_steps
, BRICK_WIDTH
- 1, size
.height
- 7);
181 for (int i
= 0; i
< bricksToDraw
; i
++) {
182 g2
.setPaint(myColor
);
183 UIUtil
.drawLine(g2
, x_offset
, y_center
, x_offset
+ BRICK_WIDTH
- 1, y_center
);
184 for (int j
= 0; j
< y_steps
; j
++) {
185 Color color
= new Color(myColor
.getRed(), myColor
.getGreen(), myColor
.getBlue(), 255 - alpha_step
* (j
+ 1));
187 UIUtil
.drawLine(g2
, x_offset
, y_center
- 1 - j
, x_offset
+ BRICK_WIDTH
- 1, y_center
- 1 - j
);
188 if (!(y_center
% 2 != 0 && j
== y_steps
- 1)) {
189 UIUtil
.drawLine(g2
, x_offset
, y_center
+ 1 + j
, x_offset
+ BRICK_WIDTH
- 1, y_center
+ 1 + j
);
193 new Color(myColor
.getRed(), myColor
.getGreen(), myColor
.getBlue(), 255 - alpha_step
* (y_steps
/ 2 + 1)));
194 g2
.drawRect(x_offset
, y_center
- y_steps
, BRICK_WIDTH
- 1, size
.height
- 7);
195 x_offset
+= BRICK_WIDTH
+ BRICK_SPACE
;
199 g2
.setRenderingHint(RenderingHints
.KEY_ANTIALIASING
, oldAntialiasing
);
202 public Dimension
getPreferredSize() {
203 return PREFERRED_SIZE
;
206 public Dimension
getMaximumSize() {
207 Dimension dimension
= getPreferredSize();
208 dimension
.width
= Short
.MAX_VALUE
;
212 public Dimension
getMinimumSize() {
213 Dimension dimension
= getPreferredSize();
214 dimension
.width
= 13;
218 public Color
getColor() {
222 @SuppressWarnings({"HardCodedStringLiteral"})
223 public static void main(String
[] args
) {
224 JFrame frame
= new JFrame("ColorProgressBar Test");
225 frame
.addWindowListener(
226 new WindowAdapter() {
227 public void windowClosing(WindowEvent e
) {
232 frame
.setSize(800, 600);
233 frame
.setLocation(0, 0);
234 Container contentPane
= frame
.getContentPane();
235 contentPane
.setLayout(new BorderLayout());
236 final ColorProgressBar colorProgressBar
= new ColorProgressBar();
237 colorProgressBar
.setFraction(0.5);
238 colorProgressBar
.setIndeterminate(true);
239 contentPane
.add(colorProgressBar
, BorderLayout
.NORTH
);
240 frame
.setVisible(true);
241 JButton b
= new JButton ("X");
242 b
.addActionListener(new ActionListener () {
243 public void actionPerformed(ActionEvent e
) {
244 colorProgressBar
.setFraction(1);
247 contentPane
.add(b
, BorderLayout
.SOUTH
);