【進階JAVA】第二次作業 小畫家功能實作



PainterFrame.java 基本上就是上次第一次作業的範圍





import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.color.*;
import javax.swing.*;




public class PainterFrame extends JFrame{
 private final JComboBox  paintingToolsBox;
 private final static String toolsArray[] = {"筆刷","直線","橢圓形","矩形","圓角矩形"}; 
 private final JPanel northPnl;
 private final JPanel radioButtonPnl;
 private final JPanel northRightPnl;
 private final JPanel northLeftPnl;
 private  PaintPanel paintPanel;
 private final JRadioButton smallRadioButton;
 private final JRadioButton mediumRadioButton;
 private final JRadioButton largeRadioButton;
 private final ButtonGroup radioGroup;
 private final JLabel label1;
 private final JLabel label2;
 private final JLabel label3;
 public  static JLabel statusBarLabel;
 private final JCheckBox fillCheckBox;
 private final JButton button1;
 private final JButton button2;
 private final JButton button3;
 private final JButton button4;
 
 public static int paintsize = 4;
 public static String toolselect =toolsArray[0];
 public static boolean fillcheck =false;
 public static Color forecolor = Color.BLACK;
 public static Color backcolor = Color.black;
 public static boolean clear =false;
 public PainterFrame() {
  super("小畫家");
  BorderLayout layOut = new BorderLayout();
  setLayout(layOut);
  //welcome message
  
  //JCombobox
  paintingToolsBox = new JComboBox(toolsArray);
  paintingToolsBox.addItemListener(
    new ItemListener()
    {
     @Override
     public void itemStateChanged(ItemEvent e)
     {
      if(e.getStateChange() == ItemEvent.SELECTED)
       System.out.printf("選擇  %s\r\n",toolsArray[paintingToolsBox.getSelectedIndex()]);
      switch(toolsArray[paintingToolsBox.getSelectedIndex()]) {
      case "筆刷":
       toolselect = toolsArray[0];
       fillCheckBox.setEnabled(false);
       break;
      case"直線":
       toolselect = toolsArray[1];
       fillCheckBox.setEnabled(true);
       break;
      case"橢圓形":
       toolselect = toolsArray[2];
       fillCheckBox.setEnabled(true);
       break;
      case"矩形":
       toolselect = toolsArray[3];
       fillCheckBox.setEnabled(true);
       break;
      case"圓角矩形":
       toolselect = toolsArray[4];
       fillCheckBox.setEnabled(true);
       break;
      }//end switch
     }//end itemStateChanged
     
    });
  
  //上面大Panel
  northPnl = new JPanel();
  GridLayout northLayout = new GridLayout(1,2);
  northPnl.setLayout(northLayout);
  //右上panel
  northRightPnl = new JPanel();
  GridLayout northRightLayout =  new GridLayout(2,3);
  northRightPnl.setLayout(northRightLayout);
  //左上panel
  northLeftPnl = new JPanel();
  GridLayout northLeftLayout = new GridLayout(1,4,10,10);
  northLeftPnl.setLayout(northLeftLayout);
  //radioButton panel
  radioButtonPnl = new JPanel();
  radioButtonPnl.setLayout(new GridLayout());
  //drawing Panwl
  paintPanel = new PaintPanel();
  //labels
  label1 = new JLabel("繪圖工具");
  label2 = new JLabel("筆刷大小");
  label3 = new JLabel("填滿");
  
  //radioButtons
  smallRadioButton = new JRadioButton("小",true);
  mediumRadioButton = new JRadioButton("中",false);
  largeRadioButton = new JRadioButton("大",false);
  radioButtonPnl.add(smallRadioButton);
  radioButtonPnl.add(mediumRadioButton);
  radioButtonPnl.add(largeRadioButton);
  smallRadioButton.addItemListener(new RadioButtonHandler(smallRadioButton.getText()));
  mediumRadioButton.addItemListener(new RadioButtonHandler(mediumRadioButton.getText()));
  largeRadioButton.addItemListener(new RadioButtonHandler(largeRadioButton.getText()));
  //checkBox
  fillCheckBox = new JCheckBox();
  fillCheckBox.setEnabled(false);
  CheckBoxHandler checkBoxHandler= new CheckBoxHandler();
  fillCheckBox.addItemListener(checkBoxHandler);
  //buttons
  button1 = new JButton("前景色");
  button2 = new JButton("背景色");
  button3 = new JButton("清除畫面");
  button4 = new JButton("橡皮擦");
  button1.setBackground(Color.BLACK);
  
  button1.addActionListener(new ButtonHandler(button1.getText()));
  button2.addActionListener(new ButtonHandler(button2.getText()));
  button3.addActionListener(new ButtonHandler(button3.getText()));
  button4.addActionListener(new ButtonHandler(button4.getText()));
  
  //create logical relationship between JRadioButtons
  radioGroup = new ButtonGroup();
  radioGroup.add(smallRadioButton);
  radioGroup.add(mediumRadioButton);
  radioGroup.add(largeRadioButton);
  
  //status bar,mouse handler
  statusBarLabel = new JLabel();
  //MouseHandler mouseHandler = new MouseHandler();
  //paintPanel.addMouseMotionListener(mouseHandler);
  
  northRightPnl.add(label1);//1
  northRightPnl.add(label2);//2
  northRightPnl.add(label3);//3
  northRightPnl.add(paintingToolsBox);//4
  northRightPnl.add(radioButtonPnl);//5
  northRightPnl.add(fillCheckBox);//6
  northLeftPnl.add(button1);
  northLeftPnl.add(button2);
  northLeftPnl.add(button3);
  northLeftPnl.add(button4);
  northPnl.add(northRightPnl);
  northPnl.add(northLeftPnl);
  add(northPnl,layOut.NORTH);
  add(paintPanel,BorderLayout.CENTER);
  add(statusBarLabel,BorderLayout.SOUTH);
 }//end constructor
  
