简体   繁体   中英

Saving Gradient colored object after drawing it on a jframe (JAVA)

ok so here's my code. package mypanal;

/** * * @author Morgan */

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import static mypanal.MyPanel.GradientBox;

public class MyPanel extends JPanel implements MouseListener,
       MouseMotionListener {

   static ArrayList<String> itemsDrawn;
   static String shape, color, color1;
   static JCheckBox fillBox, GradientBox;

   public static void main(String[] args) {
       JFrame frame = new JFrame("Java 2D Drawing");

       frame.setSize(400, 400);
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       BorderLayout borderLayout = new BorderLayout();
       frame.setLayout(borderLayout);


       final JPanel panel = new JPanel();

       panel.setLayout(new GridLayout(0, 4, 0, 0));

       JButton clear = new JButton("Clear");
       panel.add(clear);
       JButton undo = new JButton("Undo");
       panel.add(undo);
       String[] itemTypes = { "Oval", "Rectangle", "Line" };
       JComboBox<String> shapeChooser = new JComboBox<>(itemTypes);
       panel.add(shapeChooser);
       shape = "Oval";
       fillBox = new JCheckBox("Fill");
       panel.add(fillBox);
       String[] colors = { "Red", "Green", "Blue", "Black" };
       String[] colors1= { "Red", "Green", "Blue", "Black" };
       JComboBox<String> colorChooser = new JComboBox<>(colors);
       JComboBox<String> colorChooser1 = new JComboBox<>(colors1);
       panel.add(colorChooser);
       panel.add(colorChooser1); 
       color = "Red";
       color1 = "Blue";
       GradientBox = new JCheckBox("Use Gradient");
       panel.add(GradientBox);


       frame.add(panel, BorderLayout.PAGE_START);

       final MyPanel myPanel = new MyPanel();
       frame.add(myPanel, BorderLayout.CENTER);

       shapeChooser.addActionListener(new ActionListener() {

           @Override
           public void actionPerformed(ActionEvent e) {
               // TODO Auto-generated method stub
               JComboBox<String> cb = (JComboBox<String>) e.getSource();
               shape = (String) cb.getSelectedItem();
           }
       });

       colorChooser.addActionListener(new ActionListener() {

           @Override
           public void actionPerformed(ActionEvent e) {
               // TODO Auto-generated method stub
               JComboBox<String> cb = (JComboBox<String>) e.getSource();
               color = (String) cb.getSelectedItem();
           }
       });
       colorChooser1.addActionListener(new ActionListener() {

           @Override
           public void actionPerformed(ActionEvent e) {
               // TODO Auto-generated method stub
               JComboBox<String> cb = (JComboBox<String>) e.getSource();
               color1 = (String) cb.getSelectedItem();
           }
       });

       clear.addActionListener(new ActionListener() {

           @Override
           public void actionPerformed(ActionEvent arg0) {
               // TODO Auto-generated method stub
               itemsDrawn = new ArrayList<>();
               myPanel.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);
                   myPanel.repaint();
               }
           }
       });

       frame.setVisible(true);
   }



   Point start, end;

   public MyPanel() {
       start = end = null;
       addMouseListener(this);
       addMouseMotionListener(this);
       itemsDrawn = new ArrayList<>();
   }



   @Override
   public void paint(Graphics g) {
       // TODO Auto-generated method stub
       super.paint(g);
       int counter;
       String[] temp;
       Graphics2D g2d = (Graphics2D)g;
       GradientPaint gp;
       Color color2 = null;


       for (counter = 0; counter < itemsDrawn.size(); counter++) {
           temp = itemsDrawn.get(counter).split(" ");
           if (temp[1].equals("Red")) {
               g.setColor(Color.RED);
           } else if (temp[1].equals("Green")) {
               g.setColor(Color.GREEN);
           } else if (temp[1].equals("Blue")) {
               g.setColor(Color.BLUE);
           } else if (temp[1].equals("Black")) {
               g.setColor(Color.BLACK);
           }

           if (temp[0].equals("Rectangle")) {
               if (Boolean.parseBoolean(temp[6])) {
                   g.fillRect(
                           Integer.parseInt(temp[2]) > Integer
                                   .parseInt(temp[4]) ? Integer
                                   .parseInt(temp[4]) : Integer
                                   .parseInt(temp[2]),
                           Integer.parseInt(temp[3]) > Integer
                                   .parseInt(temp[5]) ? Integer
                                   .parseInt(temp[5]) : Integer
                                   .parseInt(temp[3]), Math.abs(Integer
                                   .parseInt(temp[4])
                                   - Integer.parseInt(temp[2])), Math
                                   .abs(Integer.parseInt(temp[5])
                                           - Integer.parseInt(temp[3])));
               } else {
                   g.drawRect(
                           Integer.parseInt(temp[2]) > Integer
                                   .parseInt(temp[4]) ? Integer
                                   .parseInt(temp[4]) : Integer
                                   .parseInt(temp[2]),
                           Integer.parseInt(temp[3]) > Integer
                                   .parseInt(temp[5]) ? Integer
                                   .parseInt(temp[5]) : Integer
                                   .parseInt(temp[3]), Math.abs(Integer
                                   .parseInt(temp[4])
                                   - Integer.parseInt(temp[2])), Math
                                   .abs(Integer.parseInt(temp[5])
                                           - Integer.parseInt(temp[3])));
               }
           } else if (temp[0].equals("Oval")) {
               if (Boolean.parseBoolean(temp[6])) {
                   g.fillOval(
                           Integer.parseInt(temp[2]) > Integer
                                   .parseInt(temp[4]) ? Integer
                                   .parseInt(temp[4]) : Integer
                                   .parseInt(temp[2]),
                           Integer.parseInt(temp[3]) > Integer
                                   .parseInt(temp[5]) ? Integer
                                   .parseInt(temp[5]) : Integer
                                   .parseInt(temp[3]), Math.abs(Integer
                                   .parseInt(temp[4])
                                   - Integer.parseInt(temp[2])), Math
                                   .abs(Integer.parseInt(temp[5])
                                           - Integer.parseInt(temp[3])));
               } else {
                   g.drawOval(
                           Integer.parseInt(temp[2]) > Integer
                                   .parseInt(temp[4]) ? Integer
                                   .parseInt(temp[4]) : Integer
                                   .parseInt(temp[2]),
                           Integer.parseInt(temp[3]) > Integer
                                   .parseInt(temp[5]) ? Integer
                                   .parseInt(temp[5]) : Integer
                                   .parseInt(temp[3]), Math.abs(Integer
                                   .parseInt(temp[4])
                                   - Integer.parseInt(temp[2])), Math
                                   .abs(Integer.parseInt(temp[5])
                                           - Integer.parseInt(temp[3])));
               }

           } else if (temp[0].equals("Line")) {
               g.drawLine(Integer.parseInt(temp[2]),
                       Integer.parseInt(temp[3]), Integer.parseInt(temp[4]),
                       Integer.parseInt(temp[5]));
           }
       }


       if (start != null && end != null) {
           if (color.equals("Red")) {
               g.setColor(Color.RED);
           } else if (color.equals("Green")) {
               g.setColor(Color.GREEN);
           } else if (color.equals("Blue")) {
               g.setColor(Color.BLUE);
           } else if (color.equals("Black")) {
              g.setColor(Color.black);
           }
          if (start != null && end != null) {
           if (color1.equals("Red")) {
               color2 = Color.RED;
           } else if (color1.equals("Green")) {
               color2 = Color.GREEN;
           } else if (color1.equals("Blue")) {
               color2 = Color.BLUE;
           } else if (color1.equals("Black")) {
              color2 = Color.black;
           }


           if (shape.equals("Oval")) {
               if (fillBox.isSelected()) {
                   if(GradientBox.isSelected()){
                        gp = new GradientPaint(start.x > end.x ? end.x : start.x,
                           start.y > end.y ? end.y : start.y,g.getColor(),
                           Math.abs(end.x - start.x),
                           Math.abs(end.y - start.y),color2);
                   g2d.setPaint(gp);
                   g2d.fillOval(start.x > end.x ? end.x : start.x,
                           start.y > end.y ? end.y : start.y,
                           Math.abs(end.x - start.x),
                           Math.abs(end.y - start.y));
                   }
                   else{
                       g.fillOval(start.x > end.x ? end.x : start.x,
                           start.y > end.y ? end.y : start.y,
                           Math.abs(end.x - start.x),
                           Math.abs(end.y - start.y));
                   }
               } else {
                   g.drawOval(start.x > end.x ? end.x : start.x,
                           start.y > end.y ? end.y : start.y,
                           Math.abs(end.x - start.x),
                           Math.abs(end.y - start.y));
               }
           } else if (shape.equals("Rectangle")) {
               if (fillBox.isSelected()) {
                   if(GradientBox.isSelected()){
                        gp = new GradientPaint(start.x > end.x ? end.x : start.x,
                           start.y > end.y ? end.y : start.y,g.getColor(),
                           Math.abs(end.x - start.x),
                           Math.abs(end.y - start.y),color2);
                   g2d.setPaint(gp);
                   g2d.fillRect(start.x > end.x ? end.x : start.x,
                           start.y > end.y ? end.y : start.y,
                           Math.abs(end.x - start.x),
                           Math.abs(end.y - start.y));
                   }
                   else{
                   g.fillRect(start.x > end.x ? end.x : start.x,
                           start.y > end.y ? end.y : start.y,
                           Math.abs(end.x - start.x),
                           Math.abs(end.y - start.y));
                   }
               } else {
                   g.drawRect(start.x > end.x ? end.x : start.x,
                           start.y > end.y ? end.y : start.y,
                           Math.abs(end.x - start.x),
                           Math.abs(end.y - start.y));
               }
           } else if (shape.equals("Line")) {
               g.drawLine(start.x, start.y, end.x, end.y);
           }
       }
       }
   }

   @Override
   public void mouseDragged(MouseEvent arg0) {
       // TODO Auto-generated method stub
       end = arg0.getPoint();
       repaint();
   }

   @Override
   public void mouseMoved(MouseEvent arg0) {
       // TODO Auto-generated method stub

   }

   @Override
   public void mouseClicked(MouseEvent arg0) {
       // TODO Auto-generated method stub

   }

   @Override
   public void mouseEntered(MouseEvent arg0) {
       // TODO Auto-generated method stub

   }

   @Override
   public void mouseExited(MouseEvent arg0) {
       // TODO Auto-generated method stub

   }

   @Override
   public void mousePressed(MouseEvent arg0) {
       // TODO Auto-generated method stub
       start = arg0.getPoint();
   }

   @Override
   public void mouseReleased(MouseEvent arg0) {
       // TODO Auto-generated method stub

       if (start != null && end != null) {
           itemsDrawn.add(shape + " " + color + " " + start.x + " " + start.y
                   + " " + end.x + " " + end.y + " " + fillBox.isSelected());

       }
       start = null;
       end = null;
   }

}

