
Swing界面实现画图板
最近几天在蓝杰集训,编写了一个简单的画图板。
实现画图板,首先需要创建一个继承JFrame的类,用这个类中父类的方法创建一个窗体并添加按键,为窗体和上面的按键添加监听器(监听器继承了接口Mouselistener、MouseMotionListener和ActionListioner)。
因为画图形需要在画板上获取坐标,所以添加的面板监听器是MouseListener(可以画直线和形状)和MouseMitionListener(可以画曲线)。用不同的Graphics的方法形状还可以多样化。
因为ActionListener中的方法中的getActionCommand可以用来获得按钮的信息,所以只为按键添加ActionListener。
因为每次改变窗体的显示范围或者最小化后重新打开窗体,窗体都会进行重绘,所以我们还需要创建一个数组队列来存储先相关的形状属性(另外新建一个形状的类,并创建一个个对象,对象里面存储了形状的信息的属性,我们可以用形状类的数组队列来存储一个个形状对象),在重写重绘方法的时候调用数组,重绘形状。
其中图形是画在面板上的,所以获取的Graphics是面板的Graphics,并且通过调用之前在监听器类中写好的获取画笔的方法传入监听器中(使用构造方法中的构造器传参的话,必须在创建对象时进行参数传递,假另外编写一个获取参数的方法的,可以更自由地在需要传入参数的时候进行参数传递),再对画笔的形状、粗细和颜色进行调整。
以下是我的窗体代码
public class logListener extends JFrame implements MouseListener{
private loginUI ui;
Graphics g;
public Graphics2D gg;
Listener li;
public logListener(loginUI ui){
this.ui=ui;
}
public void mouseClicked(MouseEvent e) {
ui.dispose();
logListener boardUI = new logListener(null);
boardUI.showUI();
}
public void showUI(){
this.setTitle("画图板");
this.setSize(800,600);
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
this.setResizable(false);
//设置西边北边区域
//创建一个JPanel
JPanel jpw = new JPanel();
jpw.setPreferredSize(new Dimension(800,100));
jpw.setBackground(Color.LIGHT_GRAY);
//顶端空白
JPanel jpw2= new JPanel();
jpw2.setPreferredSize(new Dimension(800,20));
jpw2.setBackground(Color.LIGHT_GRAY);
jpw.add(jpw2);
//颜色文字提示
jpw.add(new JLabel("选择颜色:"));
//创建监听器
li = new Listener();
//设置颜色按钮
for(int i=0;i<35;i++){
JButton jbu = new JButton();
jbu.setPreferredSize(new Dimension(15,15));
jbu.setBackground(new Color(150+3*i,i+1*8,255-i));
jbu.addActionListener(li);
jpw.add(jbu);
}
this.add(jpw,BorderLayout.NORTH);
//设置形状按钮
String[] array={"画笔","直线","椭圆","矩形","橡皮","撤销"};
for(int i=0;i<array.length;i++){
JButton jbu = new JButton(array[i]);
jbu.setPreferredSize(new Dimension(122,40));
jbu.addActionListener(li);
jpw.add(jbu);
}
this.addMouseListener(li);
this.addMouseMotionListener(li);
this.setVisible(true);
g = this.getGraphics();
li.setpen(g);
}
//重写重绘方法
public void paint(Graphics g){
super.paint(g);
gg = (Graphics2D)g;
try{
for(int i=0;i<li.que.getSzie();i++){
shapes shape = new shapes();
shape.x=li.que.array[i].x;
shape.y=li.que.array[i].y;
shape.x1=li.que.array[i].x1;
shape.y1=li.que.array[i].y1;
shape.color=li.que.array[i].color;
shape.style=li.que.array[i].style;
if(shape.style=="画笔"){
gg.setColor(shape.color);
gg.setStroke(new BasicStroke(3.0f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
gg.drawLine(shape.x, shape.y, shape.x1, shape.y1);
}
if(shape.style=="橡皮"){
gg.setColor(new Color(238,238,238));
gg.setStroke(new BasicStroke(20.0f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
gg.drawLine(shape.x, shape.y, shape.x1, shape.y1);
}
if(shape.style=="直线"){
gg.setColor(shape.color);
gg.setStroke(new BasicStroke(3.0f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
gg.drawLine(shape.x, shape.y, shape.x1, shape.y1);
}
if(shape.style=="椭圆"){
gg.setColor(shape.color);
gg.setStroke(new BasicStroke(3.0f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
gg.drawOval(shape.x, shape.y, shape.x1, shape.x1);
}
if(shape.style=="矩形"){
gg.setColor(shape.color);
gg.setStroke(new BasicStroke(3.0f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
gg.drawLine(shape.x, shape.y1, shape.x1, shape.y1);
gg.drawLine(shape.x, shape.y, shape.x1, shape.y);
gg.drawLine(shape.x1, shape.y, shape.x1, shape.y1);
gg.drawLine(shape.x, shape.y, shape.x, shape.y1);
}
}
}catch (Exception e) {
}
}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent arg0) {}
}
监听器代码
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JButton;
public class Listener implements MouseListener,ActionListener,MouseMotionListener{
public Graphics g;
public String str="画笔";;
public int x,y,x1,y1;
public Graphics2D gg;
public Color color = Color.BLACK;
queue que = new queue();
public void setpen(Graphics g){
this.g=g;
gg = (Graphics2D)g;
}
数组队列代码
public class queue {
public shapes[] array = null;
//添加形状
public void add(shapes ele){
if(array==null){
array=new shapes[]{ele};
}
else{
shapes[] newarray=new shapes[array.length+1];
for(int i=0;i<array.length;i++){
newarray[i]=array[i];
}
newarray[array.length] =ele ;
array = newarray;
}
}
//获取数组队列长度
public int getSzie(){
return array.length;
}
}
创建的形状类的代码
import java.awt.Color;
public class shapes {
public int x,y,x1,y1;
public String style;
public Color color;
}
因为之前还写了一个登陆界面,所以主函数在登陆界面那个类里头,没有出现在上述代码中。
虽然这个画图板写得有些简陋,但是学会了Swing界面中的不少方法,并且我还可以用于以上的方法对画图板进行完善。通过这次学习,我对Java编写代码的思想有了更深的体会,特别是每个类之间搭建联系需要用到传递参数,传递参数的值或者传参的时候不对,都有可能导致空指针异常(指针为空,没有获得相应的数据)。通过多次的空指针报错,我以后更应该注意避免再次犯错误。
来源:CSDN
作者:培培哥
链接:https://blog.csdn.net/u014695839/article/details/84624757