创意画板项目及其具体内容教程

1. 创建shouui方法

要想绘制一个可见的画板,我们需要用到Java类库中的Jframe类来帮助我们创建

首先,我们先创建shouui()方法,并且在main中调用此方法

public class UI{
    
    public void showui(){
        
    }
​
    public static void main(String[] args) {
            UI ui = new UI();
            ui.showui();
​
    }
}
​

这样,我们在shouui()中写的代码就可以在main中运行了

创意画板项目需要java.lang包下的swing类和awt类,所以导入进来(导包)

import javax.swing.*;
import java.awt.*;

2.创建画板

然后就是创建画板了

 public void showui(){
​
        JFrame jf = new JFrame();
​
        //尺寸,标题,居中,关闭,可见
        jf.setSize(1500,800);
        jf.setTitle("创意画板");
        jf.setLocationRelativeTo(null);//窗体在绘制时处于屏幕中央
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//点击窗体右上角的x可以结束程序
        jf.setVisible(true);
     
}
        

这样,我们就获得了一张这样的画板

 

当我们点击右上角的x时,程序结束

 

3.布局管理器

现在,我们开始丰富这个窗口吧

一个成熟的创意画板应该拥有很多功能,而选择不同的功能就需要不同的按钮,所以我们先给画板添加按钮

要添加按钮,就要介绍下布局管理器了

//流式布局管理器
//        FlowLayout flowLayout = new FlowLayout();
//        jf.setLayout(flowLayout);
​
        //边框布局管理器
        BorderLayout borderLayout = new BorderLayout();
        jf.setLayout(borderLayout);

布局管理器,顾名思义,管理布局的。按钮的布局我们就是通过布局管理器进行布局管理,其中,流式布局管理器的布局特点是:从第一行开始分布,居中显示,如果一行不够则在第一行填满的情况下用第二行(居中显示)

 

 

而边框布局管理器则是将画板分为五块,每一块内部都是流式布局管理

 

流式布局管理器的用法具体为

//面板对象
        JPanel westjPanel = new JPanel();
//        westjPanel.setBackground(Color.WHITE);
        westjPanel.setPreferredSize(new Dimension(120,0));
        jf.add(westjPanel,BorderLayout.WEST);
​
        JPanel eastjPanel = new JPanel();
//        eastjPanel.setBackground(Color.WHITE);
        eastjPanel.setPreferredSize(new Dimension(50,0));
        jf.add(eastjPanel,BorderLayout.EAST);
​
        JPanel centerjPanel = new JPanel();
//        centerjPanel.setBackground(Color.WHITE);
        jf.add(centerjPanel,BorderLayout.CENTER);
​
        JPanel southjPanel = new JPanel();
//        southjPanel.setBackground(Color.WHITE);
        southjPanel.setPreferredSize(new Dimension(0,40));
        jf.add(southjPanel,BorderLayout.SOUTH);

其中,南北只能设置高度,东西只能设置宽度,中间是剩余的空间,无法设置(设置了也没有用)

4.添加按钮

由于我们会添加很多按钮,而每一次添加按钮都会进行重复的添加操作,所以我创建了一个集合用于存放按钮的名字,再用增强for循环遍历集合,在循环内部进行添加操作

ArrayList<String> functionlist = new ArrayList();
functionlist.add("直线");
functionlist.add("三角形");
functionlist.add("任意多边形");
​
​
for(String f : functionlist){
    JButton a = new JButton(f);
    westjPanel.add(a);
​
​
}

现在,我们的画板上就有按钮了

 

5.添加监听器

但是,现在我们点击按钮,什么事情都不会发生,这是因为我们还没有给按钮添加相对应的监听器,现在我们来添加监听器

 

我们这里会用到三种监听器

新建mouselistener类实现MouseListener,ActionListener,MouseMotionListener接口,并且实现相应的抽象方法

public class mouselistener implements MouseListener,ActionListener,MouseMotionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        //点击按钮
    }
​
    @Override
    public void mouseClicked(MouseEvent e) {
        //点击
    }
​
    @Override
    public void mousePressed(MouseEvent e) {
        //按下
    }
​
    @Override
    public void mouseReleased(MouseEvent e) {
        //释放
    }
