如何在Java中实现Graphic2D对象的颜色变化?
How to implement color change for a Graphic2D object in Java?
我想了解是否可以在我的应用程序运行时更改现有图形的颜色(多种不同颜色之间的某种闪烁)。
我有一个使用 GeneralPath
class 绘制的起始形状,我的随机 RGB 颜色代码选择器也正常工作。是否可以使用 repaint();
来改变颜色,让我的星星的颜色在从我的 createRandomColor()
方法中随机选择的 3 种选定颜色之间变化?
代码
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import static java.lang.Math.random;
import java.util.Vector;
import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Sandbox extends JApplet {
DrawingStar canvas;
public static void main(String[] args) {
JFrame frame = new JFrame();
Sandbox path = new Sandbox();
path.init();
frame.getContentPane().add(path);
frame.setSize(250, 250);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void init() {
Container container = getContentPane();
canvas = new DrawingStar();
container.add(canvas);
}
}
class DrawingStar extends Canvas {
Vector generalPaths;
private List<Color> colors;
public DrawingStar() {
colors = new ArrayList<Color>();
for (int i = 0; i < 3; i++) {
colors.add(createRandomColor());
}
setBackground(Color.white);
setSize(400, 400);
generalPaths = new Vector();
GeneralPath gp1;
gp1 = new GeneralPath();
gp1.moveTo(50, 120);
gp1.lineTo(70, 180);
gp1.lineTo(20, 140);
gp1.lineTo(80, 140);
gp1.lineTo(30, 180);
gp1.closePath();
generalPaths.addElement(gp1);
}
public void paint(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
g2D.translate(70.0f, -85.0f);
g2D.draw((GeneralPath) generalPaths.elementAt(0));
for (int i = 0; i < 3; i++) {
Color color = colors.get(i);
g2D.setColor(color);
g2D.fill((GeneralPath) generalPaths.elementAt(0));
}
System.out.println("Is this working");
repaint();
}
private Color createRandomColor(){
int r = (int) (Math.random() * 256);
int g = (int) (Math.random() * 256);
int b = (int) (Math.random() * 256);
Color color = new Color(r,g,b);
return color;
}
}
小程序已死,万岁HTML5
- Oracle reveals Java Applet API deprecation plan
- DK 9 发行说明
弃用的 API、功能和选项
- The clock is ticking: The Java browser plugin will be deprecated soon
- Oracle Reminds Java Developers That Soon They Won’t Have a Browser to Run Applets
是时候继续了...此外,applet 生命周期比您实现的要复杂得多。
“另类”
- Creating a GUI With JFC/Swing
- Performing Custom Painting
- Painting in AWT and Swing
- How to Use Swing Timers
Canvas
是一个低级组件,可能不太适合您的需要。它也不是双缓冲的,因此重绘时会出现闪烁。
不要从任何绘画方法中调用 repaint
,您不会喜欢这样的结果。相反,安排在将来某个时间点进行更新。
这个例子简单地使用 Swing Timer
作为一个伪循环,它增加一个计数器并获取下一个颜色并每秒调用重绘。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.GeneralPath;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Sandbox {
DrawingStar canvas;
public static void main(String[] args) {
new Sandbox();
}
public Sandbox() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
canvas = new DrawingStar();
frame.getContentPane().add(canvas);
frame.setSize(250, 250);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
class DrawingStar extends JPanel {
Vector generalPaths;
private List<Color> colors;
private int colorIndex = 0;
private Color color;
public DrawingStar() {
colors = new ArrayList<Color>();
for (int i = 0; i < 3; i++) {
colors.add(createRandomColor());
}
color = colors.get(0);
setBackground(Color.white);
generalPaths = new Vector();
GeneralPath gp1;
gp1 = new GeneralPath();
gp1.moveTo(50, 120);
gp1.lineTo(70, 180);
gp1.lineTo(20, 140);
gp1.lineTo(80, 140);
gp1.lineTo(30, 180);
gp1.closePath();
generalPaths.addElement(gp1);
Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
colorIndex++;
if (colorIndex >= colors.size()) {
colorIndex = 0;
}
color = colors.get(colorIndex);
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
Graphics2D g2D = (Graphics2D) g;
g2D.translate(70.0f, -85.0f);
g2D.draw((GeneralPath) generalPaths.elementAt(0));
g2D.setColor(color);
g2D.fill((GeneralPath) generalPaths.elementAt(0));
}
private Color createRandomColor() {
int r = (int) (Math.random() * 256);
int g = (int) (Math.random() * 256);
int b = (int) (Math.random() * 256);
Color color = new Color(r, g, b);
return color;
}
}
}
Swing 不是线程安全的并且是单线程的,因此使用 Swing 的原因 Timer
我想了解是否可以在我的应用程序运行时更改现有图形的颜色(多种不同颜色之间的某种闪烁)。
我有一个使用 GeneralPath
class 绘制的起始形状,我的随机 RGB 颜色代码选择器也正常工作。是否可以使用 repaint();
来改变颜色,让我的星星的颜色在从我的 createRandomColor()
方法中随机选择的 3 种选定颜色之间变化?
代码
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import static java.lang.Math.random;
import java.util.Vector;
import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Sandbox extends JApplet {
DrawingStar canvas;
public static void main(String[] args) {
JFrame frame = new JFrame();
Sandbox path = new Sandbox();
path.init();
frame.getContentPane().add(path);
frame.setSize(250, 250);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void init() {
Container container = getContentPane();
canvas = new DrawingStar();
container.add(canvas);
}
}
class DrawingStar extends Canvas {
Vector generalPaths;
private List<Color> colors;
public DrawingStar() {
colors = new ArrayList<Color>();
for (int i = 0; i < 3; i++) {
colors.add(createRandomColor());
}
setBackground(Color.white);
setSize(400, 400);
generalPaths = new Vector();
GeneralPath gp1;
gp1 = new GeneralPath();
gp1.moveTo(50, 120);
gp1.lineTo(70, 180);
gp1.lineTo(20, 140);
gp1.lineTo(80, 140);
gp1.lineTo(30, 180);
gp1.closePath();
generalPaths.addElement(gp1);
}
public void paint(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
g2D.translate(70.0f, -85.0f);
g2D.draw((GeneralPath) generalPaths.elementAt(0));
for (int i = 0; i < 3; i++) {
Color color = colors.get(i);
g2D.setColor(color);
g2D.fill((GeneralPath) generalPaths.elementAt(0));
}
System.out.println("Is this working");
repaint();
}
private Color createRandomColor(){
int r = (int) (Math.random() * 256);
int g = (int) (Math.random() * 256);
int b = (int) (Math.random() * 256);
Color color = new Color(r,g,b);
return color;
}
}
小程序已死,万岁HTML5
- Oracle reveals Java Applet API deprecation plan
- DK 9 发行说明 弃用的 API、功能和选项
- The clock is ticking: The Java browser plugin will be deprecated soon
- Oracle Reminds Java Developers That Soon They Won’t Have a Browser to Run Applets
是时候继续了...此外,applet 生命周期比您实现的要复杂得多。
“另类”
- Creating a GUI With JFC/Swing
- Performing Custom Painting
- Painting in AWT and Swing
- How to Use Swing Timers
Canvas
是一个低级组件,可能不太适合您的需要。它也不是双缓冲的,因此重绘时会出现闪烁。
不要从任何绘画方法中调用 repaint
,您不会喜欢这样的结果。相反,安排在将来某个时间点进行更新。
这个例子简单地使用 Swing Timer
作为一个伪循环,它增加一个计数器并获取下一个颜色并每秒调用重绘。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.GeneralPath;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Sandbox {
DrawingStar canvas;
public static void main(String[] args) {
new Sandbox();
}
public Sandbox() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
canvas = new DrawingStar();
frame.getContentPane().add(canvas);
frame.setSize(250, 250);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
class DrawingStar extends JPanel {
Vector generalPaths;
private List<Color> colors;
private int colorIndex = 0;
private Color color;
public DrawingStar() {
colors = new ArrayList<Color>();
for (int i = 0; i < 3; i++) {
colors.add(createRandomColor());
}
color = colors.get(0);
setBackground(Color.white);
generalPaths = new Vector();
GeneralPath gp1;
gp1 = new GeneralPath();
gp1.moveTo(50, 120);
gp1.lineTo(70, 180);
gp1.lineTo(20, 140);
gp1.lineTo(80, 140);
gp1.lineTo(30, 180);
gp1.closePath();
generalPaths.addElement(gp1);
Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
colorIndex++;
if (colorIndex >= colors.size()) {
colorIndex = 0;
}
color = colors.get(colorIndex);
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
Graphics2D g2D = (Graphics2D) g;
g2D.translate(70.0f, -85.0f);
g2D.draw((GeneralPath) generalPaths.elementAt(0));
g2D.setColor(color);
g2D.fill((GeneralPath) generalPaths.elementAt(0));
}
private Color createRandomColor() {
int r = (int) (Math.random() * 256);
int g = (int) (Math.random() * 256);
int b = (int) (Math.random() * 256);
Color color = new Color(r, g, b);
return color;
}
}
}
Swing 不是线程安全的并且是单线程的,因此使用 Swing 的原因 Timer