**图板优化**

图板优化

上次做的简单画图板过程很麻烦,重复的代码也很多,而且更让我们受不了的是bug太多啦,你会发现当窗体被拉伸的时候,图消失了!并且多拖出来的面板部分不能使用左边面板按钮效果。相对于真正的画图板,我们也发现画图形时效果也没显示出来,那我们该怎么解决这两个大问题呢~其实方法非常简单~今天我们学习的内容首先是分工合作(封装)~然后再来优化我们的画图板吧!
这里写图片描述

这里写图片描述
这里写图片描述一.主要内容

  1. 封装(窗体框架、左面板、中间面板、底部面板、测试函数)
  2. 画板的重绘
    2.1 泛型(MyList)列表
    2.2 Shape(父类)与各形状子类(ShapeLine、ShapeOval、ShapeRect、ShapeRound_Rect……)
  3. 显示效果

二.封装(Frame、pLeft、pCenter、pBottom、Test)
1.Frame类

//继承JFrame属性
public class Frame extends JFrame {
//需要的属性
    public pLeft pLeft;
    pBottom pBottom = null;
    pCenter pCenter = null;
    Graphics2D graphicsLeft;
//设置窗体属性,并添加组件
    public void setFrame() {
        this.setSize(500, 500);
        this.setLocationRelativeTo(null);
        this.setTitle("画图板");
        this.setDefaultCloseOperation(3);
        this.setLayout(new BorderLayout());
        pBottom = new pBottom();
        pBottom.setBottomPanel();
        pCenter = new pCenter();
        pLeft = new pLeft(graphicsLeft, pBottom);

        this.add(pCenter, BorderLayout.CENTER);
        this.add(pLeft, BorderLayout.WEST);
        this.add(pBottom, BorderLayout.SOUTH);
        this.setVisible(true);
        //画笔必须在 setVisible(true);之后!传画笔!
        graphicsLeft = (Graphics2D) pCenter.getGraphics();
        pLeft.g = graphicsLeft;
        pCenter.g = graphicsLeft;
        pBottom.g = graphicsLeft;
        //将左边面板传给中间面板,中间面板会用到
        pCenter.pL = pLeft;

    }
}

2.左边画板(pLeft)
//继承JPanel

public class pLeft extends JPanel {}

//需要的属性

public int pressedCount;// 多边形按下的次数 int pressedCount=0
public String currentComman = "line"; // 默认一开始就是直线
public Color currentColor = Color.black;//默认一开始就是黑色
public Graphics2D g;// 此时g=null;
pBottom pBottom;// 表示pBottom=null;
public int count;

// 构造方法

public pLeft(Graphics2D gr, pBottom p) {
        this.g = gr;
        this.pBottom = p;
        Dimension dSizie = new Dimension(70, 100);
        this.setPreferredSize(dSizie);// 设置窗体大小
        this.setBackground(Color.gray);// 设置背景颜色
        // 添加JButton添加图片
        String[] value = { "star", "airbrush", "brush", "color_picker","curve", "dot_rect", "eraser", "fill", "line", "magnifier","oval", "pencil", "polygon", "rect", "round_rect", "word" };
        ActionListener actionlistener = new ActionListener() { 
    public void actionPerformed(ActionEvent e) {
    //获得当前触发按钮的命令
    currentComman = e.getActionCommand();
            count = 0;  
            }
        };
        for (int i = 0; i < 16; i++) {
            ImageIcon imageicon = new ImageIcon("images/" + value[i] + ".jpg");
            JButton button = new JButton(imageicon);
            Dimension preferredSize = new Dimension(25, 25);
            button.setPreferredSize(preferredSize);
            // 给按钮添加监听
            button.addActionListener(actionlistener);
            // 给触发按钮设置一个命令
            button.setActionCommand(value[i]);
            this.add(button);
        }

    }

3.中间面板(pCenter)
//继承Jpanel

public class pCenter extends JPanel {}

//需要的属性

public int xStart1;
public int yStart1;
public int xClick1;
public int yClick1;
public int xEnd1;
public int yEnd1;
public int clickcount;
public int yClick2;
public int xClick2;
public int xStart;
public int yStart;
public int xEnd;
public int yEnd;
public int count;
public Graphics2D g;
pLeft pL;// = null;
Random random = new Random();// 随机数生成器
Shape shape = null;

