渐变 算法 java_java实现渐变效果工具

这个Java程序提供了一个渐变生成器,支持线性和辐射渐变效果。用户可以通过交互方式调整渐变颜色、位置、重复模式等。此外,程序还包含颜色选择窗口,允许用户选择或定制颜色。该工具可用于集成到第三方程序中,实现实时更新渐变效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

packagegradient;importjava.awt.Color;importjava.awt.Dimension;importjava.awt.Graphics;importjava.awt.Graphics2D;importjava.awt.Insets;importjava.awt.LinearGradientPaint;importjava.awt.MultipleGradientPaint;importjava.awt.Paint;importjava.awt.RadialGradientPaint;importjava.awt.RenderingHints;importjava.awt.event.KeyAdapter;importjava.awt.event.KeyEvent;importjava.awt.event.MouseAdapter;importjava.awt.event.MouseEvent;importjava.awt.event.MouseMotionAdapter;importjava.awt.geom.Ellipse2D;importjava.awt.geom.GeneralPath;importjava.awt.geom.Point2D;importjava.awt.geom.Rectangle2D;importjava.util.ArrayList;importjava.util.LinkedList;importjava.util.List;importjavax.swing.JFrame;importjavax.swing.JPanel;importjavax.swing.event.ChangeEvent;importjavax.swing.event.ChangeListener;/*使用方法:

渐变窗体:

a. 左键双击顶点的linear gradient 渐变区,改变渐变超出范围的重复绘制模式.

b. 左键双击fractions小按钮区,创建添加一个新的fraction按钮.

c. 左键双击fractions小按钮,弹出窗口选择窗口选择颜色.

d. 右键双击fractions小按钮,删除此fraction按钮.

e. 按住fractions小按钮可以拖动它,修改fractions的位置.

f. 左键双击辐射渐变区,改变辐射渐变的焦点(focus)到点击位置.

g. 在辐射渐变区按住左键拖动,改变辐射渐变的焦点.

h. 按下f,显示辐射渐变的圆周,为了方便看到更清楚的数据,默认这圆周是隐藏的.

i. 按下c,恢复辐射渐变的焦点到辐射渐变的圆心,焦点默认是与圆心重合.

颜色选择窗体:

a. 单击某一个颜色,则选中此颜色,并在底部的预览区显示出来.但颜色选择窗口不消失.

b. 双击某一个颜色,则选中此颜色,返回给调用者,颜色选择窗口消失.

c. 按下回车键,返回选中的颜色,颜色选择窗口消失.

d. 按下ESC键,返回传给颜色选择窗体的默认色,颜色选择窗口消失.

e. 下部的JSlider依次调节被选中颜色的red, green, blue, alpha,拖动并实时的在预览区显示出调整后颜色.

第三方程序集成使用方法: 在第三方程序中创建一个GradientGenerator对象,并添加到组件的某一部分,

并给此gradientGenerator添加上change listener:

gradientGenerator.addChangeListener(new ChangedListener() {

public void stateChanged(ChangeEvent e) {

float[] fractions = gradientGenerator.getFractons();

Color[] colors = gradientGenerator.getColors();

Point2D focus = gradientGenerator.calculateFocus(center, radius);

repaint(); // 使用这里得到的fractions, colors, focus等去绘制第三方程序中的渐变图形

});

这样,当gradient generator中的数据发生变化时,第三方程序里也会即时的反映出来.

1. 提示,现在Swing支持合建不规则窗体。

2. 此程序中,除了JSlider,其他的部分都是使用Java2D手动计算绘制出来的。

基于上面两点,可以自己创建一个统一的JSlider风格,

然后就可以把整个程序的外观风格做得在所有平台下都是一个样。*/

