添加清除和撤消Jbutton到java绘图程序

时间:2014-04-16 20:48:35

标签: java graphics

我的项目遇到了麻烦。 使用我从前一个问题收到的代码,我已经复制了我的问题。 我需要添加一个清除和撤消JButton。你可以看到我添加了按钮hpwever我无法执行所需的操作。 我已经尝试将ActionListeners添加到创建按钮的类,然后尝试执行 itemsDrawn = new ArrayList<&gt ;; (清楚) itemsDrawn.remove(itemsDrawn.size() - 1)(用于撤消) 作为结果的动作,但程序锁定。

基本上我正在做这个/我把ActionListeners放在哪里?

任何帮助将不胜感激

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.LinearGradientPaint;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class MyPaint {

    static ArrayList<Drawable> itemsDrawn;
    static JButton Clear,Undo;

    public static void main(String[] args) {
        new MyPaint();
    }

    public MyPaint() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Java 2D Drawing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());

                DrawablePane dp = new DrawablePane();
                ControlPane cp = new ControlPane(dp);

                frame.add(dp);
                frame.add(cp, BorderLayout.NORTH);

                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class State {

        private final Color foreground;
        private final Color background;
        private final boolean gradient;
        private final boolean filled;
        private final boolean dashed;
        private int LineWidth, DashLength;

        public State(Color foreground, Color background, boolean gradient, boolean filled, boolean dashed,int LineWidth, int DashLength) {
            this.foreground = foreground;
            this.background = background;
            this.gradient = gradient;
            this.filled = filled;
            this.dashed = dashed;
            this.LineWidth = LineWidth;
            this.DashLength = DashLength;

        }

        public Color getBackground() {
            return background;
        }

        public Color getForeground() {
            return foreground;
        }

        public boolean isGradient() {
            return gradient;
        }
        public boolean isFilled() {
            return filled;
        }
        public boolean isDashed(){
            return dashed;
        }
        public int getLineWidth(){
                return LineWidth;
        }
        public int getDashLength(){
            return DashLength;
        }

    }

    public class ControlPane extends JPanel {

        private JComboBox shapes;
        private JLabel foreground;
        private JLabel background;
        private JCheckBox gradient,Filled,dashed;
        private JTextField Dashlength,Linewidth;
        private JLabel Len,Wid;


        private DrawablePane drawablePane;

        public ControlPane(DrawablePane pane) {

            shapes = new JComboBox<>(new String[]{"Rectangle", "Oval","Line"});
            foreground = createColorLable(Color.BLACK);
            foreground.setToolTipText("Foreground");
            background = createColorLable(Color.WHITE);
            background.setToolTipText("Background");
            gradient = new JCheckBox("Gradient");
            Filled = new JCheckBox("Filled");
            dashed = new JCheckBox("Dashed");
            Dashlength = new JTextField("1");
            Linewidth = new JTextField("1");
            Len = new JLabel("Dash Length:");
            Wid = new JLabel("Line Width:");
            Clear = new JButton("Clear");
            Undo = new JButton("Undo");






            JPanel panel = new JPanel();
            panel.add(Clear);
            panel.add(Undo);
            panel.add(foreground);
            panel.add(background);
            panel.add(Filled);

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weightx = 1;

            add(shapes, gbc);
            add(panel, gbc);
            gbc.weighty = 1;
            gbc.anchor = GridBagConstraints.NORTH;
            add(gradient, gbc);
            add(dashed, gbc);
            add(Len);
            add(Linewidth);
            add(Wid);
            add(Dashlength);



            setBorder(new CompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(12, 12, 12, 12)));

            this.drawablePane = pane;
            MouseHandler mouseHandler = new MouseHandler();
            drawablePane.addMouseListener(mouseHandler);
            drawablePane.addMouseMotionListener(mouseHandler);


        }



                public int getDash(){
                String Length = Dashlength.getText();
                int Dash = Integer.parseInt(Length);
                return Dash;
            }
                public int getLine(){
                String LWidth = Linewidth.getText();
                int Line = Integer.parseInt(LWidth);
                return Line;
                }

        protected Drawable createDrawable() {

            Drawable drawable = null;
            State state = new State(foreground.getBackground(), background.getBackground(), gradient.isSelected(), Filled.isSelected(), dashed.isSelected(),getLine(), getDash());
            String selected = (String) shapes.getSelectedItem();
            if ("rectangle".equalsIgnoreCase(selected)) {
                drawable = new Square(state);
            } else if ("oval".equalsIgnoreCase(selected)) {
                drawable = new Circle(state);
            }
            else if ("Line".equalsIgnoreCase(selected)){
                drawable = new Line(state);
            }

            return drawable;

        }

        protected JLabel createColorLable(Color base) {
            final JLabel label = new JLabel();
            label.setBackground(base);
            label.setBorder(new LineBorder(Color.BLACK));
            label.setPreferredSize(new Dimension(25, 25));
            label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
            label.setOpaque(true);
            label.addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    Color color = JColorChooser.showDialog(label, "Color", label.getBackground());
                    if (color != null) {
                        label.setBackground(color);
                    }
                }
            });
            return label;
        }

        public class MouseHandler extends MouseAdapter {

            private Drawable drawable;
            private Point clickPoint;

            @Override
            public void mousePressed(MouseEvent e) {
                drawable = createDrawable();
                drawable.setLocation(e.getPoint());
                drawablePane.addDrawable(drawable);
                clickPoint = e.getPoint();
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                Point drag = e.getPoint();
                Point start = clickPoint;

                int maxX = Math.max(drag.x, start.x);
                int maxY = Math.max(drag.y, start.y);
                int minX = Math.min(drag.x, start.x);
                int minY = Math.min(drag.y, start.y);

                int width = maxX - minX;
                int height = maxY - minY;

                drawable.setLocation(new Point(minX, minY));
                drawable.setSize(new Dimension(width, height));

                drawablePane.repaint();
            }

        }

    }

    public interface Drawable {

        public void paint(JComponent parent, Graphics2D g2d);

        public void setLocation(Point location);

        public void setSize(Dimension size);

        public State getState();

        public Rectangle getBounds();

    }

    public abstract class AbstractDrawable implements Drawable {

        private Rectangle bounds;
        private State state;

        public AbstractDrawable(State state) {
            bounds = new Rectangle();
            this.state = state;
        }

        @Override
        public State getState() {
            return state;
        }

        public abstract Shape getShape();

        @Override
        public void setLocation(Point location) {
            bounds.setLocation(location);
        }

        @Override
        public void setSize(Dimension size) {
            bounds.setSize(size);
        }

        @Override
        public Rectangle getBounds() {
            return bounds;
        }

        @Override
        public void paint(JComponent parent, Graphics2D g2d) {

            Shape shape = getShape();
            State state = getState();
            Rectangle bounds = getBounds();
            final float dash1[] = {state.LineWidth};
            final BasicStroke dashed =
            new BasicStroke(state.DashLength,
                        BasicStroke.CAP_BUTT,
                        BasicStroke.JOIN_MITER,
                        10.0f, dash1, 0.0f);

            if (bounds.width > 0 && bounds.height > 0) {
                 if (state.isGradient()){
                     if (state.isDashed()){
                     Point2D startPoint = new Point2D.Double(bounds.x, bounds.y);
            Point2D endPoint = new Point2D.Double(bounds.x + bounds.width, bounds.y + bounds.height);
            LinearGradientPaint gp = new LinearGradientPaint(
                            startPoint,
                            endPoint,
                            new float[]{0f, 1f},
                            new Color[]{state.getForeground(), state.getBackground()});    
                    g2d.setPaint(gp);
                    g2d.setStroke(dashed);
                    g2d.draw(shape);
                }
                     else{
            Point2D startPoint = new Point2D.Double(bounds.x, bounds.y);
            Point2D endPoint = new Point2D.Double(bounds.x + bounds.width, bounds.y + bounds.height);
            LinearGradientPaint gp = new LinearGradientPaint(
                            startPoint,
                            endPoint,
                            new float[]{0f, 1f},
                            new Color[]{state.getForeground(), state.getBackground()});
                     g2d.setPaint(gp);
                     g2d.fill(shape);
                     }
                 }

            else if (state.isFilled()){
                if (bounds.width > 0 && bounds.height > 0) {

                g2d.setPaint(state.getForeground());
                g2d.fill(shape);


                }
                }
            else if(state.isDashed()){
                g2d.setStroke(dashed);
                g2d.setPaint(state.getForeground());
                g2d.draw(shape);

            } 
            else{
                 BasicStroke stroke = new BasicStroke();
                 g2d.setStroke(stroke);
                g2d.setPaint(state.getForeground());
                g2d.draw(shape);
            }
        }
        }
        }


    public class Square extends AbstractDrawable {

        public Square(State state) {
            super(state);
        }

        @Override
        public Shape getShape() {
            return getBounds();
        }

    }

    public class Circle extends AbstractDrawable {

        public Circle(State state) {
            super(state);
        }

        @Override
        public Shape getShape() {
            Rectangle bounds = getBounds();
            return new Ellipse2D.Float(bounds.x, bounds.y, bounds.width, bounds.height);
        }

    }

    public class Line extends AbstractDrawable {

        public Line(State state){
            super(state);
        }
        @Override
        public Shape getShape() {
           Rectangle bounds = getBounds();
           return new Line2D.Float(bounds.x, bounds.y,bounds.width, bounds.height);

        }
    }

    public class DrawablePane extends JPanel {

        List<Drawable> itemsDrawn;

        public DrawablePane() {
            itemsDrawn =  new ArrayList<>();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            for (Drawable d : itemsDrawn) {
                d.paint(this, g2d);
            }
            g2d.dispose();
        }

        public void addDrawable(Drawable drawable) {

            itemsDrawn.add(drawable);
            repaint();

        }



               }
           }