//构造函数

public pCenter() {
        this.setBackground(Color.white);// 设置背景颜色
        MouseListener mouse = new MouseListener() {
            public void mouseClicked(MouseEvent e) {
                System.out.println("点击了");
                //多边形 
                    if ("polygon".equals(pL.currentComman)) {
                    clickcount = e.getClickCount();
                    if (clickcount == 1) {
                        xClick1 = e.getX();
                        yClick1 = e.getY();
                        g.drawLine(xClick1, yClick1, xEnd1, yEnd1);
                        myList.add(new ShapeLine(xClick1, yClick1, xEnd1,yEnd1, g.getColor(), 1));
                        xEnd1 = xClick1;
                        yEnd1 = yClick1;
                    } else if (clickcount == 2) {
                        xClick2 = e.getX();
                        yClick2 = e.getY();
                        g.drawLine(xEnd1, yEnd1, xStart1, yStart1);
                        //放到容器中重绘
                        myList.add(new ShapeLine(xEnd1, yEnd1, xStart1,yStart1, g.getColor(), 1));
                        count = 0;
                        }
                }
            }

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

            public void mouseExited(MouseEvent e) {
                System.out.println("退出了");
            }

            public void mousePressed(MouseEvent e) {
                System.out.println("按下了");
                xStart = e.getX();
                yStart = e.getY();
                 g.setColor(Color.BLACK);
                Stroke stroke = new BasicStroke(1);
                g.setStroke(stroke);
            }

            public void mouseReleased(MouseEvent e) {
                System.out.println("释放了");
                xEnd = e.getX();
                yEnd = e.getY();
                // 画
                if ("line".equals(pL.currentComman))          
                {g.drawLine(xStart, yStart, xEnd, yEnd);}
 else if ("polygon".equals(pL.currentComman)) {
                    if (count == 0) {
                        xStart1 = xStart;
                        yStart1 = yStart;
                        g.drawLine(xStart, yStart, xEnd, yEnd);                  xEnd1 = e.getX();
                        yEnd1 = e.getY();
                        count++;
                    }
                }
            }
        };
        MouseMotionListener mouseMotionLisener = new MouseMotionListener() {
            public void mouseDragged(MouseEvent e) {
                int x1 = e.getX();
                int y1 = e.getY();
    if ("pencil".equals(pL.currentComman)) 
    { g.drawLine(xStart, yStart, x1, y1);
      xStart = x1;yStart = y1;
      } else if ("airbrush".equals(pL.currentComman)) {for (int i = 0; i < 25; i++) {
int nextInt1 = random.nextInt(8) - 4;
                        int nextInt2 = random.nextInt(8) - 4;
                        g.drawLine(x1 + nextInt1, y1 + nextInt2, x1 + nextInt1,y1 + nextInt2);  }}if ("eraser".equals(pL.currentComman)) {
g.setColor(Color.WHITE);
BasicStroke stroke = new BasicStroke(10);
((Graphics2D) g).setStroke(stroke);
g.drawLine(xStart, yStart, x1, y1);
xStart = x1;
yStart = y1;
}
if ("brush".equals(pL.currentComman)) {
Stroke stroke = new BasicStroke(10);
g.setStroke(stroke);
g.drawLine(xStart, yStart, x1, y1);
xStart = x1;
yStart = y1;
}
            }

            public void mouseMoved(MouseEvent e) {
            }
        };
        this.addMouseMotionListener(mouseMotionLisener);
        this.addMouseListener(mouse);

    }
}

4.底部面板.pBottom

public class pBottom extends JPanel {
    public Color[] colors = { Color.BLACK, Color.BLUE, Color.GREEN,
            Color.ORANGE, Color.YELLOW, Color.LIGHT_GRAY, Color.PINK,
            Color.CYAN, Color.WHITE };
    pLeft pLeft;
    public Graphics2D g;

    public Color currentColor;