/*** *^o^*,本程序一惯还是一惯的作风,LGPL协议,什么版权的废话就不整了,希望修改得效果好的朋友给大家分享一下心得,在此权当扔出块板砖,

* 希望能砸出块暖玉来,嗷呜嗷呜嗷呜.*/@SuppressWarnings("serial")public class GradientGenerator extendsJPanel {private int width = 400; //整个Panel的宽度

private int height = 400; //整个Panel的高度

private Insets padding = new Insets(10, 10, 10, 10); //边距

private int thumbRectHeight = 20; //Fraction按钮区的高度

private int linearRectHeight = 40; //线性渐变区域的高度

private int radialRectHeight = 310; //辐射渐变区域的高度

private Ellipse2D radialCircle = new Ellipse2D.Float(); //辐射渐变的圆周

private Point2D focusPoint = new Point2D.Float(); //辐射渐变的焦点

private Point2D pressedPoint = new Point2D.Float(); //鼠标按下时的点

private Rectangle2D linearRect = new Rectangle2D.Float(); //线性渐变区域

private Rectangle2D thumbsRect = new Rectangle2D.Float(); //Fractions按钮区域

private Rectangle2D radialRect = new Rectangle2D.Float(); //辐射渐变区域

private Thumb selectedThumb = null; //被选中的Fraction按钮

private List thumbs = new ArrayList(); //Fractions按钮

private boolean showCircle = false; //显示辐射渐变的圆周

private List changeListeners = new LinkedList();private MultipleGradientPaint.CycleMethod cycleMethod =MultipleGradientPaint.CycleMethod.REFLECT;/*** 返回渐变的fractions数组

*

*@return

*/

public float[] getGradientFractions() {float[] fractions = new float[thumbs.size()];int i = 0;for(Thumb t : thumbs) {

fractions[i]= (float) ((t.getX() - padding.left) /linearRect.getWidth());++i;

}returnfractions;

}/*** 返回渐变的colors数组

*

*@return

*/

publicColor[] getGradientColors() {

Color[] colors= newColor[thumbs.size()];int i = 0;for(Thumb t : thumbs) {

colors[i]=t.getColor();++i;

}returncolors;

}/*** 利用指定圆的圆心和半径和当前的辐射渐变数据,计算相对于指定圆的焦点

*

*@paramcenter

* 圆心

*@paramradius

* 半径

*@return返回相对于指定圆的焦点*/

public Point2D calculateFocus(Point2D center, doubleradius) {

Point2D curCenter= newPoint2D.Double(radialCircle.getCenterX(), radialCircle.getCenterY());double curRadius = radialCircle.getWidth() / 2;double curFocusLen =GeometryUtil.distanceOfPoints(curCenter, focusPoint);double newFocusLen = radius * curFocusLen /curRadius;

Point2D newFocusPoint=GeometryUtil.extentPoint(curCenter, focusPoint, newFocusLen);//先移回原点,再移动到center的位置

newFocusPoint.setLocation(center.getX() -curCenter.getX(),

center.getY()-curCenter.getY());returnnewFocusPoint;

}publicGradientGenerator() {

setFocusable(true); //为了能接收键盘按键事件

afterResized();

resetThumbs(new float[] { 0.0f, 0.5f, 1.0f }, newColor[] { Color.BLACK, Color.BLUE,new Color(255, 255, 255, 220) });

handleEvents();

setBackground(Color.DARK_GRAY);

}//事件处理

private voidhandleEvents() {this.addMouseListener(newMouseAdapter() {

@Overridepublic voidmousePressed(MouseEvent e) {int x =e.getX();int y =e.getY();

pressedPoint.setLocation(x, y);//得到被选中的Thumb

for(Thumb t : thumbs) {if(t.contains(x, y)) {

t.setSelected(true);

selectedThumb=t;break;

}

}

repaint();

}

@Overridepublic voidmouseReleased(MouseEvent e) {for(Thumb t : thumbs) {

t.setSelected(false);

selectedThumb= null;

}

repaint();

}

@Overridepublic voidmouseClicked(MouseEvent e) {int x =e.getX();int y =e.getY();//左键双击

if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {//如果在thumbs里面,则弹出颜色选择器

for(Thumb t : thumbs) {if(t.contains(x, y)) {

changeThumbColor(t);

repaint();return;

}

}//如果不在thumbs里,而在thumbs的区域里,则增加一个thumb

if(thumbsRect.contains(x, y)) {

insertThumbAt(x);

repaint();return;

}//修改focus的位置

if(radialRect.contains(x, y)) {

changeFocusPoint(newPoint2D.Float(x, y));

repaint();return;

}//在Linear rect里面,修改cycle method

if(linearRect.contains(x, y)) {

changeCycleMethod();

repaint();return;

}

}else if (e.getButton() == MouseEvent.BUTTON3 && e.getClickCount() == 2) {//右键双击

removeThumbAt(x, y);return;

}

}

});this.addMouseMotionListener(newMouseMotionAdapter() {

@Overridepublic voidmouseDragged(MouseEvent e) {//拖动滑块

if (selectedThumb != null) {int deltaX = e.getX() - (int) (selectedThumb.getX());int x = selectedThumb.getX() +deltaX;//不能超过边界

int maxRight = (int) (padding.left +linearRect.getWidth());if (x < padding.left || x > maxRight) { return; }int index =thumbs.indexOf(selectedThumb);int prevX =Integer.MIN_VALUE;int nextX =Integer.MAX_VALUE;//只能在前一个和后一个之间移动

if (index - 1 >= 0) {

prevX= (int) (thumbs.get(index - 1).getX());

}if (index + 1

nextX= (int) (thumbs.get(index + 1).getX());

}if (x > prevX && x

selectedThumb.setX(x);

repaint();

}return;

}else if(radialRect.contains(e.getX(), e.getY())) {int deltaX = (int) (e.getX() -pressedPoint.getX());int deltaY = (int) (e.getY() -pressedPoint.getY());

focusPoint.setLocation(focusPoint.getX()+ deltaX, focusPoint.getY() +deltaY);

pressedPoint.setLocation(e.getX(), e.getY());

repaint();

}

}

});this.addKeyListener(newKeyAdapter() {

@Overridepublic voidkeyReleased(KeyEvent e) {switch(e.getKeyCode()) {caseKeyEvent.VK_F:

showCircle= !showCircle;break;caseKeyEvent.VK_C:

changeFocusPoint(radialCircle.getCenterX(), radialCircle.getCenterY());break;

}

repaint();

}

});

}//执行监听器的事件

public voidfireChangeEvent() {for(ChangeListener l : changeListeners) {

l.stateChanged(new ChangeEvent(this));

}

}//改变超出渐变区的颜色渐变方式

public voidchangeCycleMethod() {

changeCycleMethod(cycleMethod);

}public voidchangeCycleMethod(MultipleGradientPaint.CycleMethod cycleMethod) {switch(cycleMethod) {caseNO_CYCLE:this.cycleMethod =MultipleGradientPaint.CycleMethod.REFLECT;break;caseREFLECT:this.cycleMethod =MultipleGradientPaint.CycleMethod.REPEAT;break;caseREPEAT:this.cycleMethod =MultipleGradientPaint.CycleMethod.NO_CYCLE;break;

}

}

@Overrideprotected voidpaintComponent(Graphics g) {super.paintComponent(g);

Graphics2D g2d=(Graphics2D) g;

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

drawLinearRect(g2d);

drawThumbsRect(g2d);

drawRadialRect(g2d);

}//绘制fraction按钮所在区域

private voiddrawThumbsRect(Graphics2D g2d) {

g2d.setColor(new Color(255, 255, 255, 40));

g2d.fill(thumbsRect);//绘制fraction按钮

for(Thumb t : thumbs) {

t.paint(g2d);

}

}private voiddrawLinearRect(Graphics2D g2d) {//绘制线性渐变区域

float sx = (float) linearRect.getX();float sy = (float) linearRect.getY();float ex = (int) (sx +linearRect.getWidth());float ey =sy;float[] fractions =getGradientFractions();

Color[] colors=getGradientColors();

Paint p= newLinearGradientPaint(sx, sy, ex, ey, fractions, colors, cycleMethod);

TransparentPainter.paint(g2d, linearRect);

g2d.setPaint(p);

g2d.fill(linearRect);

}//绘制辐射渐变区

private voiddrawRadialRect(Graphics2D g2d) {float cx = (float) radialCircle.getCenterX();float cy = (float) radialCircle.getCenterY();float fx = (float) focusPoint.getX();float fy = (float) focusPoint.getY();float radius = (float) radialCircle.getWidth() / 2;float[] fractions =getGradientFractions();

Color[] colors=getGradientColors();

TransparentPainter.paint(g2d, radialRect);

Paint p= newRadialGradientPaint(cx, cy, radius, fx, fy, fractions, colors, cycleMethod);

g2d.setPaint(p);

g2d.fill(radialRect);if(showCircle) {//绘制辐射渐变的圆

g2d.setPaint(Color.BLACK);

g2d.draw(radialCircle);

}

}//最少需要两个渐变值,所以开始就创建两个fraction

public void resetThumbs(float[] fractions, Color[] colors) {if (fractions == null || colors == null) { throw newNullPointerException(); }if (fractions.length != colors.length) { throw newIllegalArgumentException("Fractions 和 Colors 参数个数不等"); }int x = (int) thumbsRect.getX();int w = (int) thumbsRect.getWidth();for (int i = 0; i < fractions.length; ++i) {

insertThumbAt(x+ (int) (w *fractions[i]), colors[i]);

}

}//在指定的水平位置插入Fraction按钮

private void insertThumbAt(intx) {

insertThumbAt(x, Color.BLUE);

}private void insertThumbAt(intx, Color color) {int index = 0;for(Thumb t : thumbs) {if (x >t.getX()) {

index++;

}

}int y = (int) (padding.top +linearRect.getHeight());

thumbs.add(index,newThumb(x, y, color));

fireChangeEvent();

}public void removeThumbAt(int x, inty) {for(Thumb t : thumbs) {if(t.contains(x, y)) {if (thumbs.size() > 2) {

thumbs.remove(t);

fireChangeEvent();break;

}

}

}

}private voidchangeThumbColor(Thumb thumb) {//弹出颜色选择器

Color newColor = ColorChooser.chooseColor(this, thumb.getColor());if (newColor != null) {

thumb.setColor(newColor);

fireChangeEvent();

}

}//改变焦点的位置

public void changeFocusPoint(double x, doubley) {

focusPoint.setLocation(x, y);

fireChangeEvent();

}private voidchangeFocusPoint(Point2D focusPoint) {

changeFocusPoint(focusPoint.getX(), focusPoint.getY());

}//当panel的大小改变时,再次调用此函数更新显示区域

private voidafterResized() {//

//padding-top//linear gradient area//thumbs area//padding = padding top//radial gradient area//padding-bottom// /线性渐变显示区域

int x =padding.left;int y =padding.top;int w = width - padding.left -padding.right;int h =linearRectHeight;

linearRect.setRect(x, y, w, h);//Fraction按钮所在区域

y +=linearRectHeight;

h=thumbRectHeight;

thumbsRect.setRect(x, y, w, h);//辐射渐变显示区域

y = padding.top + linearRectHeight + thumbRectHeight +padding.top;

h=radialRectHeight;

h=Math.min(w, h);

x= (width - w) / 2;

radialRect.setRect(x, y, w, h);//中心点和焦点

int cx = x + w / 2;int cy = y + h / 2;int radius = 100;

focusPoint.setLocation(cx, cy);

radialCircle.setFrame(cx- radius, cy - radius, radius + radius, radius +radius);

repaint();

}

@OverridepublicDimension getMinimumSize() {return newDimension(width, height);

}

@OverridepublicDimension getMaximumSize() {return newDimension(width, height);

}

@OverridepublicDimension getPreferredSize() {return newDimension(width, height);

}private static voidcreateGuiAndShow() {

JFrame frame= new JFrame("Gradient Generator");

JPanel panel= newJPanel();

panel.add(newGradientGenerator());

frame.setContentPane(newGradientGenerator());

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.pack();//使用此函数后always on top就不起作用了

frame.setResizable(false);

frame.setLocationRelativeTo(null);

frame.setAlwaysOnTop(true);

frame.setVisible(true);

}public static voidmain(String[] args) {

createGuiAndShow();

}

}classThumb {private intx;private inty;private int width = 16;private int height = 20;privateColor color;private booleanselected;privateGeneralPath outerPath;privateGeneralPath innerPath;public Thumb(int x, inty, Color color) {

setXY(x, y);this.color =color;

}public intgetX() {returnx;

}public void setX(intx) {

setXY(x, y);

}public intgetY() {returny;

}public void setY(inty) {

setXY(x, y);

}public intgetWidth() {returnwidth;

}public void setWidth(intwidth) {

setWidthHeight(width, height);

}public intgetHeight() {returnheight;

}public void setHeight(intheight) {

setWidthHeight(width, height);

}publicColor getColor() {returncolor;

}public voidsetColor(Color color) {this.color =color;

}public booleanisSelected() {returnselected;

}public void setSelected(booleanselected) {this.selected =selected;

}public boolean contains(int x, inty) {returnouterPath.contains(x, y);

}public void setXY(int x, inty) {this.x =x;this.y =y;

createPaths();

}public void setWidthHeight(int width, intheight) {this.width =width;this.height =height;

createPaths();

}private float[] fractions = new float[] { 0.0f, 0.5f, 1.0f};private Color[] colors = newColor[] { Color.ORANGE, Color.BLACK, Color.ORANGE.brighter() };public voidpaint(Graphics2D g2d) {//绘制大三角形按钮//Paint p = new GradientPaint(x, y, selected ? color.darker() : color,//x, y + height, Color.ORANGE);

Paint p = new LinearGradientPaint(x - width, y, x + width / 4, y, fractions, colors);

g2d.setPaint(p);

g2d.fill(outerPath);//绘制小三角形按钮

g2d.setColor(color);

g2d.fill(innerPath);

}//创建按钮的形状

private voidcreatePaths() {

outerPath= newGeneralPath();

outerPath.moveTo(x, y);

outerPath.lineTo(x+ width / 2, y +height);

outerPath.lineTo(x- width / 2, y +height);

outerPath.closePath();

innerPath= newGeneralPath();

innerPath.moveTo(x, y+ height / 2);

innerPath.lineTo(x+ width / 4, y +height);

innerPath.lineTo(x- width / 4, y +height);

innerPath.closePath();

}

}

