看的见的算法—GUI框架搭建
一直以来学算法解决实际问题都是一件枯燥的事情因为我们只能面对枯燥的控制台输出语句那大家有没有想过用GUI的形式演示我们的算法不仅效果明显而且十分有趣
搭建GUI框架注意:
1.我们可以使用Android,IOS或者css的canvas都可以绘制我们的效果不过为了统一和简单也基于本人接触过java的swing我们和大佬用的一样。
2.其实我们所有的GUI框架都是一样的,我们学会了一种学习其他的将会非常的快速
开始搭建框架
1.java.swing的JFrame这是java swing的窗体类我们继承者这个类来构建我们的视图层我们所使用的一些Swing的技巧这里面只用了一个双缓存为了实现动画的过度使用两个缓存面板交替绘制,而后就是我们为边缘平滑使用的抗锯齿效果(我们的重点是算法)
视图层
package com.lipengge.montecarlo.view;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.lipengge.montecarlo.data.MonteCarloData;
import com.lipengge.randomquestion.util.AlgoVisHelper;
public class AlgoFrame extends JFrame{
private static final long serialVersionUID = -3035088527551930125L;
private int canvasWidth;
private int canvasHeight;
private Object data;
public int getCanvasWidth() {
return canvasWidth;
}
public int getCanvasHeight() {
return canvasHeight;
}
public void render(Object data){
this.data=data;
repaint();
}
public AlgoFrame(String title,int canvasWidth, int canvasHeight){
super(title);
this.canvasWidth=canvasWidth;
this.canvasHeight=canvasHeight;
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
AlgoCanvas algoCanvas = new AlgoCanvas();
setContentPane(algoCanvas);
pack();
}
class AlgoCanvas extends JPanel{
private static final long serialVersionUID = -6056196800598676936L;
private AlgoCanvas(){
super(true);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d=(Graphics2D) g;
AlgoVisHelper.setRenderingHints(g2d);
AlgoVisHelper.setStrokeWidth(g2d, 1);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(canvasWidth,canvasHeight);
}
}
}
辅助类
这里面提供了我们的一些图形绘制 圆和正方形他们的空心和填充状态
package com.lipengge.montecarlo.util;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
public class AlgoVisHelper {
private AlgoVisHelper(){}
public static void strokeCircle(Graphics2D g,int x,int y,int r){
Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
g.draw(circle);
}
public static void fillCircle(Graphics2D g,int x,int y,int r){
Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
g.fill(circle);
}
public static void strokeReactangle(Graphics2D g,int x,int y,int width,int height){
Rectangle2D reactangle = new Rectangle2D.Double(x,y,width,height);
g.draw(reactangle);
}
public static void fillReactangle(Graphics2D g,int x,int y,int width,int height){
Rectangle2D reactangle = new Rectangle2D.Double(x,y,width,height);
g.fill(reactangle);
}
public static void setColor(Graphics2D g,Color color){
g.setColor(color);
}
public static void setStrokeWidth(Graphics2D g,int w){
g.setStroke(new BasicStroke(w,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
}
public static void setRenderingHints(Graphics2D g){
RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.addRenderingHints(hints);
}
public static void pause(long millsecond){
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
控制层
package com.lipengge.montecarlo.controller;
import java.awt.EventQueue;
import java.awt.Point;
import com.lipengge.montecarlo.data.MonteCarloData;
import com.lipengge.montecarlo.model.Circle;
import com.lipengge.montecarlo.view.AlgoFrame;
import com.lipengge.randomquestion.util.AlgoVisHelper;
public class AlgoVisualizer {
private AlgoFrame frame;
private int screenHeight;
private int screenWidth;
public AlgoVisualizer(int screenWidth,int screenHeight){
this.screenWidth=screenWidth;
this.screenHeight=screenHeight;
EventQueue.invokeLater(()->{
frame=new AlgoFrame("标题",screenWidth,screenHeight);
new Thread(()->run()).start();
});
}
public void run(){
}
public static void main(String[] args) {
new AlgoVisualizer(screenWidth,screenHeight);
}
}
这只是我们的模板之后我们对此进行改进来实现我们的算法下一篇我们来验证我们的模板