 private class RadioButtonHandler implements ItemListener {
  public String size;
  public RadioButtonHandler(String size) {
   this.size = size;
   
   
  }//end constructor
  @Override 
  public void itemStateChanged(ItemEvent e) {
   if(e.getStateChange() == ItemEvent.SELECTED)
    System.out.printf("選擇  %s 筆刷\r\n", size);
   switch(size) {
   case "小":
    paintsize = 4;
    break;
   case "中":
    paintsize = 25;
    break;
   case "大":
    paintsize = 50;
    break;
   }//end switch
  }//end itemStatechanged
 }//end radioButtonHandler
 
 private class CheckBoxHandler implements ItemListener{
  @Override
  public void itemStateChanged(ItemEvent e) {
   if(e.getStateChange() == ItemEvent.SELECTED) {
    System.out.println("選擇填滿");
    fillcheck = true;
    
   }//end if
   else {
    System.out.println("取消填滿");
    fillcheck = false;
   }
  }//end itemStateChanged
  
 }//end CheckBoxHandler
 
 private class ButtonHandler implements ActionListener{
  public String text;
  public ButtonHandler(String text) {
   this.text = text;
  }//end constructor
  @Override 
  public void actionPerformed(ActionEvent e) {
   System.out.printf("點選  %s\r\n",text);
   switch(text) {
    case"前景色":
    forecolor = JColorChooser.showDialog(PainterFrame.this, "Choose a color", forecolor);
    button1.setBackground(forecolor);
    break;
   case"背景色":
    backcolor = JColorChooser.showDialog(PainterFrame.this, "Choose a color", backcolor);
    button2.setBackground(backcolor);
    break;
    
   case"清除畫面":
    clear = true;
    paintPanel.clearPanel();
    
    //paintPanel = new PaintPanel();
    //add(paintPanel,BorderLayout.CENTER);
    break;
   case"橡皮擦":
    forecolor = Color.WHITE;
    backcolor = Color.WHITE;
    
    break;
    
   }//end switch
  }
 }//end ButtonHandler
 
 /*private class MouseHandler extends MouseAdapter{
  @Override
  public void mouseMoved(MouseEvent e) {
   statusBarLabel.setText((String.format("游標位置 [%d,%d]", e.getX(),e.getY())));
  }//end mouseMoved
 }//end mouseHandler
 */
}//end class

PaintPanel.java 繼承JPanel 來做筆刷等功能



import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;

import javax.swing.JPanel;

public class PaintPanel extends JPanel {
 private final ArrayList<PaintPoint> points = new ArrayList<>();
 private Point firstpointbuffer;
 private Point lastpointbuffer;
 private final ArrayList<LinePoints> lines = new ArrayList<>();
 private final ArrayList<OvalShape> ovals = new ArrayList<>();
 private final ArrayList<RectShape> rects = new ArrayList<>();
 
 //private Point ovalpointbuffer1;
 //private Point ovalpointbuffer2;
 public PaintPanel() {
  firstpointbuffer = new Point();
  lastpointbuffer = new Point();
  this.setBackground(Color.WHITE);
  
  addMouseMotionListener(
    
    new MouseMotionAdapter()
    {
     
     @Override
     public void mouseDragged(MouseEvent e)
     {
      switch(PainterFrame.toolselect) {
      case "筆刷":
       points.add(new PaintPoint(e.getPoint(),PainterFrame.paintsize,PainterFrame.forecolor));
       
       break;
      case"直線":
       lastpointbuffer = e.getPoint();
       break;
      case"橢圓形":
       lastpointbuffer = e.getPoint();
       break;
      case"矩形":
       lastpointbuffer = e.getPoint();
       break;
      case"圓角矩形":
       
       break;
      }//end switch
      repaint();
      
     }//end mouseDragged
     
     @Override
     public void mouseMoved(MouseEvent e) {
      PainterFrame.statusBarLabel.setText((String.format("游標位置 [%d,%d]", e.getX(),e.getY())));
     }//end MouseMoved 
    }//end mousemotionadapter
    );
  addMouseListener(
    new MouseAdapter()
    {
     @Override 
     public void mousePressed(MouseEvent e) {
      firstpointbuffer = e.getPoint();
     }//end mouseRelease
     
     @Override
     public void mouseReleased(MouseEvent e) {
      switch(PainterFrame.toolselect) {
      case "筆刷":
       break;
      case"直線":
       if(PainterFrame.fillcheck) {
       lines.add(new LinePoints(firstpointbuffer,e.getPoint(),new BasicStroke(PainterFrame.paintsize),PainterFrame.forecolor));
       
       repaint(); 
       }//end if
       else{
       lines.add(new LinePoints(firstpointbuffer,e.getPoint(),new BasicStroke(
         PainterFrame.paintsize, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{9}, 0),PainterFrame.forecolor));
       repaint();
       //System.out.println("1");
       
       }//end else
       break;
      case"橢圓形":
       ovals.add(new OvalShape(
         firstpointbuffer,e.getPoint(),PainterFrame.forecolor,PainterFrame.backcolor,PainterFrame.fillcheck,new BasicStroke(
           PainterFrame.paintsize)));
       repaint();
       break;
      case"矩形":
       rects.add(new RectShape(
         firstpointbuffer,e.getPoint(),PainterFrame.forecolor,PainterFrame.backcolor,PainterFrame.fillcheck,new BasicStroke(
           PainterFrame.paintsize)));
       repaint();
       
       break;
      case"圓角矩形":
       
       break;
      }//end switch
      
     }//end mouseReleased
     
    }//end mouseadapter
    );//end mouseListener
 }//end constructor
 @Override 
 public void paintComponent(Graphics g) {
  super.paintComponent(g);
  Graphics2D g2 = (Graphics2D) g;
  
   for(PaintPoint point:points) {
    g.setColor(point.forecolor);
    g.fillOval(point.x, point.y, point.size , point.size);}//end for
   
   for(LinePoints line:lines) {
    g2.setColor(line.forecolor);
    g2.setStroke(line.thickness);
    g2.drawLine(line.firstpoint.x, line.firstpoint.y, line.lastpoint.x, line.lastpoint.y);
   }//end for
   
   //暫時直線
   if(PainterFrame.toolselect=="直線" && PainterFrame.fillcheck) {
    g2.setColor(PainterFrame.forecolor);
    g2.setStroke(new BasicStroke(PainterFrame.paintsize));
    g2.drawLine(firstpointbuffer.x, firstpointbuffer.y, lastpointbuffer.x, lastpointbuffer.y);
   }//end if
   else if(PainterFrame.toolselect=="直線") {
    g2.setColor(PainterFrame.forecolor);
    g2.setStroke(new BasicStroke(PainterFrame.paintsize, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{9}, 0));
    g2.drawLine(firstpointbuffer.x, firstpointbuffer.y, lastpointbuffer.x, lastpointbuffer.y);
   }//end else if
   
   for(OvalShape oval:ovals) {
    g2.setColor(oval.forecolor);
    g2.setStroke(oval.thickness);
    
    if(oval.fillcheck) {
     g2.setColor(oval.backcolor);
     g2.fillOval(oval.startpoint.x, oval.startpoint.y, oval.width, oval.height);//先填滿
     g2.setColor(oval.forecolor);
     g2.drawOval(oval.startpoint.x, oval.startpoint.y, oval.width, oval.height);//在畫邊框
    }//end if
    else {
     g2.drawOval(oval.startpoint.x, oval.startpoint.y, oval.width, oval.height);
    }//end else
   }//end for
   
   //暫時橢圓
   if(PainterFrame.toolselect == "橢圓形") {
    
    g2.setStroke(new BasicStroke(PainterFrame.paintsize));
    g2.setColor(PainterFrame.forecolor);
    if(PainterFrame.fillcheck) {
     g2.setColor(PainterFrame.backcolor);
     g2.fillOval(Math.min(firstpointbuffer.x, lastpointbuffer.x), Math.min(firstpointbuffer.y, lastpointbuffer.y),
       Math.abs(firstpointbuffer.x-lastpointbuffer.x), Math.abs(firstpointbuffer.y-lastpointbuffer.y));//先填滿
     g2.setColor(PainterFrame.forecolor);
     g2.drawOval(Math.min(firstpointbuffer.x, lastpointbuffer.x), Math.min(firstpointbuffer.y, lastpointbuffer.y),
       Math.abs(firstpointbuffer.x-lastpointbuffer.x), Math.abs(firstpointbuffer.y-lastpointbuffer.y));//在畫邊框
    }//end if
    else {
     g2.drawOval(Math.min(firstpointbuffer.x, lastpointbuffer.x), Math.min(firstpointbuffer.y, lastpointbuffer.y),
       Math.abs(firstpointbuffer.x-lastpointbuffer.x), Math.abs(firstpointbuffer.y-lastpointbuffer.y));
    }//end else
    
   }//end if
   
   for(RectShape rect:rects) {
    g2.setColor(rect.forecolor);
    g2.setStroke(rect.thickness);
    
    if(rect.fillcheck) {
     g2.setColor(rect.backcolor);
     g2.fillRect(rect.startpoint.x, rect.startpoint.y, rect.width, rect.height);//先填滿
     g2.setColor(rect.forecolor);
     g2.drawRect(rect.startpoint.x, rect.startpoint.y, rect.width, rect.height);//在畫邊框
    }//end if
    else {
     g2.drawRect(rect.startpoint.x, rect.startpoint.y, rect.width, rect.height);
    }//end else
   }//end for
   
   //暫時矩形
   if(PainterFrame.toolselect =="矩形" && PainterFrame.clear == false) {
    g2.setStroke(new BasicStroke(PainterFrame.paintsize));
    g2.setColor(PainterFrame.forecolor);
    if(PainterFrame.fillcheck) {
     g2.setColor(PainterFrame.backcolor);
     g2.fillRect(Math.min(firstpointbuffer.x, lastpointbuffer.x), Math.min(firstpointbuffer.y, lastpointbuffer.y),
       Math.abs(firstpointbuffer.x-lastpointbuffer.x), Math.abs(firstpointbuffer.y-lastpointbuffer.y));//先填滿
     g2.setColor(PainterFrame.forecolor);
     g2.drawRect(Math.min(firstpointbuffer.x, lastpointbuffer.x), Math.min(firstpointbuffer.y, lastpointbuffer.y),
       Math.abs(firstpointbuffer.x-lastpointbuffer.x), Math.abs(firstpointbuffer.y-lastpointbuffer.y));//在畫邊框
    }//end if
    else {
     g2.drawRect(Math.min(firstpointbuffer.x, lastpointbuffer.x), Math.min(firstpointbuffer.y, lastpointbuffer.y),
       Math.abs(firstpointbuffer.x-lastpointbuffer.x), Math.abs(firstpointbuffer.y-lastpointbuffer.y));
    }//end else
   }
   
  
 }//end PaintComponent
 //清除畫面阿
 public void clearPanel() {
  points.clear();
  lines.clear();
  ovals.clear();
  rects.clear();
  firstpointbuffer = new Point();
  lastpointbuffer = new Point();
  repaint();
  PainterFrame.clear = false;
 }//end clearPanel
 //專屬於筆刷的
 public static class PaintPoint extends Point
 {
  public int size;
  public Color forecolor;
  public PaintPoint(Point p,int size,Color forecolor ) {
   super(p);
   this.size = size;
   this.forecolor = forecolor;
  }//end constructor
 }//end PaintPoint
 