[html] view plain copypackagegradient;importjava.awt.AWTEvent;importjava.awt.BorderLayout;importjava.awt.Color;importjava.awt.Component;importjava.awt.Dimension;importjava.awt.Graphics;importjava.awt.Graphics2D;importjava.awt.Insets;importjava.awt.RenderingHints;importjava.awt.Toolkit;importjava.awt.event.AWTEventListener;importjava.awt.event.KeyEvent;importjava.awt.event.MouseAdapter;importjava.awt.event.MouseEvent;importjava.awt.event.WindowAdapter;importjava.awt.event.WindowEvent;importjava.awt.geom.Rectangle2D;importjava.awt.image.BufferedImage;importjava.io.File;importjava.io.FileNotFoundException;importjava.util.ArrayList;importjava.util.List;importjava.util.Scanner;importjavax.swing.JComponent;importjavax.swing.JDialog;importjavax.swing.JPanel;importjavax.swing.JSlider;importjavax.swing.event.ChangeEvent;importjavax.swing.event.ChangeListener;/*** 创建一个模态的颜色选择对话框,可以加载用户预先定义存储好的颜色.

*

*@authorBiao

**/@SuppressWarnings("serial")public class ColorChooser extendsJDialog {private static ColorChooser instance = newColorChooser();private ColorPanel colorPanel = newColorPanel();privateColor color;public staticColor chooseColor(JComponent ower, Color defaultColor) {

instance.color=defaultColor;

instance.colorPanel.startSelect(defaultColor);

instance.pack();

instance.setLocationRelativeTo(ower);

instance.setVisible(true);returninstance.color;

}privateColorChooser() {

setTitle("Choose a color");

setModal(true);

setResizable(false);

setBackground(Color.DARK_GRAY);

getContentPane().add(colorPanel, BorderLayout.CENTER);this.addWindowListener(newWindowAdapter() {

@Overridepublic voidwindowClosing(WindowEvent e) {

gotoHell(color);

}

});

colorPanel.addChangeListener(newChangeListener() {

@Overridepublic voidstateChanged(ChangeEvent e) {

Color c=colorPanel.getColor();if(colorPanel.isDoubleClickSelection()) {

gotoHell(c);

}int r =c.getRed();int g =c.getGreen();int b =c.getBlue();int a =c.getAlpha();

String hex= ColorPanel.colorToHexString(newColor(r, g, b, a));

String title= String.format("RGBA(%d,%d,%d,%d) Hex(%s)", r, g, b, a, hex);

setTitle(title);

}

});//处理JDialog所有子组件的按键事件//按下回车使用选择的颜色,按下Esc返回默认传进来的颜色

Toolkit.getDefaultToolkit().addAWTEventListener(newAWTEventListener() {

@Overridepublic voideventDispatched(AWTEvent event) {

KeyEvent ke=(KeyEvent) event;if (ke.getID() ==KeyEvent.KEY_PRESSED) {if (event.getSource() instanceofComponent) {

Component com=(Component) event.getSource();if (ke.getKeyCode() == KeyEvent.VK_ESCAPE &&hasChild(com)) {

gotoHell(color);//取消时返回默认的颜色

} else if (ke.getKeyCode() == KeyEvent.VK_ENTER &&hasChild(com)) {

gotoHell(colorPanel.getColor());

}

}

}

}

}, AWTEvent.KEY_EVENT_MASK);

}//是否包含了组件

public booleanhasChild(Component c) {for (Component parent = c; parent != null; parent =parent.getParent()) {if (parent == this) { return true; }

}return false;

}//隐藏颜色选择对话框

public voidgotoHell(Color c) {

color= (c == null) ?color : c;

setVisible(false);

}

}

@SuppressWarnings("serial")class ColorPanel extendsJPanel {final static private int columnSize = 21; //每行最多显示21个颜色

final static private int sliderHeight = 20; //Slider的高度

final static private int previewHeight = 20; //预览区的高度

final static private int colorRectWidth = 20; //颜色小方块的宽度

final static private int colorRectHeight = 20;//颜色小方块的高度

private int width = 520; //Color panel的尺寸

private int height = 340;private Insets padding = new Insets(10, 10, 0, 10); //边距

private int margin =padding.top;private Color color =Color.WHITE;private List storedColors = new ArrayList(); //用户存储的颜色

private List defaultColors = new ArrayList(); //使用算法生成的默认颜色

private Rectangle2D previewRect = new Rectangle2D.Float(); //预览区域

private Rectangle2D colorsImageRect = new Rectangle2D.Double(); //显示颜色的区域

private BufferedImage colorsImage; //需要使用颜色信息来创建确定大小//调节rgba的slider

private JSlider redSlider = new JSlider(0, 255, 255);private JSlider greenSlider = new JSlider(0, 255, 255);private JSlider blueSlider = new JSlider(0, 255, 255);private JSlider alphaSlider = new JSlider(0, 255, 255);//双击时如果选中颜色,则选择完成

private boolean doubleClickSelection = false;private List changeListeners = new ArrayList();publicColorPanel() {//创建颜色和显示颜色的小方块缓冲图像

prepareColors();

prepareColorsImage();//窗口的大小需要用color buffer image的大小来确定,所以必须在这里调用

prepareSize();

preparePreview();

prepareSliders();this.addMouseListener(newMouseAdapter() {

@Overridepublic voidmouseClicked(MouseEvent e) {int x =e.getX();int y =e.getY();

Color c=getColorAt(x, y);if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 1) {//单击时设置选中的颜色

if (c != null) {

setColor(c);

fireStateChanged();

}

}else if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {//双击时返回选中的颜色,隐藏颜色选取窗口

if (c != null ||previewRect.contains(x, y)) {

setDoubleClickSelection(true);

fireStateChanged();

}

}

}

});

redSlider.addChangeListener(newChangeListener() {

@Overridepublic voidstateChanged(ChangeEvent e) {

setR(redSlider.getValue());

fireStateChanged();

}

});

greenSlider.addChangeListener(newChangeListener() {

@Overridepublic voidstateChanged(ChangeEvent e) {

setG(greenSlider.getValue());

fireStateChanged();

}

});

blueSlider.addChangeListener(newChangeListener() {

@Overridepublic voidstateChanged(ChangeEvent e) {

setB(blueSlider.getValue());

fireStateChanged();

}

});

alphaSlider.addChangeListener(newChangeListener() {

@Overridepublic voidstateChanged(ChangeEvent e) {

setA(alphaSlider.getValue());

fireStateChanged();

}

});

}