long i know im sorry..

but heres my issue. if you look at were the program calls the gradient color to be painted it works and draws an oval or rectangle with the 2 gradient colors. however as soon as i start drawing the next shape the color of the object turns to the first color selected.

i believe the error is here public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub

   if (start != null && end != null) {
       itemsDrawn.add(shape + " " + color + " " + start.x + " " + start.y
               + " " + end.x + " " + end.y + " " + fillBox.isSelected());

but i cant for the life of me figure out how to save the gradient color instead of the solid color. please help. thanks (if you need pictures for a better explanation i can upload some)

Rather than relying on String parsing, actually define the objects and their properties which can be painted.

This would be mean that when the user starts to draw on the surface, you would need to create a new "drawable" object and seed it with the properties it needs, for example...

例

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.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
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.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class MyPaint {

    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("Testing");
                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.WEST);

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

    public class State {

        private final Color foreground;
        private final Color background;
        private final boolean gradient;

        public State(Color foreground, Color background, boolean gradient) {
            this.foreground = foreground;
            this.background = background;
            this.gradient = gradient;
        }

        public Color getBackground() {
            return background;
        }

        public Color getForeground() {
            return foreground;
        }

        public boolean isGradient() {
            return gradient;
        }

    }

    public class ControlPane extends JPanel {

        private JComboBox shapes;
        private JLabel foreground;
        private JLabel background;
        private JCheckBox gradient;

        private DrawablePane drawablePane;

        public ControlPane(DrawablePane pane) {
            // I'd prefer to use some kind of factory, but this is just an example..
            shapes = new JComboBox<>(new String[]{"Rectangle", "Oval"});
            foreground = createColorLable(Color.BLACK);
            foreground.setToolTipText("Foreground");
            background = createColorLable(Color.WHITE);
            background.setToolTipText("Background");
            gradient = new JCheckBox("Gradient");

            JPanel panel = new JPanel();
            panel.add(foreground);
            panel.add(background);

            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);

            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);
        }

        protected Drawable createDrawable() {

            Drawable drawable = null;
            State state = new State(foreground.getBackground(), background.getBackground(), gradient.isSelected());
            String selected = (String) shapes.getSelectedItem();
            if ("rectangle".equalsIgnoreCase(selected)) {
                drawable = new Square(state);
            } else if ("oval".equalsIgnoreCase(selected)) {
                drawable = new Circle(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();
            if (state.isGradient()) {
                if (bounds.width > 0 && bounds.height > 0) {
                    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 {
                g2d.setPaint(state.getBackground());
                g2d.fill(shape);
                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 DrawablePane extends JPanel {

        private 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();

        }

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM