【Java】如何在界面刷新后保留图案

每次当我们对界面扩大或缩小时,因为改变了界面的大小,界面就会刷新并且绘制在界面上的图案并不属于界面中的元素,当界面刷新时图案就会消失。为了解决这个问题,我们需要创建一个新的类继承原来的界面,并且重写刷新方式,让刷新后的界面也会显示出图案。

创建新的类来继承窗体对象:

public class NewJFrame extends JFrame {}

在创建窗体对象时引用NewJFrame,创建窗体对象:

//引用完成重写刷新方式的窗体对象
        NewJFrame pad=new NewJFrame();
        pad.setTitle("画图板");
        pad.setSize(730,600);
        pad.setLocation(280,50);
        pad.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        FlowLayout layout=new FlowLayout();
        pad.setLayout(layout);
        
        //创建鼠标监听对象
        DrawListener d1=new DrawListener();
        
        //添加选择图形的按钮
        String[] shapeNames={"直线","实心矩形","矩形","实心三角形","三角形","长方体","圆形","实心圆形"};
        for(int i=0;i< shapeNames.length;i++){
            JButton btn=new JButton(shapeNames[i]);
            pad.add(btn);
            btn.addActionListener(d1);
        }
        //选择画图的颜色
        Color[] colors={Color.black,Color.white,Color.gray,Color.lightGray,Color.darkGray,
                Color.red,Color.blue,Color.yellow,Color.green,Color.orange,Color.pink,Color.magenta
        };
        for(int i=0;i< colors.length;i++){
            JButton btn=new JButton(" ");
            btn.setBackground(colors[i]);
            pad.add(btn);
            btn.addActionListener(d1);
        }

        //进行可视化
        pad.setVisible(true);

        //添加监听对象(鼠标)
        pad.addMouseListener(d1);
        //获取画笔
        Graphics g= pad.getGraphics();
        //使界面中的图形渲染器和鼠标监听器中的图形渲染器表示为同一个
        d1.g1= g;
        //由于要使用d1中的内容,把监听器传入pad对象中
        pad.d1=d1;

然后就是编写监听器用来实现画图和调色:

public class DrawListener implements MouseListener , ActionListener {
    //添加画笔对象
    Graphics g1;
    //起始和终末的坐标
    int x1,y1,x2,y2;
    //进行初始化,防止报错
    String shape="直线";
    Color color=Color.black;
    //创建数组用来存储图案
    MyShape[] shapeList=new MyShape[10];
    int shapeLength=10;
    int shapeCount=0;

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(e.getActionCommand());
        //获取按钮上的文本
        String word=e.getActionCommand();
        //进行判断
        if(word.equals(" ")){//获取点击按钮的背景颜色,并将其作为画笔改变像素点后的颜色
            //创建一个按钮对象指向界面中的按钮
            JButton btn=(JButton) e.getSource();
            //获取按钮背景色
            color=btn.getBackground();
            //改变画笔的颜色
            g1.setColor(color);
        }
        else{
            shape=word;
        }
    }

    @Override
    public void mouseClicked(MouseEvent e){
        System.out.println("点击");
    }

    @Override
    public void mousePressed(MouseEvent e){
        System.out.println("按下");
        //获取按下鼠标时的坐标
        x1=e.getX();
        y1=e.getY();
    }
    @Override
    public void mouseReleased(MouseEvent e) {
        System.out.println("松开");
        //获取松开鼠标时的坐标
        x2 = e.getX();
        y2 = e.getY();
        if(shape.equals(" ")){
            return;
        }
        else{
            //将数据输入进画图的类中,并将其存入数组中
            MyShape ms=new MyShape();
            ms.shapeName=shape;
            ms.color=color;
            ms.x1=x1;
            ms.y1=y1;
            ms.x2=x2;
            ms.y2=y2;
            shapeList[shapeCount++]=ms;
            //进行扩容
            if(shapeCount==shapeLength){
                int newSize=shapeCount+(shapeCount>>1);
                MyShape[] newArray=new MyShape[newSize];
                for(int i=0;i<shapeLength;i++){
                    newArray[i]=shapeList[i];
                }
                shapeList=newArray;
                shapeLength=newSize;
            }
            //进行绘图
            ms.drawShape(g1);
        }
    }

    @Override
    public void mouseEntered(MouseEvent e){
        System.out.println("进入");
    }

    @Override
    public void mouseExited(MouseEvent e){
        System.out.println("离开");
    }

}

这里要将画出的图案存入数组中,以便刷新时重新在窗体上显示出图案。

因为监听器功能太多,我们就在另一个类中编写绘图的方法,并且在监听器中使用:

public class MyShape {
    int x1,y1,x2,y2;
    String shapeName;
    Color color;