@Overrideprotected voidpaintComponent(Graphics g) {super.paintComponent(g);

setBackground(Color.DARK_GRAY);

Graphics2D g2d=(Graphics2D) g;

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);//绘制颜色方块的缓冲图片

int x = (int) colorsImageRect.getX();int y = (int) colorsImageRect.getY();int w = (int) colorsImageRect.getWidth();int h = (int) colorsImageRect.getHeight();

g2d.drawImage(colorsImage, x, y, w, h,null);//绘制颜色预览

TransparentPainter.paint(g2d, previewRect);

g2d.setPaint(color);

g2d.fill(previewRect);

}public voidstartSelect(Color color) {

setColor(color);

setDoubleClickSelection(false);

}public booleanisDoubleClickSelection() {returndoubleClickSelection;

}protected void setDoubleClickSelection(booleandoubleClickSelection) {this.doubleClickSelection =doubleClickSelection;

}//当属性改变事件发生时,调用监听器并且重绘

public voidfireStateChanged() {for(ChangeListener l : changeListeners) {

l.stateChanged(new ChangeEvent(this));

}

repaint();

}public voidaddChangeListener(ChangeListener l) {

changeListeners.add(l);

}public voidremoveChangeListener(ChangeListener l) {

changeListeners.remove(l);

}//选得鼠标选中的颜色