 public static class LinePoints{
  public Color forecolor;
  public Point firstpoint;
  public Point lastpoint;
  public BasicStroke thickness;
  public LinePoints(Point one , Point two, BasicStroke thickness,Color forecolor) {
   firstpoint = one;
   lastpoint = two;
   this.thickness = thickness;
   this.forecolor = forecolor;
   
  }//end constructor
 }//end LinePoints
 
 public static class OvalShape {
  public Point startpoint;
  public Point endpoint;
  public int width, height;
  public Color forecolor;
  public Color backcolor;
  public Boolean fillcheck;
  public BasicStroke thickness;
  public OvalShape(Point p,Point p2,Color forecolor,Color backcolor,Boolean fillcheck,BasicStroke thickness) {
   this.startpoint = p;
   this.endpoint = p2;
   this.forecolor = forecolor;
   this.backcolor = backcolor;
   this.fillcheck = fillcheck;
   this.thickness = thickness;
   this.width = Math.abs(p2.x-p.x);
   this.height = Math.abs(p2.y-p.y);
   
   if(p2.x<p.x) {
    this.startpoint.x = p2.x;
   }//end if
   if(p2.y<p.y){
    this.startpoint.y = p2.y;
   }//end if
   
  }//end constructor
 }//end OvalShape
 