这是带有已实现的撤消和清除按钮的ControlPane类

public ControlPane(DrawablePane pane) {

            shapes = new JComboBox<>(new String[]{"Rectangle", "Oval","Line"});
            foreground = createColorLable(Color.BLACK);
            foreground.setToolTipText("Foreground");
            background = createColorLable(Color.WHITE);
            background.setToolTipText("Background");
            gradient = new JCheckBox("Gradient");
            Filled = new JCheckBox("Filled");
            dashed = new JCheckBox("Dashed");
            Dashlength = new JTextField("1");
            Linewidth = new JTextField("1");
            Len = new JLabel("Dash Length:");
            Wid = new JLabel("Line Width:");
            Clear = new JButton("Clear");
            Undo = new JButton("Undo");






            JPanel panel = new JPanel();
            panel.add(Clear);
            panel.add(Undo);
            panel.add(foreground);
            panel.add(background);
            panel.add(Filled);

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weightx = 1;

            add(shapes, gbc);
            add(panel, gbc);
            gbc.weighty = 1;
            gbc.anchor = GridBagConstraints.NORTH;
            add(gradient, gbc);
            add(dashed, gbc);
            add(Len);
            add(Linewidth);
            add(Wid);
            add(Dashlength);



            setBorder(new CompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(12, 12, 12, 12)));

            this.drawablePane = pane;
            MouseHandler mouseHandler = new MouseHandler();
            drawablePane.addMouseListener(mouseHandler);
            drawablePane.addMouseMotionListener(mouseHandler);

            Clear.addActionListener(new ActionListener() {

           @Override
           public void actionPerformed(ActionEvent arg0) {
               // TODO Auto-generated method stub
               itemsDrawn = new ArrayList<>();
               (Not sure what to use here).repaint();
           }
       });
            undo.addActionListener(new ActionListener() {

           @Override
           public void actionPerformed(ActionEvent arg0) {
               // TODO Auto-generated method stub
               if (itemsDrawn.size() != 0) {
                   itemsDrawn.remove(itemsDrawn.size() - 1);
                   (Not sure what to put here).repaint();
               }
           }
       });

        }