public Color getColorAt(int x, inty) {//如果不在显示颜色的图片中,则返回null

if (!colorsImageRect.contains(x, y)) { return null; }//以图片的左上角为原点

x -=colorsImageRect.getX();

y-=colorsImageRect.getY();if (y <=getHeightOfColorsRect(storedColors)) {int i = y / colorRectHeight * columnSize + x /colorRectWidth;return i >= storedColors.size() ? null: storedColors.get(i);

}else{

y-= getHeightOfColorsRect(storedColors) +margin;int i = y / colorRectHeight * columnSize + x /colorRectWidth;return i >= defaultColors.size() ? null: defaultColors.get(i);

}

}//返回当前选中的颜色

publicColor getColor() {returncolor;

}//设置当前颜色

public voidsetColor(Color color) {this.color = (color == null) ?Color.WHITE : color;

setSliderValues(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());

}public void setColor(int r, int g, intb) {this.color = new Color(r, g, b, 255);

setSliderValues(r, g, b,255);

}public void setColor(int r, int g, int b, inta) {

r=clamp(r);

g=clamp(g);

b=clamp(b);

a=clamp(a);this.color = newColor(r, g, b, a);

setSliderValues(r, g, b, a);

}public void setR(intr) {

setColor(r, color.getGreen(), color.getBlue(), color.getAlpha());

}public void setG(intg) {

setColor(color.getRed(), g, color.getBlue(), color.getAlpha());

}public void setB(intb) {

setColor(color.getRed(), color.getGreen(), b, color.getAlpha());

}public void setA(inta) {

setColor(color.getRed(), color.getGreen(), color.getBlue(), a);

}public int clamp(intval) {

val= val < 0 ? 0: val;

val= val > 255 ? 255: val;returnval;

}//设置slier的值