​
    @Override
    public void mouseEntered(MouseEvent e) {
        //进入
    }
​
    @Override
    public void mouseExited(MouseEvent e) {
        //离开
    }
​
    @Override
    public void mouseDragged(MouseEvent e) {
        //鼠标拖动事件
    }
​
    @Override
    public void mouseMoved(MouseEvent e) {
        //鼠标移动事件
    }
}

现在,当我们需要在画板的哪个部分实现什么功能的时候,只需要将此部分添加对应功能需要的监听器,然后在事件内部写对应的代码就行啦

比如,我想实现按下直线按钮后,就可以在centerjPanel上画直线的功能。

首先,按按钮事件是由接口ActionListener中actionPerformed()方法实现的。

其次,画直线需要你点击画板,然后移动鼠标松开,绘制直线,当然你也可以选择不同的方式。此处的方式会用到MouseListener中mousePressed(),和mouseReleased()方法

所以我们在UI类中新建窗口鼠标监听器

mouselistener mouselistener = new mouselistener();

并且在增强for循环中添加鼠标监听器

for(String f : functionlist){
    JButton a = new JButton(f);
    westjPanel.add(a);
    a.addActionListener(mouselistener);
    
}

这样,我们在点击按钮时,就会执行mouselistener类中的actionPerformed()方法了

然后,我们给centerjPanel添加MouseListener监听器

centerjPanel.addMouseListener(mouselistener);

这样,我们在centerjPanel用鼠标进行操作的时候就能触发对应的方法了

但是,想要在mouselistener类中达到在centerjPanel绘画,我们还需要将centerjPanel的画笔传递给mouselistener

在mouselistener类中创建画笔和对应的set方法

private Graphics gr = null;
public void setGr(Graphics gr) {
        this.gr = gr;
    }

在UI类中

//从中间窗体获取画笔
Graphics g = centerjPanel.getGraphics();
​
//将画笔传递给鼠标监听器
mouselistener.setGr(g);

给centerjPanel添加对应监听器

centerjPanel.addMouseMotionListener(mouselistener);
centerjPanel.addMouseListener(mouselistener);

现在,基础知识完备,我们可以来发挥我们的聪明才智,丰富我们的画板了!

6.绘制直线

当我们点击按钮“直线”时,获取按钮的名字

private String firstname = "";
@Override
public void actionPerformed(ActionEvent e) {
    //点击按钮
    firstname = e.getActionCommand();//获取按钮的名字
}

然后在按下按钮时,获取x1,y1,松开时,获取x2,y2,绘制

@Override
public void mousePressed(MouseEvent e) {
    //按下
    if(name.equals("直线")){
        x1 = e.getX();
        y1 = e.getY();
    }
}
​
@Override
public void mouseReleased(MouseEvent e) {
    //释放
    if(name.equals("直线")){
        x2 = e.getX();
        y2 = e.getY();
        gr.drawLine(x1,y1,x2,y2);
​
    }
}

这样,我们在按下“直线”按钮后,在centerJpanel中我们就可以自由的画直线了

 

然后,就是写绘制三角形和任意多边形的方法了

7.绘制三角形和任意多边形

三角形:

 private int flag = 0;
@Override
    public void mousePressed(MouseEvent e) {
        //按下
        if(name.equals("三角形") && flag == 0){
            x1 = e.getX();
            y1 = e.getY();
        }
    }
 @Override
    public void mouseReleased(MouseEvent e) {
        //释放
         if(name.equals("三角形") && flag == 0){
            x2 = e.getX();
            y2 = e.getY();
            gr.drawLine(x1,y1,x2,y2);
            flag++;
        }
    }
@Override
public void mouseClicked(MouseEvent e) {
    //点击
    if(name.equals("三角形") && flag == 1){
        x3 = e.getX();
        y3 = e.getY();
        gr.drawLine(x1,y1,x3,y3);
        gr.drawLine(x2,y2,x3,y3);
        Myshape myshape = new Myshape(x1,y1,x2,y2,x3,y3,name, gr.getColor(),D);
        myshapes[index++] = myshape;
        flag--;
    }
}

任意多边形:

@Override
    public void mouseClicked(MouseEvent e) {
        //点击
         if(name.equals("任意多边形")){
            if(e.getButton() == 1){
                if(flag == 0) {
                    x1 = e.getX();
                    y1 = e.getY();
                }else if(flag == 1){
                    x2 = e.getX();
                    y2 = e.getY();
                    gr.drawLine(x2,y2,x1,y1);
                }else {
                    gr.drawLine(x2,y2,e.getX(),e.getY())
                    x2 = e.getX();
                    y2 = e.getY();
                }
                flag++;
​
            }
            if(e.getButton() == 3){
                gr.drawLine(x2,y2,x1,y1);
                flag = 0;
            }
        }
    }

8.绘制曲线

在按下方法中

if(name.equals("曲线")){
    x1 = e.getX();
    y1 = e.getY();
​
}
 @Override
    public void mouseDragged(MouseEvent e) {
        //鼠标拖动事件
        if(name.equals("曲线")){
            x2 = e.getX();
            y2 = e.getY();
            gr.drawLine(x1,y1,x2,y2);
            x1 = x2;
            y1 = y2;
        }
​
    }

9.添加颜色按钮

在学会了如何绘制各种基础图形之后,我们尝试给这些图形添加一些属性

在UI界面中,和添加按钮一样,创建集合存储按钮

//添加右侧颜色按钮
ArrayList<Color> colorlist = new ArrayList<>();
colorlist.add(Color.yellow);
colorlist.add(Color.pink);
colorlist.add(Color.black);
colorlist.add(Color.blue);
colorlist.add(Color.red);
colorlist.add(Color.cyan);
colorlist.add(Color.DARK_GRAY);
colorlist.add(Color.GRAY);
colorlist.add(Color.GREEN);
colorlist.add(Color.LIGHT_GRAY);
colorlist.add(Color.MAGENTA);
colorlist.add(Color.ORANGE);
colorlist.add(Color.WHITE);
​
for(Color color : colorlist){
    JButton a = new JButton();
    a.setPreferredSize(new Dimension(30,30));//设置按钮大小
    a.setBackground(color);
    eastjPanel.add(a);
    a.addActionListener(mouselistener);
}

然后在mouslistener类的actionPerformed()方法中

private String firstname = "",name = "";
@Override
public void actionPerformed(ActionEvent e) {
    //点击按钮
​
    firstname = e.getActionCommand();
​
    if(firstname == ""){
        JButton JButton = (JButton) e.getSource();//e.getSource():获取按钮对应的对象(Object类)
        gr.setColor(JButton.getBackground());
    }else{
        name = firsename;
    }
}

这样,我们就获得了这样的界面

 

10.自定义颜色

众所周知,所有颜色都是由绿色,红色,蓝色三种基础色进行混合合成的,所以,我们也可以给我们的画板添加自定义颜色

在UI类中

//自定义颜色
JTextField R = new JTextField(3);
JTextField G = new JTextField(3);
JTextField B = new JTextField(3);
R.setText("0");
G.setText("0");
B.setText("0");
southjPanel.add(new JLabel("自定义颜色  R:"));
southjPanel.add(R);
southjPanel.add(new JLabel("G:"));
southjPanel.add(G);
southjPanel.add(new JLabel("B:"));
southjPanel.add(B);
JButton a1 = new JButton("确定");
southjPanel.add(a1);
a1.addActionListener(mouselistener);

效果

 

在mouselistener类中

private JTextField R;
private JTextField G;
private JTextField B;
@Override
public void actionPerformed(ActionEvent e) {
    //点击按钮
​
    firstname = e.getActionCommand();
​
    if(firstname == "确定"){
            gr.setColor(new Color(Integer.parseInt(R.getText()),Integer.parseInt(G.getText()),Integer.parseInt(B.getText())));
​
        }else if(firstname == ""){
        JButton JButton = (JButton) e.getSource();//e.getSource():获取按钮对应的对象(Object类)
        gr.setColor(JButton.getBackground());
    }else{
        name = firsename;
    }
}

11.设置粗细

//添加底侧按钮和文本框
ArrayList<String> downlist = new ArrayList();
downlist.add("加粗");
downlist.add("减细");

在mouselistener类中,设置静态变量D表示粗细

static int D = 3;
@Override
public void actionPerformed(ActionEvent e) {
    //点击按钮
    
    Graphics2D d2 = (Graphics2D)gr;
    gr = d2;
    d2.setStroke(new BasicStroke(D));//Graphics2D类有设置粗细的方法
​
    firstname = e.getActionCommand();
​
    if(firstname == "确定"){
            gr.setColor(new Color(Integer.parseInt(R.getText()),Integer.parseInt(G.getText()),Integer.parseInt(B.getText())));
​
        }else if(firstname == ""){
        JButton JButton = (JButton) e.getSource();//e.getSource():获取按钮对应的对象(Object类)
        gr.setColor(JButton.getBackground());
    }else if(firstname == "加粗"){
            D += 2;
​
    }else if(firstname == "减细"){
            if(D > 1){
            D -= 2;
    }else{
        name = firsename;
    }
}

现在,效果图就是这样了

 

12.重写paint()方法

要注意,Jfream在窗体发生任意改变的时候,都会重新调用panit()方法,所以在我们绘制了一些图形之后,一旦我们对窗体进行了任意改动,比如把窗口拉大,移动窗口到屏幕外,都会使得我们辛辛苦苦画的图形消失或者残缺,所以为了不让这种状况发生,我新建了Myshape类用于存储我们画的物体的数据,并且在paint()时调用。

由于我们是要重绘centrjPanel面板,所以让UI继承JPanel

将UI界面中的centrjPanel.改为this.

借鉴传递画笔的过程,将UI对象传递给mouslistener类

mouselistener.setUi(this);//UI
private UI ui = null;
public void setUi(UI ui) {
    this.ui = ui;
}//mouslistener
public class Myshape {
​
    private int x1;
    private int y1;
    private int x2;
    private int y2;
    private int x3;
    private int y3;
    private String name;
    private Color color;
    private int D;//粗细
​
    //初始化属性
​
    public Myshape(int x1, int y1, int x2, int y2, String name, Color color, int d) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.name = name;
        this.color = color;
        D = d;
    }
​
    public Myshape(int x1, int y1, int x2, int y2, int x3, int y3, String name, Color color, int d, int fengxingFlag) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.x3 = x3;
        this.y3 = y3;
        this.name = name;
        this.color = color;
        D = d;
        this.fengxingFlag = fengxingFlag;
    }
​
    public Myshape(int x1, int y1, int x2, int y2, int x3, int y3, String name, Color color, int d) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.x3 = x3;
        this.y3 = y3;
        this.name = name;
        this.color = color;
        D = d;
    }
​
    //还原图形
​
    public String getName() {
        return name;
    }
​
    public void drawShape(Graphics g){
        Graphics2D d2 = (Graphics2D)g;
        g.setColor(color);
        d2.setStroke(new BasicStroke(D));
        switch (name){
            case "直线":
                g.drawLine(x1,y1,x2,y2);
                break;
​
            case"三角形":
                g.drawLine(x1,y1,x2,y2);
                g.drawLine(x1,y1,x3,y3);
                g.drawLine(x3,y3,x2,y2);
                break;
​
            case "曲线":
                g.drawLine(x1,y1,x2,y2);
                break;
​
            case "任意多边形":
                g.drawLine(x1,y1,x2,y2);
                break;
​
​
        }
    }
}

在UI界面中重写paint方法

@Override
    public void paint(Graphics g){
​
            super.paint(g);
            for (int i = 0; i < myshapes.length; i++) {
                if (myshapes[i] != null) {
                    myshapes[i].drawShape(g);
//                    System.out.println(myshapes[i].getName());
​
                }
            }
        
    }

然后在mouselistener类中创建myshapes数组

private Myshape[] myshapes = new Myshape[10000];
private int index = 0;

然后在需要存储的地方,用对应的构造器进行存储,例如:

Myshape myshape = new Myshape(x1,y1,x2,y2,x3,y3,name, gr.getColor(),D);
myshapes[index++] = myshape;

13.清空方法

给界面添加清空按钮

functionlist.add("清空");
if(firstname == "清空"){
    ui.flag = true;
    ui.rep();
​
}
public void rep(){
    paint(this.getGraphics());
    for (int i = 0; i < myshapes.length; i++) {
        myshapes[i] = null;
    }
​
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值