    public void setBottomPanel() {
        Dimension d = new Dimension(100, 50);
        this.setPreferredSize(d);
        // 创建按钮的点击事件
        ActionListener listener = new ActionListener() {

            public void actionPerformed(ActionEvent e) {
            //获取当前命令
                String command = e.getActionCommand();
                int i = Integer.valueOf(command);
                Color color = colors[i];
                g.setColor(color);
                currentColor = color;
            }
        };
        for (int i = 0; i < 9; i++) {
            JButton button = new JButton();
            button.setBackground(colors[i]);
            Dimension dd = new Dimension(25, 25);
            button.setPreferredSize(dd);
            button.addActionListener(listener);
            button.setActionCommand(i + "");
            // 添加
            this.add(button);

        }
    }

}

5.测试函数

public class Test {
    public static void main(String[] args) {
        Frame p = new Frame();
        p.setFrame();
    }
}

三、画板的重绘
1.泛型
1.1泛型,即“参数化类型”。顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。在泛型接口、泛型类和泛型方法的定义过程中,我们常见的如T、E、K、V等形式的参数常用于表示泛型形参。
1.2自定义泛型

public class MyList<T> {

    private int size = 0;
    private Object[] ages = new Object[size];

    public int getsize() {
        return size;
    }

    public T get(int i) {
        return (T) ages[i];
    }

    public boolean add(T age) {
        Object[] ages_new = new Object[size + 1];
        for (int i = 0; i < size; i++) {
            ages_new[i] = ages[i];
        }
        ages_new[size] = age;
        size++;
        ages = ages_new;
        return true;
    }

    public boolean delete(int index) {
        Object[] ages_new = new Object[size - 1];
        for (int i = 0; i < index; i++) {
            ages_new[i] = ages[i];
        }
        for (int i = index + 1; i < size; i++) {
            ages_new[i] = ages[i];
        }
        // 从0开始
        ages = ages_new;
        size--;
        return true;

    }

    public int check(int index) {
        return (int) ages[index];
    }

    public void update(int index, T age) {
        ages[index] = age;
    }

}

2.Shape抽象类
2.1抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。

2.2抽象类不能用来创建对象;

2.3如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。
2.4

public abstract class Shape {
    public int x1, y1, x2, y2;
    public Color currentcolor;
    public int stroke = 1;
    public Shape(int x1, int y1, int x2, int y2, Color currentcolor, int stroke) {
        super();
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.currentcolor = currentcolor;
        this.stroke = stroke;
    }
    public String toString() {
        return "Shape [x1=" + x1 + ", y1=" + y1 + ", x2=" + x2 + ", y2=" + y2
                + ", currentcolor=" + currentcolor + ", stroke=" + stroke + "]";
    }

    public abstract void paint(Graphics2D g);

}

2.5实例ShapeLine类(其他类似)

public class ShapeLine extends Shape {

    public ShapeLine(int x1, int y1, int x2, int y2, Color currentcolor,
            int stroke) {
        super(x1, y1, x2, y2, currentcolor, stroke);

    }

    public void paint(Graphics2D g) {
        g.setColor(currentcolor);
        g.setStroke(new BasicStroke(stroke));
        g.drawLine(x1, y1, x2, y2);

    }

}

2.6在中间面板将图形的绘制添加到列表,并重绘出来。

    //g.drawLine(xStart, yStart, xEnd, yEnd);
    myList.add(new ShapeLine(xStart, yStart, xEnd, yEnd, g
                            .getColor(), 1));

2.7其他图形和多边形也是相同情况,重绘多边形时每一步都用ShapeLine重绘出来。
2.8中间面板
将MyList列表中存储的图形全部重绘出来

public void paint(Graphics g) {

        super.paint(g);
        for (int i = 0; i < myList.getsize(); i++) {
            myList.get(i).paint((Graphics2D) g);
        }
    }

2.9每次添加到容器中,都用repaint();刷新

四、显示效果
1.如绘制直线时显示效果,则应在鼠标拖动时就画出来,为避免画一坨的情况,应该增加一个中间变量来记录。

Shape shape = null;

鼠标拖动时

if ("line".equals(pL.currentComman)) {
shape = new ShapeLine(xStart, yStart, x1, y1, g.getColor(),1);}

中间面板重绘时

if (shape != null) {
            shape.paint((Graphics2D) g);
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值