private void setSliderValues(int r, int g, int b, inta) {

redSlider.setValue(r);

greenSlider.setValue(g);

blueSlider.setValue(b);

alphaSlider.setValue(a);

fireStateChanged();

}/*** 把16进制模式的字符串转化成颜色.

*

*@paramhex

* 表示颜色的16进制字符串,格式为#rgb, #rrggbb, #aarrggbb

*@return返回字符串的颜色,如果字符串格式不对,返回null*/

public staticColor parseColorHex(String hex) {//#rgb, #rrggbb, #aarrggbb//检查长度

if (hex == null || hex.length() != 4 && hex.length() != 7 && hex.length() != 9

&& hex.charAt(0) != '#') { return null; }//检查字符是否有效

for (int i = 1; i < hex.length(); ++i) {char aChar =hex.charAt(i);if (!('0' <= aChar && aChar <= '9') && !('a' <= aChar && aChar <= 'f')&& !('A' <= aChar && aChar <= 'F')) { return null; }

}if (hex.length() == 4) {//#rgb

int r = Integer.valueOf(hex.charAt(1) + "" + hex.charAt(1), 16);int g = Integer.valueOf(hex.charAt(2) + "" + hex.charAt(2), 16);int b = Integer.valueOf(hex.charAt(3) + "" + hex.charAt(3), 16);return newColor(r, g, b);

}else if (hex.length() == 7) {//#rrggbb

int r = Integer.valueOf(hex.substring(1, 3), 16);int g = Integer.valueOf(hex.substring(3, 5), 16);int b = Integer.valueOf(hex.substring(5, 7), 16);return newColor(r, g, b);

}else if (hex.length() == 9) {//#aarrggbb

int a = Integer.valueOf(hex.substring(1, 3), 16);int r = Integer.valueOf(hex.substring(3, 5), 16);int g = Integer.valueOf(hex.substring(5, 7), 16);int b = Integer.valueOf(hex.substring(7, 9), 16);return newColor(r, g, b, a);

}return null;

}public static char[] hexDight = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B','C', 'D', 'E', 'F'};/*** 把颜色的表示转换为16进制表示#rrggbbaa

*

*@paramcolor

*@return返回颜色的16进制字符串*/