这样的事情(DrawablePane中的clear和undo方法)

Clear.addActionListner(new ActionListener() {
                @Override
                public void actionPreformed(ActionEvent arg0){
                    Clear();
                }
            });

          Undo.addActionListener(new ActionListener() {

           @Override
           public void actionPerformed(ActionEvent arg0) {
               // TODO Auto-generated method stub
               Undo();
           }
       });
public class DrawablePane extends JPanel {

        List<Drawable> itemsDrawn;

        public DrawablePane() {
            itemsDrawn =  new ArrayList<>();

        }
        public void undo(){
            if (itemsDrawn.size() != 0) {
                   itemsDrawn.remove(itemsDrawn.size() - 1);
                   repaint();
        }
        }
        public void Clear(){
             itemsDrawn = new ArrayList<>();
               repaint();

        }
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            for (Drawable d : itemsDrawn) {
                d.paint(this, g2d);
            }
            g2d.dispose();
        }

        public void addDrawable(Drawable drawable) {

            itemsDrawn.add(drawable);
            repaint();

        }



               }
           }

我收到一条错误,说明在DrawablePane

中找不到清除和撤消

2 个答案:

答案 0 :(得分:4)

主要问题是itemsDrawn使用DrawablePane而非ControlPane,因此尝试从ControlPane更改DrawablePaneDrawablePane无效

相反,您应该向undo调用clearActionListener添加两个方法,这些方法可以通过ControlPane中的undo来调用

更新了示例

首先,将clearDrawablePane方法添加到public class DrawablePane extends JPanel { List<Drawable> itemsDrawn; public DrawablePane() { itemsDrawn = new ArrayList<>(); } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); for (Drawable d : itemsDrawn) { d.paint(this, g2d); } g2d.dispose(); } public void addDrawable(Drawable drawable) { itemsDrawn.add(drawable); repaint(); } public void undo() { if (!itemsDrawn.isEmpty()) { int size = itemsDrawn.size() - 1; itemsDrawn.remove(size); repaint(); } } public void clear() { itemsDrawn.clear(); repaint(); } } ...

ActionListener

其次,从适当的clear.addActionListner(new ActionListener() { @Override public void actionPreformed(ActionEvent arg0) { drawablePane.clear(); } }); undo.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { drawablePane.undo(); } }); ...

调用方法
ControlPane

显然,这些会在您的{{1}}

中创建

答案 1 :(得分:0)

在BufferedImage上绘制图形并将其显示在DrawPane的paintComponent方法中。如果要清除它,只需用背景颜色覆盖BufferedImage或创建一个新的BufferedImage并将其填充到图像变量中。

public class DrawablePane extends JPanel {
    private BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_ARGB);

    List<Drawable> itemsDrawn;

    public DrawablePane() {
        itemsDrawn =  new ArrayList<>();
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(200, 200);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (img != null) {
           g.drawImage(img, 0, 0, this);
        }
     }

     public void addDrawable(Drawable drawable) {
        itemsDrawn.add(drawable);
        repaint();
     }

     public void clear() {
       img = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_ARGB);
       repaint();
     }

}

在您为此课程提供的公共方法中,您的所有绘图 上的BufferedImage。