2014-04-16 19 views
0

好的,这是我的代码。 包mypanal;在jframe上绘制后保存渐变色对象(JAVA)

/** * * @author摩根 */

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

} 

长,我知道对不起..

但是我的继承人问题。 如果你看看程序调用渐变色来绘制它的效果,并绘制一个椭圆或长方形与2渐变颜色。然而,只要我开始绘制下一个形状,对象的颜色就会变成所选的第一种颜色。

我相信错误是在这里 公共无效的mouseReleased(的MouseEvent为arg0){// TODO自动生成方法存根

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

,但我不能为我的生活弄清楚如何拯救梯度颜色而不是纯色。 请帮忙。 谢谢 (如果你需要更好的解释我可以上传一些图片)

+0

好的,所以你使用一个'String'作为你想绘制和后来解析它的表示,在一个面向对象的编程语言中......为什么不创建一个'Drawable'对象,它有一个简单的“绘画”方法,它知道如何绘画自己。当你创建它时,传入一个描述控件当前状态的'State'对象,并允许它确定它需要的信息,以便稍后重新绘制自己的内容......这样你就可以不断向内容添加内容'国家',只有'可绘制的'关心将需要访问它...只是说... – MadProgrammer

+0

即时通讯不太确定我明白你的建议..你能给我一个例子在代码? – Lewmor71

+0

花了一段时间,但我已经添加了一个我正在谈论的例子 – MadProgrammer

回答

1

而不是依靠String解析,实际上定义了可以绘制的对象及其属性。

这将意味着,当用户开始绘制表面上,你需要创建一个新的“绘制”对象,并使用需要,例如性能种子吧...

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

     } 

    } 
} 
+0

我得老实,我的代码丢失了。我了解你的想法,但我无法遵循你的方法... – Lewmor71

+0

想通了。非常感谢你的帮助。设法完成并实现了您向我展示的虚线,线宽/长度调整能力,撤消和清除按钮。再次感谢 – Lewmor71