 public static class RectShape{
  public Point startpoint;
  public Point endpoint;
  public Color forecolor;
  public Color backcolor;
  public int width,height;
  public boolean fillcheck;
  public BasicStroke thickness;
  public RectShape(Point p,Point p2,Color forecolor,Color backcolor,Boolean fillcheck,BasicStroke thickness) {
   this.startpoint = p;
   this.endpoint = p2;
   this.forecolor = forecolor;
   this.backcolor = backcolor;
   this.thickness = thickness;
   this.fillcheck = fillcheck;
   this.width = Math.abs(p2.x-p.x);
   this.height = Math.abs(p.y-p2.y);
   if(p2.x<p.x) {
    this.startpoint.x = p2.x;
   }//end if
   if(p2.y<p.y){
    this.startpoint.y = p2.y;
   }//end if
   
   
  }//end constructor
 }//end rectShape
}//end class

Main 用來執行的檔案



import javax.swing.JFrame;
import javax.swing.JOptionPane;


public class PainterTest {
 public static void main(String[]args) {
  PainterFrame painterFrame = new PainterFrame();
  
  painterFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  painterFrame.setSize(1000, 500);
  painterFrame.setVisible(true);
  JOptionPane.showMessageDialog(painterFrame, "wellcome", "訊息", JOptionPane.PLAIN_MESSAGE);
 }//end main
}//end class

留言

熱門文章