/************************************************************************************************************/
public class DrawMain extends JFrame{
    //Main Method
    public static void main(String[] args) {
        J_ButtonPanel btPanel = new J_ButtonPanel();
        J_PaintingGround ptGround = new J_PaintingGround(btPanel);
        DrawMain app = new DrawMain(btPanel, ptGround);        app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        app.setSize(600, 600);
        app.setVisible(true);
        
        //设置显示外观
        try{
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    //构造函数
    public DrawMain(J_ButtonPanel btPanel, J_PaintingGround ptGround) {
        //设置容器及容器的整体布局
        super("画板例程");
        Container cp = getContentPane();        cp.add(btPanel.getPanel(),BorderLayout.WEST);
        cp.add(ptGround, BorderLayout.CENTER);
    }
}
/************************************************************************************************************/
public class J_ButtonPanel extends JPanel implements ActionListener{
    private int optype = 0;  //操作类型变量,默认值为0
    private JPanel buttonPanel = new JPanel();  //按钮版
    public JPanel getPanel(){return buttonPanel;}  //获取按钮版
    public int getOptype(){return optype;}  //获取操作类型
    J_ButtonPanel() {
        //新建按钮
        btFree = new JButton("随手画");
        btLine = new JButton("直线");
        btRectangle = new JButton("矩形");
        btRound = new JButton("圆");
        btEllipse = new JButton("椭圆");
        btFill = new JButton("填充");
        btSave = new JButton("保存");
        btOpen = new JButton("打开");
        //添加按钮
        buttonPanel.add(btOpen);
        buttonPanel.add(btSave);
        buttonPanel.add(btFree);
        buttonPanel.add(btLine);
        buttonPanel.add(btRectangle);
        buttonPanel.add(btRound);
        buttonPanel.add(btEllipse);
        buttonPanel.add(btFill);
    }    public void actionPerformed(ActionEvent event) {  //鼠标监听器
        Object source = event.getSource();  //获取动作,确定操作类型
        if(source == btFree) optype = 0;
        if(source == btLine) optype = 1;
        if(source == btRectangle) optype = 2;
        if(source == btRound) optype = 3;
        if(source == btEllipse) optype = 4;
        if(source == btFill) optype = 5;
        if(source == btOpen) optype = 6;
        if(source == btSave) optype = 7;
    }    private JButton btFree;
    private JButton btLine;
    private JButton btRectangle;
    private JButton btRound;
    private JButton btEllipse;
    private JButton btFill;
    private JButton btSave;
    private JButton btOpen;
}
/************************************************************************************************************/
public class J_PaintingGround extends JPanel{
    public Vector<Vector<Integer>> m_vectorSet = new Vector<Vector<Integer>>();  //设置变量存放笔画
    
    public J_PaintingGround(J_ButtonPanel buttonpanel) {  //构造函数
        btPanel = buttonpanel;  //按钮版
        
        if(btPanel.getOptype() == 0){
            addMouseListener(new MouseAdapter()
            {
                public void mousePressed(MouseEvent event)
                {
                    Vector<Integer> v = new Vector<Integer>();
                    v.add(btPanel.getOptype());
                    v.add(event.getX());
                    v.add(event.getY());
                    m_vectorSet.add(v);
                }
            }
            );
            addMouseMotionListener(new MouseMotionListener()
            {
                public void mouseMoved(MouseEvent event){}                public void mouseDragged(MouseEvent event)
                {
                    int n = m_vectorSet.size()-1;
                    Vector<Integer> v = new Vector<Integer>();
                    v = m_vectorSet.get(n);
                    v.add(event.getX());
                    v.add(event.getY());
                    repaint();
                }
            }
            );
        }
        if(btPanel.getOptype() >=1 && btPanel.getOptype() <= 4){
            addMouseListener(new MouseAdapter()
            {
                Vector<Integer> v = new Vector<Integer>();
                public void mousePressed(MouseEvent event)
                {
                    v.add(btPanel.getOptype());
                    v.add(event.getX());
                    v.add(event.getY());
                }
                public void mouseReleased(MouseEvent event)
                {
                    v.add(event.getX());
                    v.add(event.getY());
                    m_vectorSet.add(v);
                    repaint();
                }
            }
            );
        }
        if(btPanel.getOptype() == 5){}
        if(btPanel.getOptype() == 7){
            try
                {
                FileOutputStream f = new FileOutputStream("绘画作品.txt");
                DataOutputStream fout = new DataOutputStream(f);
                int i,j,m;
                int n = m_vectorSet.size();
                Vector<Integer> vv = new Vector<Integer>();
                for(i=0;i<n;i++)
                {
                    vv = m_vectorSet.get(i);
                    m = vv.size()-1;
                    for(j=0; j<m; j++)
                    {
                        fout.writeInt(vv.get(j).intValue());
                    }
                    fout.writeInt('\n');
                }
                fout.close();
                repaint();
            }
            catch(Exception e)
            {
                System.err.println("发生异常:" + e);
                e.printStackTrace();
            }
        }        if(btPanel.getOptype() == 6){
            try
            {
                int i,j,k=0;
                RandomAccessFile f = new RandomAccessFile("绘画作品.txt","r");
                Vector<Vector> v = new Vector<Vector>();
                Vector<Integer> vv = new Vector<Integer>();                for(i=0;i<f.length()/4-1;i++)
                {
                    if(f.readInt() == '\n'){
                        v.add(vv);
                        vv = new Vector<Integer>();
                    }
                    else {
                        f.seek(i*4);
                        vv.add(f.readInt());
                    }
                }
                this.repaint();
            }
            catch(Exception e)
            {
                System.err.println("发生异常:" + e);
                e.printStackTrace();
            }
        }
    }    protected void paintComponent(Graphics g)
    {
        g.setColor(Color.YELLOW);
        g.clearRect(0, 0, getWidth(), getHeight());
        Vector<Integer> v = new Vector<Integer>();
        Point s, t;
        int i, j, m;
        int n = m_vectorSet.size();
        for(i=0,j=0; i<n; i++)
        {
            v = m_vectorSet.get(i);
            Integer a = v.get(0);
            v.remove(0);
            m = v.size()-1;
            switch(a.intValue())
            {
                case FREE:
                    while(j+3<m){
                        s = new Point(v.get(j).intValue(),v.get(j+1).intValue());
                        t = new Point(v.get(j+2).intValue(),v.get(j+3).intValue());
                        g.drawLine(s.x, s.y, t.x, t.y);
                        j=j+2;
                    }
                    break;
                case LINE:
                    s = new Point(v.get(j++).intValue(),v.get(j++).intValue());
                    t = new Point(v.get(j++).intValue(),v.get(j++).intValue());
                    g.drawLine(s.x, s.y, t.x, t.y);
                    break;
                case ROUND:
                    s = new Point(v.get(j++).intValue(),v.get(j++).intValue());
                    t = new Point(v.get(j++).intValue(),v.get(j++).intValue());
                    g.drawRoundRect(s.x, s.y, t.x-s.x, t.x-s.x, t.x-s.x, t.x-s.x);
                    break;
                case RECTANGLE:
                    s = new Point(v.get(j++).intValue(),v.get(j++).intValue());
                    t = new Point(v.get(j++).intValue(),v.get(j++).intValue());
                    g.drawRect(s.x, s.y, t.x-s.x, t.y-s.y);
                    break;
                case ELLIPSE:
                    s = new Point(v.get(j++).intValue(),v.get(j++).intValue());
                    t = new Point(v.get(j++).intValue(),v.get(j++).intValue());
                    g.drawOval(s.x, s.y, t.x-s.x, t.y-s.y);
                    break;
                default:break;
            }
        }
    }    public Dimension getPreferredSize()
    {
        return new Dimension(600,600);
    }
    
    private int optype;
    private J_ButtonPanel btPanel = new J_ButtonPanel();    public static final int FREE = 0;
    public static final int LINE = 1;
    public static final int RECTANGLE = 2;
    public static final int ROUND = 3;
    public static final int ELLIPSE = 4;
    public static final int FILL = 5;
    public static final int OPEN = 6;
    public static final int SAVE = 7;
}
/************************************************************************************************************/
运行通过,但是无法在画图版上画图,按钮没反应。

解决方案 »

  1.   

    你程序的问题主要出在paintComponent中的v.remove(0)。每次拖动,都会导致添加元素及重绘。然而,你在第一次绘制的时候,就把作为区分标记的v的第0个元素去掉了,下次重绘的时候,第一个就不是标记,而是坐标x,显然是出问题的。还有一些小问题,比如说for(i=0,j=0; i<n; i++),j在开始时赋0,那么在你画的第二笔及其以后,都会出问题的。下面是我改后的程序,将你的存取文件部分删掉了,呵呵。如果还有疑问的话,可以加我QQ:815611030,我们讨论讨论。加时注明:Java讨论import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Container;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Point;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseMotionListener;
    import java.io.DataOutputStream;
    import java.io.FileOutputStream;
    import java.io.RandomAccessFile;
    import java.util.Vector;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;public class DrawMain extends JFrame {
        //Main Method    public static void main(String[] args) {
            //设置显示外观
            //如果选生成配置组件,再改变默认外观,之前生成的组件,是不会有变化的
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e) {
                e.printStackTrace();
            }
            J_ButtonPanel btPanel = new J_ButtonPanel();
            J_PaintingGround ptGround = new J_PaintingGround(btPanel);
            DrawMain app = new DrawMain(btPanel, ptGround);        app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            app.setSize(600, 600);
            //让窗口显示在屏幕的正中间
            app.setLocationRelativeTo(null);
            app.setVisible(true);    }    //构造函数
        public DrawMain(J_ButtonPanel btPanel, J_PaintingGround ptGround) {
            //设置容器及容器的整体布局
            super("画板例程");
            Container cp = getContentPane();
            cp.add(btPanel.getPanel(), BorderLayout.NORTH);
            cp.add(ptGround, BorderLayout.CENTER);
        }
    }/************************************************************************************************************/
    class J_ButtonPanel implements ActionListener {
        //本来你的J_ButtonPanel是继承JPanel的,可是你的J_ButtonPane中有一个buttonPanel元素
        //也就是说J_ButtonPanel本身不具备JPanel的特性,没必要继续JPanel
        
        private int optype = 0; //操作类型变量,默认值为0
        private JPanel buttonPanel = new JPanel(); //按钮版    public JPanel getPanel() {
            return buttonPanel;
        } //获取按钮版    public int getOptype() {
            return optype;
        } //获取操作类型    J_ButtonPanel() {
            //新建按钮
            btFree = new JButton("随手画");
            btLine = new JButton("直线");
            btRectangle = new JButton("矩形");
            btRound = new JButton("圆");
            btEllipse = new JButton("椭圆");
            btFill = new JButton("填充");
            btSave = new JButton("保存");
            btOpen = new JButton("打开");
            //添加按钮
            buttonPanel.add(btOpen);
            buttonPanel.add(btSave);
            buttonPanel.add(btFree);
            buttonPanel.add(btLine);
            buttonPanel.add(btRectangle);
            buttonPanel.add(btRound);
            buttonPanel.add(btEllipse);
            buttonPanel.add(btFill);
            //
            btFree.addActionListener(this);
            btLine.addActionListener(this);
            btRectangle.addActionListener(this);
            btRound.addActionListener(this);
            btEllipse.addActionListener(this);
            btFill.addActionListener(this);
            btSave.addActionListener(this);
            btOpen.addActionListener(this);
        }    public void actionPerformed(ActionEvent event) { //鼠标监听器
            Object source = event.getSource(); //获取动作,确定操作类型
            if (source == btFree) {
                optype = 0;
            }
            if (source == btLine) {
                optype = 1;
            }
            if (source == btRectangle) {
                optype = 2;
            }
            if (source == btRound) {
                optype = 3;
            }
            if (source == btEllipse) {
                optype = 4;
            }
            if (source == btFill) {
                optype = 5;
            }
            if (source == btOpen) {
                optype = 6;
            }
            if (source == btSave) {
                optype = 7;
            }
        }
        private JButton btFree;
        private JButton btLine;
        private JButton btRectangle;
        private JButton btRound;
        private JButton btEllipse;
        private JButton btFill;
        private JButton btSave;
        private JButton btOpen;
    }/************************************************************************************************************/
    class J_PaintingGround extends JPanel {    public Vector<Vector<Integer>> m_vectorSet = new Vector<Vector<Integer>>(); //设置变量存放笔画    public J_PaintingGround(J_ButtonPanel buttonpanel) { //构造函数
            btPanel = buttonpanel; //按钮版
            addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent event) {
                    Vector<Integer> v = new Vector<Integer>();
                    v.add(btPanel.getOptype());
                    v.add(event.getX());
                    v.add(event.getY());
                    m_vectorSet.add(v);
                }
            });
            addMouseMotionListener(new MouseMotionListener() {
                public void mouseMoved(MouseEvent event) {}
                public void mouseDragged(MouseEvent event) {
                    int n = m_vectorSet.size() - 1;
                    Vector<Integer> v;
                    v = m_vectorSet.get(n);
                    if(btPanel.getOptype()==0||v.size()==3){
                        v.add(event.getX());
                        v.add(event.getY());
                    }
                    else{
                        int j=v.size()-2;
                        v.setElementAt(event.getX(), j);
                        v.setElementAt(event.getY(), j+1);
                    }
                    repaint();
                }
            });
        }    protected void paintComponent(Graphics g) {
            g.setColor(Color.YELLOW);
            g.clearRect(0, 0, getWidth(), getHeight());
            Vector<Integer> v;
            Point s, t;
            int i, j, m;
            int n = m_vectorSet.size();
            for (i = 0; i < n; i++) {
                v = m_vectorSet.get(i);
                Integer a = v.get(0);
    //            v.remove(0);
                m = v.size() - 1;
                j = 1;
                switch (a.intValue()) {
                    case FREE:
                        while (j + 3 <= m) {
                            s = new Point(v.get(j).intValue(), v.get(j + 1).intValue());
                            t = new Point(v.get(j + 2).intValue(), v.get(j + 3).intValue());
                            g.drawLine(s.x, s.y, t.x, t.y);
                            j = j + 2;
                        }
                        break;
                    case LINE:
                        s = new Point(v.get(1).intValue(), v.get(2).intValue());
                        t = new Point(v.get(m-1).intValue(), v.get(m).intValue());
                        g.drawLine(s.x, s.y, t.x, t.y);
                        break;
                    case ROUND:
                        s = new Point(v.get(1).intValue(), v.get(2).intValue());
                        t = new Point(v.get(m-1).intValue(), v.get(m).intValue());
                        int width=t.x-s.x;
                        int height=t.y-s.y;
                        int r=width<height?width:height;
                        g.drawOval(s.x, s.y, r, r);
                        break;
                    case RECTANGLE:
                        s = new Point(v.get(1).intValue(), v.get(2).intValue());
                        t = new Point(v.get(m-1).intValue(), v.get(m).intValue());
                        g.drawRect(s.x, s.y, t.x - s.x, t.y - s.y);
                        break;
                    case ELLIPSE:
                        s = new Point(v.get(1).intValue(), v.get(2).intValue());
                        t = new Point(v.get(m-1).intValue(), v.get(m).intValue());
                        g.drawOval(s.x, s.y, t.x-s.x, t.y-s.y);
                        break;
                    default:
                        break;
                }
            }
        }    public Dimension getPreferredSize() {
            return new Dimension(600, 600);
        }
        private int optype;
        private J_ButtonPanel btPanel;
        public static final int FREE = 0;
        public static final int LINE = 1;
        public static final int RECTANGLE = 2;
        public static final int ROUND = 3;
        public static final int ELLIPSE = 4;
        public static final int FILL = 5;
        public static final int OPEN = 6;
        public static final int SAVE = 7;
    }