-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathCButton.java
More file actions
257 lines (223 loc) · 8.19 KB
/
Copy pathCButton.java
File metadata and controls
257 lines (223 loc) · 8.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-2012 MIT, All rights reserved
// Released under the MIT License https://raw.github.com/mit-cml/app-inventor/master/mitlicense.txt
package openblocks.codeblockutil;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
/**
* A CButton is a swing-compatible widget that allows clients
* to display an oval button with an optional text.
*
* To add a particular action to this widget, users should invoke
* this.addCButtonListener( new CButtonListener());
*/
public class CButton extends JButton implements MouseListener{
private static final long serialVersionUID = 328149080228L;
/** blur lighting of this button */
static float[] BLUR = {0.10f, 0.10f, 0.10f, 0.10f, 0.30f, 0.10f, 0.10f, 0.10f, 0.10f};
/** the inset of this button */
static final int INSET = 3;
/** The highlighting inset */
static final int HIGHLIGHT_INSET = 2;
/** Focus Flag: true iff mouse is hovering over button */
boolean focus = false;
/** Press Flag: true iff button was pressed but has not been released */
boolean pressed = false;
/** Selected Flag: true iff button was toggled to selected */
boolean selected = false;
/** Color of this button when not pressed */
Color buttonColor;
/** Color of this button when pressed */
Color selectedColor;
/** Color of the foreground when not hovered */
Color foregroundColor = Color.white;
/** Color of the foreground whe hovered */
Color hoveredColor = Color.red;
/**
* Creates a button with text and black buttonColor, and
* white selectedColor
* @param text
*/
public CButton(String text){
this(new Color(30,30,30), Color.gray, text);
}
/**
* Create a button with text;
* @param buttonColor - color when not pressed down
* @param selectedColor - color when pressed down but not released yet
* @param text - textual label of this
*
* @requires buttonColor, selectedColor, text != null
* @effects constructs new CButton
*/
public CButton(Color buttonColor, Color selectedColor, String text){
super();
this.setOpaque(false);
this.buttonColor=buttonColor;
this.selectedColor=selectedColor;
this.setText(text);
this.setFont(new Font("Ariel", Font.BOLD, 14));
this.addMouseListener(this);
this.setPreferredSize(new Dimension(80, 25));
this.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
/**
* Dynamically changes the coloring of the buttons when
* pressed or not pressed.
*
* @param buttonColor
* @param selectedColor
*
* @requires buttonColor, selectedColor != null
* @modifies this.buttonColor && this.seletedColor
* @effects change button coloring to match to inputs
*/
public void setLighting(Color buttonColor, Color selectedColor){
this.buttonColor = buttonColor;
this.selectedColor = selectedColor;
}
public void setTextLighting(Color foregroundColor, Color hoveredColor){
this.foregroundColor = foregroundColor;
this.hoveredColor = hoveredColor;
}
/**
* @modifies this.selected
* @effects toggles selcted flag to value of selected
*/
public void toggleSelected(boolean selected){
this.selected=selected;
this.repaint();
}
/////////////////////////////////////////////////////////////////////////
//Methods below this line should not be
//modified or overriden and affects the Rendering of this button.
///////////////////////
/**
* Prevents textual label from display out of the bounds
* of the this oval shaped button's edges
*/
public Insets getInsets(){
//top, left, bottom, right
return new Insets(0,this.getHeight()/2,0,this.getHeight()/2);
}
/**
* re paints this
*/
public void paint(Graphics g){
//super.paint(g);
//selected color
Color backgroundColor;
if(this.pressed || this.selected){
backgroundColor = this.selectedColor;
}else{
backgroundColor = this.buttonColor;
}
// Set up graphics and buffer
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
BufferedImage buffer = GraphicsManager.gc.createCompatibleImage(this.getWidth(), this.getHeight(), Transparency.TRANSLUCENT);
Graphics2D gb = buffer.createGraphics();
gb.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Set up first layer
int buttonHeight = this.getHeight() - (INSET * 2);
int buttonWidth = this.getWidth() - (INSET * 2);
int arc = buttonHeight;
Color topColoring = backgroundColor.darker();
Color bottomColoring = backgroundColor.darker();
gb.setPaint(new GradientPaint(0, INSET, topColoring, 0, buttonHeight, bottomColoring, false));
// Paint the first layer
gb.fillRoundRect(INSET, INSET, buttonWidth, buttonHeight, arc, arc);
gb.setColor(Color.darkGray);
gb.drawRoundRect(INSET, INSET, buttonWidth, buttonHeight, arc, arc);
// set up paint data fields for second layer
int highlightHeight = buttonHeight - (HIGHLIGHT_INSET * 2);
int highlightWidth = buttonWidth - (HIGHLIGHT_INSET * 2);
int highlightArc = highlightHeight;
topColoring = backgroundColor.brighter().brighter().brighter().brighter();
bottomColoring = backgroundColor.brighter().brighter().brighter().brighter();
// Paint the second layer
gb.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,.8f));
gb.setPaint(new GradientPaint(0,INSET+HIGHLIGHT_INSET,topColoring,0,INSET+HIGHLIGHT_INSET+(highlightHeight/2), backgroundColor.brighter(), false));
gb.setClip(new RoundRectangle2D.Float(INSET+HIGHLIGHT_INSET,INSET+HIGHLIGHT_INSET,highlightWidth,highlightHeight / 2,highlightHeight / 3,highlightHeight /3));
gb.fillRoundRect(INSET+HIGHLIGHT_INSET,INSET+HIGHLIGHT_INSET,highlightWidth,highlightHeight,highlightArc,highlightArc);
// Blur
ConvolveOp blurOp = new ConvolveOp(new Kernel(3, 3, BLUR));
BufferedImage blurredImage = blurOp.filter(buffer, null);
// Draw button
g2.drawImage(blurredImage, 0, 0, null);
// Draw the text (if any)
if (this.getText() != null)
{
if(this.focus){
g2.setColor(hoveredColor);
}else{
g2.setColor(foregroundColor);
}
Font font = g2.getFont().deriveFont((float)(((float)buttonHeight) * .6));
g2.setFont(font);
FontMetrics metrics = g2.getFontMetrics();
Rectangle2D textBounds = metrics.getStringBounds(this.getText(),g2);
float x = (float)((this.getWidth() / 2) - (textBounds.getWidth() / 2));
float y = (float)((this.getHeight() / 2) + (textBounds.getHeight() / 2)) - metrics.getDescent();
g2.drawString(this.getText(),x,y);
}
}
//////////////////////
//Mouse Listeners
//////////////////////
public void addMouseListener(MouseListener l){
super.addMouseListener(l);
}
public void mouseEntered(MouseEvent e) {
this.focus=true;
repaint();
}
public void mouseExited(MouseEvent e) {
this.focus=false;
repaint();
}
public void mousePressed(MouseEvent e) {
if(SwingUtilities.isLeftMouseButton(e))
this.pressed=true;
repaint();
}
public void mouseReleased(MouseEvent e) {
this.pressed=false;
repaint();
}
public void mouseClicked(MouseEvent e) {}
/** debugging */
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new FlowLayout());
f.setSize(500, 75);
CButton c = new CButton("hi");
c.setPreferredSize(new Dimension(400,50));
f.add(c);
f.setVisible(true);
f.repaint();
}
}