public staticString colorToHexString(Color color) {if (color == null) { return "null"; }int r =color.getRed();int g =color.getGreen();int b =color.getBlue();int a =color.getAlpha();

StringBuilder sb= new StringBuilder("#");

sb.append(hexDight[a>> 4 & 0xF]);

sb.append(hexDight[a& 0xF]);

sb.append(hexDight[r>> 4 & 0xF]);

sb.append(hexDight[r& 0xF]);

sb.append(hexDight[g>> 4 & 0xF]);

sb.append(hexDight[g& 0xF]);

sb.append(hexDight[b>> 4 & 0xF]);

sb.append(hexDight[b& 0xF]);returnsb.toString();

}private voidprepareColors() {//从文件中读取颜色

try{

Scanner scanner= new Scanner(new File("resources/colors.txt"));while(scanner.hasNextLine()) {try{

Color c=parseColorHex(scanner.nextLine().trim());if (c != null) {

storedColors.add(c);

}

}catch(Exception e) {

}

}

}catch(FileNotFoundException e) {

e.printStackTrace();

}//创建一些默认的颜色

final float delta = 0.2f;for (float r = 0; r <= 1.0; r +=delta) {for (float g = 0; g <= 1.0; g +=delta) {for (float b = 0; b <= 1.0; b +=delta) {

defaultColors.add(newColor(r, g, b));

}

}

}

}private int getHeightOfColorsRect(Listli) {int row = (int) Math.ceil(li.size() / (float) columnSize);return row *colorRectWidth;

}private voidprepareColorsImage() {

margin=padding.top;int w = columnSize *colorRectWidth;int h = getHeightOfColorsRect(storedColors) + getHeightOfColorsRect(defaultColors) +margin;int x = 0;int y = 0;

colorsImageRect.setRect(padding.top, padding.top, w, h);

colorsImage= newBufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

Graphics2D g2d=colorsImage.createGraphics();//绘制用户存储的颜色

for (int i = 0; i < storedColors.size(); ++i) {

g2d.setPaint(storedColors.get(i));

g2d.fillRect(x, y, colorRectWidth, colorRectHeight);

x+=colorRectWidth;if ((i + 1) % columnSize == 0) {

x= 0;

y+=colorRectHeight;

}

}

x= 0;

y= getHeightOfColorsRect(storedColors) +margin;//绘制默认的颜色

for (int i = 0; i < defaultColors.size(); ++i) {

g2d.setPaint(defaultColors.get(i));

g2d.fillRect(x, y, colorRectWidth, colorRectHeight);

x+=colorRectWidth;if ((i + 1) % columnSize == 0) {

x= 0;

y+=colorRectHeight;

}

}

}private voidprepareSize() {

width= padding.left + colorsImage.getWidth() +padding.right;

height= padding.top + colorsImage.getHeight() + padding.top + previewHeight +sliderHeight;

}private voidpreparePreview() {int x =padding.left;int y = height - sliderHeight -previewHeight;int w = width - padding.left -padding.right;

previewRect.setRect(x, y, w, previewHeight);

}private voidprepareSliders() {

setLayout(null);int margin = 0; //slider之间的间隔,实际没必须

int h =sliderHeight;int w = (width - padding.left - padding.right) / 4;int x =padding.left;int y = height - h + 2;

redSlider.setBounds(x, y, w, h);

x+= w +margin;

greenSlider.setBounds(x, y, w, h);

x+= w +margin;

blueSlider.setBounds(x, y, w, h);

x+= w +margin;

alphaSlider.setBounds(x, y, w, h);

add(redSlider);

add(greenSlider);

add(blueSlider);

add(alphaSlider);

}

@OverridepublicDimension getMinimumSize() {return newDimension(width, height);

}

@OverridepublicDimension getMaximumSize() {return newDimension(width, height);

}

@OverridepublicDimension getPreferredSize() {return newDimension(width, height);

}

}

[html] view plain copypackagegradient;importjava.awt.Color;importjava.awt.Graphics2D;importjava.awt.geom.Rectangle2D;/*** 绘制Photoshop中透明色的效果.

*

*@authorBiao

**/

public classTransparentPainter {public static voidpaint(Graphics2D g2d, Rectangle2D rect) {

g2d.setClip(rect);int sx = (int) rect.getX();int sy = (int) rect.getY();int w = (int) rect.getWidth();int h = (int) rect.getHeight();

Color color=Color.WHITE;

Color color1=Color.WHITE;

Color color2=Color.LIGHT_GRAY;int delta = 10;boolean odd = false;for (int y = sy; y <= h + sy; y +=delta) {

color= (odd) ?color1 : color2;for (int x = sx; x <= w + sx; x +=delta) {

g2d.setPaint(color);

g2d.fillRect(x, y, w, h);

color= (color == color1) ?color2 : color1;

}

odd= !odd;

}

g2d.setClip(null);

}

}

[html] view plain copypackagegradient;importjava.awt.geom.Point2D;public classGeometryUtil {//两点之间的距离

public static doubledistanceOfPoints(Point2D p1, Point2D p2) {double disX = p2.getX() -p1.getX();double disY = p2.getY() -p1.getY();double dis = Math.sqrt(disX * disX + disY *disY);returndis;

}//两点的中点

public staticPoint2D middlePoint(Point2D p1, Point2D p2) {double x = (p1.getX() + p2.getX()) / 2;double y = (p1.getY() + p2.getY()) / 2;return newPoint2D.Double(x, y);

}//在两点所在直线上,以从startPoint到endPoint为方向,离startPoint的距离disToStartPoint的点

public static Point2D extentPoint(Point2D startPoint, Point2D endPoint, doubledisToStartPoint) {double disX = endPoint.getX() -startPoint.getX();double disY = endPoint.getY() -startPoint.getY();double dis = Math.sqrt(disX * disX + disY *disY);double sin = (endPoint.getY() - startPoint.getY()) /dis;double cos = (endPoint.getX() - startPoint.getX()) /dis;double deltaX = disToStartPoint *cos;double deltaY = disToStartPoint *sin;return new Point2D.Double(startPoint.getX() + deltaX, startPoint.getY() +deltaY);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值