001/* 002 * $Id: GradientPreviewPanel.java 4082 2011-11-15 18:39:43Z kschaefe $ 003 * 004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle, 005 * Santa Clara, California 95054, U.S.A. All rights reserved. 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 020 */ 021 022package org.jdesktop.swingx.color; 023 024import java.awt.Color; 025import java.awt.Graphics; 026import java.awt.Graphics2D; 027import java.awt.LinearGradientPaint; 028import java.awt.MultipleGradientPaint; 029import java.awt.Paint; 030import java.awt.RadialGradientPaint; 031import java.awt.RenderingHints; 032import java.awt.event.MouseEvent; 033import java.awt.geom.Point2D; 034import java.util.List; 035import java.util.logging.Logger; 036 037import javax.swing.event.MouseInputAdapter; 038 039import org.jdesktop.swingx.JXGradientChooser; 040import org.jdesktop.swingx.JXPanel; 041import org.jdesktop.swingx.multislider.MultiThumbModel; 042import org.jdesktop.swingx.multislider.Thumb; 043import org.jdesktop.swingx.util.PaintUtils; 044 045/** 046 * <p><b>Dependency</b>: Because this class relies on LinearGradientPaint and 047 * RadialGradientPaint, it requires the optional MultipleGradientPaint.jar</p> 048 * 049 * @author joshy 050 */ 051public class GradientPreviewPanel extends JXPanel { 052 private Paint checker_texture = null; 053 private Point2D start, end; 054 public JXGradientChooser picker; 055 boolean moving_start = false; 056 boolean moving_end = false; 057 private boolean radial = false; 058 private boolean reversed = false; 059 private boolean reflected = false; 060 private boolean repeated = false; 061 private MultipleGradientPaint gradient; 062 063 public GradientPreviewPanel() { 064 start = new Point2D.Float(10,10); 065 end = new Point2D.Float(80,10); 066 checker_texture = PaintUtils.getCheckerPaint(); 067 MouseInputAdapter ma = new GradientMouseHandler(); 068 this.addMouseListener(ma); 069 this.addMouseMotionListener(ma); 070 } 071 072 public void setGradient() { 073 repaint(); 074 } 075 076 public void setGradient(MultipleGradientPaint grad) { 077 MultipleGradientPaint old = getGradient(); 078 if(grad instanceof LinearGradientPaint) { 079 LinearGradientPaint paint = (LinearGradientPaint)grad; 080 this.start = paint.getStartPoint(); 081 this.end = paint.getEndPoint(); 082 } else { 083 RadialGradientPaint paint = (RadialGradientPaint)grad; 084 this.start = paint.getCenterPoint(); 085 this.end = new Point2D.Double(start.getX(),start.getY()+paint.getRadius()); 086 } 087 this.gradient = grad; 088 firePropertyChange("gradient", old, getGradient()); 089 repaint(); 090 } 091 092 public MultipleGradientPaint getGradient() { 093 return this.gradient; 094 } 095 096 public MultipleGradientPaint calculateGradient() { 097 List<Thumb<Color>> stops = getStops(); 098 int len = stops.size(); 099 100 // set up the data for the gradient 101 float[] fractions = new float[len]; 102 Color[] colors = new Color[len]; 103 int i = 0; 104 for (Thumb<Color> thumb : stops) { 105 colors[i] = (Color)thumb.getObject(); 106 fractions[i] = thumb.getPosition(); 107 i++; 108 } 109 110 // get the final gradient 111 this.setGradient(calculateGradient(fractions, colors)); 112 return getGradient(); 113 } 114 115 private MultiThumbModel model; 116 private Logger log = Logger.getLogger(GradientPreviewPanel.class.getName()); 117 118 private List<Thumb<Color>> getStops() { 119 // calculate the color stops 120 return model == null ? null : model.getSortedThumbs(); 121 } 122 123 public void setMultiThumbModel(MultiThumbModel model) { 124 MultiThumbModel old = getMultiThumbModel(); 125 this.model = model; 126 firePropertyChange("multiThumbModel", old, getMultiThumbModel()); 127 } 128 129 public MultiThumbModel getMultiThumbModel() { 130 return this.model; 131 } 132 133 @Override 134 protected void paintComponent(Graphics g) { 135 try { 136 Graphics2D g2 = (Graphics2D)g; 137 138 // fill the background with checker first 139 g2.setPaint(checker_texture); 140 g.fillRect(0,0,getWidth(),getHeight()); 141 142 143 Paint paint = getGradient(); 144 // fill the area 145 if(paint != null) { 146 g2.setPaint(paint); 147 } else { 148 g2.setPaint(Color.black); 149 } 150 151 g.fillRect(0,0,getWidth(),getHeight()); 152 153 drawHandles(g2); 154 } catch (Exception ex) { 155 log .severe("ex: " + ex); 156 } 157 } 158 159 private MultipleGradientPaint calculateGradient(final float[] fractions, final Color[] colors) { 160 // set up the end points 161 Point2D start = this.start; 162 Point2D end = this.end; 163 if(isReversed()) { 164 //if(picker.reversedCheck.isSelected()) { 165 start = this.end; 166 end = this.start; 167 } 168 169 // set up the cycle type 170 MultipleGradientPaint.CycleMethod cycle = MultipleGradientPaint.CycleMethod.NO_CYCLE; 171 if(isRepeated()) { 172 //if(picker.repeatedRadio.isSelected()) { 173 cycle = MultipleGradientPaint.CycleMethod.REPEAT; 174 } 175 if(isReflected()) { 176 //if(picker.reflectedRadio.isSelected()) { 177 cycle = MultipleGradientPaint.CycleMethod.REFLECT; 178 } 179 180 // create the underlying gradient paint 181 MultipleGradientPaint paint = null; 182 if(isRadial()) { //picker.styleCombo.getSelectedItem().toString().equals("Radial")) { 183 paint = new RadialGradientPaint( 184 start, (float)start.distance(end),start, 185 fractions, colors, cycle, MultipleGradientPaint.ColorSpaceType.SRGB, null 186 ); 187 } else { 188 paint = new LinearGradientPaint( 189 (float)start.getX(), 190 (float)start.getY(), 191 (float)end.getX(), 192 (float)end.getY(), 193 fractions,colors,cycle); 194 } 195 return paint; 196 } 197 198 private void drawHandles(final Graphics2D g2) { 199 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 200 RenderingHints.VALUE_ANTIALIAS_ON); 201 // draw the points and gradient line 202 g2.setColor(Color.black); 203 g2.drawOval((int)start.getX()-5,(int)start.getY()-5,10,10); 204 g2.setColor(Color.white); 205 g2.drawOval((int)start.getX()-4,(int)start.getY()-4,8,8); 206 207 g2.setColor(Color.black); 208 g2.drawOval((int)end.getX()-5,(int)end.getY()-5,10,10); 209 g2.setColor(Color.white); 210 g2.drawOval((int)end.getX()-4,(int)end.getY()-4,8,8); 211 212 g2.setColor(Color.darkGray); 213 g2.drawLine((int)start.getX(),(int)start.getY(), 214 (int)end.getX(),(int)end.getY()); 215 g2.setColor(Color.gray); 216 g2.drawLine((int)start.getX()-1,(int)start.getY()-1, 217 (int)end.getX()-1,(int)end.getY()-1); 218 } 219 220 private class GradientMouseHandler extends MouseInputAdapter { 221 222 @Override 223 public void mousePressed(MouseEvent evt) { 224 moving_start = false; 225 moving_end = false; 226 if (evt.getPoint().distance(start) < 5) { 227 moving_start = true; 228 start = evt.getPoint(); 229 return; 230 } 231 232 if (evt.getPoint().distance(end) < 5) { 233 moving_end = true; 234 end = evt.getPoint(); 235 return; 236 } 237 238 start = evt.getPoint(); 239 } 240 241 @Override 242 public void mouseDragged(MouseEvent evt) { 243 if (moving_start) { 244 start = evt.getPoint(); 245 } else { 246 end = evt.getPoint(); 247 } 248 calculateGradient(); 249 repaint(); 250 } 251 } 252 253 public boolean isRadial() { 254 return radial; 255 } 256 257 public void setRadial(boolean radial) { 258 boolean old = isRadial(); 259 this.radial = radial; 260 firePropertyChange("radial", old, isRadial()); 261 } 262 263 public boolean isReversed() { 264 return reversed; 265 } 266 267 public void setReversed(boolean reversed) { 268 boolean old = isReversed(); 269 this.reversed = reversed; 270 firePropertyChange("reversed", old, isReversed()); 271 } 272 273 public boolean isReflected() { 274 return reflected; 275 } 276 277 public void setReflected(boolean reflected) { 278 boolean old = isReflected(); 279 this.reflected = reflected; 280 firePropertyChange("reflected", old, isReflected()); 281 } 282 283 public boolean isRepeated() { 284 return repeated; 285 } 286 287 public void setRepeated(boolean repeated) { 288 boolean old = isRepeated(); 289 this.repeated = repeated; 290 firePropertyChange("repeated", old, isRepeated()); 291 } 292} 293