敢于知道,因为真理使我们自由!
图形绘制-普通方法(测试)
AlgoFrame 自定义窗口类
package com.company;
import javax.swing.*;
import javax.swing.*;
import java.awt.*;
public class AlgoFrame extends JFrame {
private int canvasWidth;
private int canvasHeight;
public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
super(title);
this.canvasWidth = canvasWidth;
this.canvasHeight = canvasHeight;
AlgoCanvas canvas = new AlgoCanvas();
setContentPane(canvas);
pack();
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public AlgoFrame(String title) {
this(title, 1024, 768);
}
public int getCanvasWidth() {
return canvasWidth;
}
public int getCanvasHeight() {
return canvasHeight;
}
private class AlgoCanvas extends JPanel {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(50, 50, 300, 300);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(canvasWidth, canvasHeight);
}
}
}
Main 主函数逻辑
package com.company;
import java.awt.*;
public class Main {
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
AlgoFrame frame = new AlgoFrame("Welcome", 500, 500);
});
}
}
图形绘制-Graphics2D法(测试)
相关代码
package com.company;
import javax.swing.*;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
public class AlgoFrame extends JFrame {
private int canvasWidth;
private int canvasHeight;
public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
super(title);
this.canvasWidth = canvasWidth;
this.canvasHeight = canvasHeight;
AlgoCanvas canvas = new AlgoCanvas();
setContentPane(canvas);
pack();
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public AlgoFrame(String title) {
this(title, 1024, 768);
}
public int getCanvasWidth() {
return canvasWidth;
}
public int getCanvasHeight() {
return canvasHeight;
}
private class AlgoCanvas extends JPanel {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int strokeWidth = 5;
g2d.setStroke(new BasicStroke(strokeWidth));
g2d.setColor(Color.RED);
Ellipse2D circle = new Ellipse2D.Double(50, 50, 300, 300);
g2d.draw(circle);
g2d.setColor(Color.BLUE);
Ellipse2D circle2 = new Ellipse2D.Double(60, 60, 280, 280);
g2d.fill(circle2);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(canvasWidth, canvasHeight);
}
}
}
封装-工具类
AlgoVisHelper
package com.company;
import java.awt.*;
import java.awt.geom.Ellipse2D;
public class AlgoVisHelper {
private AlgoVisHelper() {
}
public static void setColor(Graphics2D g2d,Color color){
g2d.setColor(color);
}
public static void setStrokeWidth(Graphics2D g2d, int w) {
int strokeWidth = w;
g2d.setStroke(new BasicStroke(strokeWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
}
public static void strokeCircle(Graphics2D g2d,int x,int y,int r){
Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
g2d.draw(circle);
};
public static void fillCircle(Graphics2D g2d,int x,int y,int r){
Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
g2d.fill(circle);
};
}
AlgoFrame
package com.company;
import javax.swing.*;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
public class AlgoFrame extends JFrame {
private int canvasWidth;
private int canvasHeight;
public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
super(title);
this.canvasWidth = canvasWidth;
this.canvasHeight = canvasHeight;
AlgoCanvas canvas = new AlgoCanvas();
setContentPane(canvas);
pack();
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public AlgoFrame(String title) {
this(title, 1024, 768);
}
public int getCanvasWidth() {
return canvasWidth;
}
public int getCanvasHeight() {
return canvasHeight;
}
private class AlgoCanvas extends JPanel {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int strokeWidth = 5;
g2d.setStroke(new BasicStroke(strokeWidth));
AlgoVisHelper.setColor(g2d, Color.BLUE);
AlgoVisHelper.fillCircle(g2d, canvasWidth / 2, canvasHeight / 2, 200);
AlgoVisHelper.setColor(g2d, Color.RED);
AlgoVisHelper.strokeCircle(g2d, canvasWidth / 2, canvasHeight / 2, 200);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(canvasWidth, canvasHeight);
}
}
}
抗锯齿
package com.company;
import javax.swing.*;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
public class AlgoFrame extends JFrame {
private int canvasWidth;
private int canvasHeight;
public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
super(title);
this.canvasWidth = canvasWidth;
this.canvasHeight = canvasHeight;
AlgoCanvas canvas = new AlgoCanvas();
setContentPane(canvas);
pack();
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public AlgoFrame(String title) {
this(title, 1024, 768);
}
public int getCanvasWidth() {
return canvasWidth;
}
public int getCanvasHeight() {
return canvasHeight;
}
private class AlgoCanvas extends JPanel {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//抗锯齿
RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.addRenderingHints(hints);
//具体绘制
AlgoVisHelper.setStrokeWidth(g2d, 5);
AlgoVisHelper.setColor(g2d, Color.BLUE);
AlgoVisHelper.fillCircle(g2d, canvasWidth / 2, canvasHeight / 2, 200);
AlgoVisHelper.setColor(g2d, Color.RED);
AlgoVisHelper.strokeCircle(g2d, canvasWidth / 2, canvasHeight / 2, 200);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(canvasWidth, canvasHeight);
}
}
}
双缓存
package com.company;
import javax.swing.*;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
public class AlgoFrame extends JFrame {
private int canvasWidth;
private int canvasHeight;
public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
super(title);
this.canvasWidth = canvasWidth;
this.canvasHeight = canvasHeight;
AlgoCanvas canvas = new AlgoCanvas();
setContentPane(canvas);
pack();
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public AlgoFrame(String title) {
this(title, 1024, 768);
}
public int getCanvasWidth() {
return canvasWidth;
}
public int getCanvasHeight() {
return canvasHeight;
}
private class AlgoCanvas extends JPanel {
//双缓存
public AlgoCanvas() {
super(true);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//抗锯齿
RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.addRenderingHints(hints);
//具体绘制
AlgoVisHelper.setStrokeWidth(g2d, 5);
AlgoVisHelper.setColor(g2d, Color.BLUE);
AlgoVisHelper.fillCircle(g2d, canvasWidth / 2, canvasHeight / 2, 200);
AlgoVisHelper.setColor(g2d, Color.RED);
AlgoVisHelper.strokeCircle(g2d, canvasWidth / 2, canvasHeight / 2, 200);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(canvasWidth, canvasHeight);
}
}
}
实现测试用例
Main
package com.company;
import java.awt.*;
public class Main {
public static void main(String[] args) {
int sceneWidth = 800;
int sceneHeight = 800;
int N = 10;
Circle[] circles = new Circle[N];
int R = 50;
for (int i = 0; i < N; i++) {
int x = (int) Math.random() * (sceneWidth - 2 * R) + R;
int y = (int) Math.random() * (sceneHeight - 2 * R) + R;
int vx = (int) (Math.random() * 11 - 5);
int vy = (int) (Math.random() * 11 - 5);
circles[i] = new Circle(x, y, R, vx, vy);
}
EventQueue.invokeLater(() -> {
AlgoFrame frame = new AlgoFrame("Welcome", sceneWidth, sceneHeight);
new Thread(() -> {
while (true) {
//绘制数据
frame.render(circles);
AlgoVisHelper.pause(20);
//更新数据
for (Circle circle : circles) {
circle.move(0, 0, sceneWidth, sceneHeight);
}
}
}).start();
});
}
}
Circle
package com.company;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
public class Circle {
public int x, y;
private int r;
public int getR() {
return r;
}
public void setR(int r) {
this.r = r;
}
public int vx, vy;
public Circle(int x, int y, int r, int vx, int vy) {
this.x = x;
this.y = y;
this.setR(r);
this.vx = vx;
this.vy = vy;
}
public void move(int minx, int miny, int maxx, int maxy) {
x += vx;
y += vy;
checkCollision(minx, miny, maxx, maxy);
}
private void checkCollision(int minx, int miny, int maxx, int maxy) {
if (x - r < minx) {
x = r;
vx = -vx;
}
if (x + r >= maxx) {
x = maxx - r;
vx = -vx;
}
if (y - r < miny) {
y = r;
vy = -vy;
}
if (y + r >= maxy) {
y = maxy - r;
vy = -vy;
}
}
}
AlgoVisHelper
package com.company;
import java.awt.*;
import java.awt.geom.Ellipse2D;
public class AlgoVisHelper {
private AlgoVisHelper() {
}
public static void setColor(Graphics2D g2d,Color color){
g2d.setColor(color);
}
public static void setStrokeWidth(Graphics2D g2d, int w) {
int strokeWidth = w;
g2d.setStroke(new BasicStroke(strokeWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
}
public static void strokeCircle(Graphics2D g2d,int x,int y,int r){
Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
g2d.draw(circle);
};
public static void fillCircle(Graphics2D g2d,int x,int y,int r){
Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
g2d.fill(circle);
};
public static void pause(int t){
try{
Thread.sleep(t);
}catch (InterruptedException e){
System.out.println("Error in sleeping!");
}
}
}
AlgoFrame
package com.company;
import javax.swing.*;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
public class AlgoFrame extends JFrame {
private int canvasWidth;
private int canvasHeight;
public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
super(title);
this.canvasWidth = canvasWidth;
this.canvasHeight = canvasHeight;
AlgoCanvas canvas = new AlgoCanvas();
setContentPane(canvas);
pack();
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public AlgoFrame(String title) {
this(title, 1024, 768);
}
public int getCanvasWidth() {
return canvasWidth;
}
public int getCanvasHeight() {
return canvasHeight;
}
private Circle[] circles;
public void render(Circle[] circles) {
this.circles = circles;
repaint();
}
private class AlgoCanvas extends JPanel {
//双缓存
public AlgoCanvas() {
super(true);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//抗锯齿
RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.addRenderingHints(hints);
//具体绘制
AlgoVisHelper.setStrokeWidth(g2d, 1);
AlgoVisHelper.setColor(g2d, Color.RED);
for (Circle circle : circles) {
AlgoVisHelper.strokeCircle(g2d, circle.x, circle.y, circle.getR());
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(canvasWidth, canvasHeight);
}
}
}
MVC应用(修改和新建类 )
Main
package com.company;
import java.awt.*;
public class Main {
public static void main(String[] args) {
int sceneWidth = 800;
int sceneHeight = 800;
int N = 10;
AlgoVisualizer visualizer = new AlgoVisualizer(sceneWidth, sceneHeight, N);
}
}
AlgoVisualizer
package com.company;
import java.awt.*;
public class AlgoVisualizer {
private Circle[] circles;
private AlgoFrame frame;
public AlgoVisualizer(int sceneWidth, int sceneHeight, int N) {
circles = new Circle[N];
int R = 50;
for (int i = 0; i < N; i++) {
int x = (int) Math.random() * (sceneWidth - 2 * R) + R;
int y = (int) Math.random() * (sceneHeight - 2 * R) + R;
int vx = (int) (Math.random() * 11 - 5);
int vy = (int) (Math.random() * 11 - 5);
circles[i] = new Circle(x, y, R, vx, vy);
}
EventQueue.invokeLater(() -> {
frame = new AlgoFrame("Welcome", sceneWidth, sceneHeight);
new Thread(() -> {
run();
}).start();
});
}
//动画逻辑
private void run() {
while (true) {
//绘制数据
frame.render(circles);
AlgoVisHelper.pause(20);
//更新数据
for (Circle circle : circles) {
circle.move(0, 0, frame.getCanvasWidth(), frame.getCanvasHeight());
}
}
}
}
键盘事件(去掉Main类)
键盘按空格暂停/继续
package com.company;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class AlgoVisualizer {
private Circle[] circles;
private AlgoFrame frame;
private boolean isAnimated = true;
public AlgoVisualizer(int sceneWidth, int sceneHeight, int N) {
circles = new Circle[N];
int R = 30;
for (int i = 0; i < N; i++) {
int x = (int) Math.random() * (sceneWidth - 2 * R) + R;
int y = (int) Math.random() * (sceneHeight - 2 * R) + R;
int vx = (int) (Math.random() * 11 - 5);
int vy = (int) (Math.random() * 11 - 5);
circles[i] = new Circle(x, y, R, vx, vy);
}
EventQueue.invokeLater(() -> {
frame = new AlgoFrame("Welcome", sceneWidth, sceneHeight);
frame.addKeyListener(new AlgoKeyListener());
new Thread(() -> {
run();
}).start();
});
}
//动画逻辑
private void run() {
while (true) {
//绘制数据
frame.render(circles);
AlgoVisHelper.pause(20);
//更新数据
if (isAnimated) {
for (Circle circle : circles) {
circle.move(0, 0, frame.getCanvasWidth(), frame.getCanvasHeight());
}
}
}
}
private class AlgoKeyListener extends KeyAdapter {
@Override
public void keyReleased(KeyEvent event) {
if (event.getKeyChar() == ' ') {
isAnimated = !isAnimated;
}
}
}
public static void main(String[] args) {
int sceneWidth = 500;
int sceneHeight = 500;
int N = 10;
AlgoVisualizer visualizer = new AlgoVisualizer(sceneWidth, sceneHeight, N);
}
}
鼠标事件
Circle
package com.company;
import java.awt.*;
public class Circle {
public int x, y;
private int r;
public boolean isFilled = false;
public int getR() {
return r;
}
public void setR(int r) {
this.r = r;
}
public int vx, vy;
public Circle(int x, int y, int r, int vx, int vy) {
this.x = x;
this.y = y;
this.setR(r);
this.vx = vx;
this.vy = vy;
}
public void move(int minx, int miny, int maxx, int maxy) {
x += vx;
y += vy;
checkCollision(minx, miny, maxx, maxy);
}
private void checkCollision(int minx, int miny, int maxx, int maxy) {
if (x - r < minx) {
x = r;
vx = -vx;
}
if (x + r >= maxx) {
x = maxx - r;
vx = -vx;
}
if (y - r < miny) {
y = r;
vy = -vy;
}
if (y + r >= maxy) {
y = maxy - r;
vy = -vy;
}
}
public boolean contain(Point p) {
return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y) <= r * r;
}
}
AlgoVisHelper
package com.company;
import java.awt.*;
import java.awt.geom.Ellipse2D;
public class AlgoVisHelper {
private AlgoVisHelper() {
}
public static void setColor(Graphics2D g2d,Color color){
g2d.setColor(color);
}
public static void setStrokeWidth(Graphics2D g2d, int w) {
int strokeWidth = w;
g2d.setStroke(new BasicStroke(strokeWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
}
public static void strokeCircle(Graphics2D g2d,int x,int y,int r){
Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
g2d.draw(circle);
};
public static void fillCircle(Graphics2D g2d,int x,int y,int r){
Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
g2d.fill(circle);
};
public static void pause(int t){
try{
Thread.sleep(t);
}catch (InterruptedException e){
System.out.println("Error in sleeping!");
}
}
}
AlgoVisualizer
package com.company;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class AlgoVisualizer {
private Circle[] circles;
private AlgoFrame frame;
private boolean isAnimated = true;
public AlgoVisualizer(int sceneWidth, int sceneHeight, int N) {
circles = new Circle[N];
int R = 30;
for (int i = 0; i < N; i++) {
int x = (int) Math.random() * (sceneWidth - 2 * R) + R;
int y = (int) Math.random() * (sceneHeight - 2 * R) + R;
int vx = (int) (Math.random() * 11 - 5);
int vy = (int) (Math.random() * 11 - 5);
circles[i] = new Circle(x, y, R, vx, vy);
}
EventQueue.invokeLater(() -> {
frame = new AlgoFrame("Welcome", sceneWidth, sceneHeight);
frame.addKeyListener(new AlgoKeyListener());
frame.addMouseListener(new AlgoMouseListener());
new Thread(() -> {
run();
}).start();
});
}
//动画逻辑
private void run() {
while (true) {
//绘制数据
frame.render(circles);
AlgoVisHelper.pause(20);
//更新数据
if (isAnimated) {
for (Circle circle : circles) {
circle.move(0, 0, frame.getCanvasWidth(), frame.getCanvasHeight());
}
}
}
}
private class AlgoMouseListener extends MouseAdapter{
@Override
public void mousePressed(MouseEvent event) {
event.translatePoint(0,-(frame.getBounds().height-frame.getCanvasHeight()));
for(Circle circle:circles){
if(circle.contain(event.getPoint())){
circle.isFilled = !circle.isFilled;
}
}
}
}
private class AlgoKeyListener extends KeyAdapter {
@Override
public void keyReleased(KeyEvent event) {
if (event.getKeyChar() == ' ') {
isAnimated = !isAnimated;
}
}
}
public static void main(String[] args) {
int sceneWidth = 500;
int sceneHeight = 500;
int N = 10;
AlgoVisualizer visualizer = new AlgoVisualizer(sceneWidth, sceneHeight, N);
}
}
AlgoFrame
package com.company;
import javax.swing.*;
import java.awt.*;
public class AlgoFrame extends JFrame {
private int canvasWidth;
private int canvasHeight;
public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
super(title);
this.canvasWidth = canvasWidth;
this.canvasHeight = canvasHeight;
AlgoCanvas canvas = new AlgoCanvas();
setContentPane(canvas);
pack();
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public AlgoFrame(String title) {
this(title, 1024, 768);
}
public int getCanvasWidth() {
return canvasWidth;
}
public int getCanvasHeight() {
return canvasHeight;
}
private Circle[] circles;
public void render(Circle[] circles) {
this.circles = circles;
repaint();
}
private class AlgoCanvas extends JPanel {
//双缓存
public AlgoCanvas() {
super(true);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//抗锯齿
RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.addRenderingHints(hints);
//具体绘制
AlgoVisHelper.setStrokeWidth(g2d, 1);
AlgoVisHelper.setColor(g2d, Color.RED);
for (Circle circle : circles) {
if (!circle.isFilled) {
AlgoVisHelper.strokeCircle(g2d, circle.x, circle.y, circle.getR());
} else {
AlgoVisHelper.fillCircle(g2d, circle.x, circle.y, circle.getR());
}
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(canvasWidth, canvasHeight);
}
}
}