    public void drawShape(Graphics g){//实现绘图的方法
        g.setColor(color);
        //线条
        if (shapeName.equals("直线")) {
            g.drawLine(x1, y1, x2, y2);
        }

        //矩形
        if (shapeName.equals("矩形")) {
            g.drawLine(x1, y1, x2, y1);
            g.drawLine(x1, y1, x1, y2);
            g.drawLine(x2, y1, x2, y2);
            g.drawLine(x1, y2, x2, y2);
        }
        if (shapeName.equals("实心矩形")) {
            g.drawLine(x1, y1, x2, y1);
            g.drawLine(x1, y1, x1, y2);
            g.drawLine(x2, y1, x2, y2);
            g.drawLine(x1, y2, x2, y2);
            for (int i = x1; i <= x2; i++) {
                g.drawLine(i, y1, i, y2);
            }
            for (int i = x2; i <= x1; i++) {
                g.drawLine(i, y1, i, y2);
            }
        }

        //三角形
        if (shapeName.equals("三角形")) {
            int i = (x1 + x2) / 2;
            g.drawLine(i, y1, x1, y2);
            g.drawLine(i, y1, x2, y2);
            g.drawLine(x1, y2, x2, y2);
        }
        if (shapeName.equals("实心三角形")) {
            int i = (x1 + x2) / 2;
            g.drawLine(i, y1, x1, y2);
            g.drawLine(i, y1, x2, y2);
            g.drawLine(x1, y2, x2, y2);
            for (int j = i; j <= x2; j++) {
                int p = x1 + x2 - j;
                int y = (j - i) * (y1 - y2) / (i - x2) + y1;
                g.drawLine(j, y, j, y2);
                g.drawLine(p, y, p, y2);
            }
            for (int j = i; j >= x2; j--) {
                int p = x1 + x2 - j;
                int y = (j - i) * (y1 - y2) / (i - x2) + y1;
                g.drawLine(j, y2, j, y);
                g.drawLine(p, y2, p, y);
            }
        }

        //长方体
        if (shapeName.equals("长方体")) {
            g.drawLine(x1, y1, x2, y1);
            g.drawLine(x1, y1, x1, y2);
            g.drawLine(x2, y1, x2, y2);
            g.drawLine(x1, y2, x2, y2);
            int x = (Math.abs(x1 - x2)) / 4;
            int y = (Math.abs(y1 - y2)) / 4;
            int x3 = Math.max(x1, x2);
            int x4 = Math.min(x1, x2);
            int y3 = Math.max(y1, y2);
            int y4 = Math.min(y1, y2);
            g.drawLine(x4 + x, y4 - y, x4, y4);
            g.drawLine(x3 + x, y4 - y, x3, y4);
            g.drawLine(x3 + x, y3 - y, x3, y3);
            g.drawLine(x4 + x, y4 - y, x3 + x, y4 - y);
            g.drawLine(x3 + x, y4 - y, x3 + x, y3 - y);
        }

        //圆形
        if (shapeName.equals("圆形")){
            //因为坐标没有小数,这里要强制类型转换
            int r=(int)Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))/2;
            int x=(x1+x2)/2,y=(y1+y2)/2;
            int x3=x-r;
            int y3=y-r;
            int x4=x+r;
            int y4=y+r;
            for(int i=x3;i<=x4;i++){
                for(int j=y3;j<=y4;j++) {
                    int r1 = (int) Math.sqrt((i - x) * (i - x) + (j - y) * (j - y));
                    if (r1 > r - 1 && r1 < r + 1) {
                        g.drawLine(i, j, i, j);
                    }
                }
            }
        }

        //实心圆形
        if (shapeName.equals("实心圆形")){
            int r=(int)Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))/2;
            int x=(x1+x2)/2,y=(y1+y2)/2;
            int x3=x-r;
            int y3=y-r;
            int x4=x+r;
            int y4=y+r;
            for(int i=x3;i<=x4;i++){
                for(int j=y3;j<=y4;j++) {
                    int r1 = (int) Math.sqrt((i - x) * (i - x) + (j - y) * (j - y));
                    if (r1 <= r) {
                        g.drawLine(i, j, i, j);
                    }
                }
            }
        }


    }
}

最后就是来改变窗体的刷新方式:

public class NewJFrame extends JFrame {
    DrawListener d1;
    public void paint(Graphics g){
        super.paint(g);//刷新窗体本身原本的代码
        for(int i=0;i<d1.shapeLength;i++){
            MyShape myShape=d1.shapeList[i];
            if(myShape==null){//判断元素是否为空
                return;
            }
            //将原来图案绘制在刷新后的窗体中
            myShape.drawShape(g);
        }
    }
}

这里添加的代码就相当于对原本的刷新方式进行了重写。

最后结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值