国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

用JAVA寫一個畫圖小程序(JAVA 大作業(yè))

這篇具有很好參考價值的文章主要介紹了用JAVA寫一個畫圖小程序(JAVA 大作業(yè))。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

第一次寫博客 且是稍微大點(diǎn)的程序 看看就行
重新寫的在這,更加清晰明了: 用Java寫一個畫圖程序
  • 設(shè)計(jì)思路

首先我直接去了Windows自帶畫圖程序去實(shí)踐模擬,看看具體方法,進(jìn)行了布局和按鈕的思考。

容器頂層放工具欄,工具欄中存放圖形按鈕、工具按鈕、顏色按鈕。對于圖形按鈕,存放在垂直的Box中,分成行列,設(shè)置邊框,設(shè)置標(biāo)簽,加入JToolbar;對于工具按鈕設(shè)置Jpanel保存,線條粗細(xì)設(shè)置垂直Box存儲,設(shè)置邊框后,最后將兩者加入水平Box中,與前面圖形按鈕設(shè)置間隔加入JToolbar中,設(shè)置標(biāo)簽;對于顏色按鈕,畫布背景顏色選擇按鈕單獨(dú)設(shè)置大按鈕,直接加入JToolbar,而顏色選擇按鈕我設(shè)置了JPanel,垂直Box進(jìn)行組裝,成行列,設(shè)置邊框,加入JToolbar中。最后的顏色選擇編輯按鈕,也是單獨(dú)大按鈕,加入JToolbar中。

最終效果如下:

用JAVA寫一個畫圖小程序(JAVA 大作業(yè))

這個程序,難在哪里?難在工具欄中按鈕監(jiān)聽。對于工具欄中各個按鈕,我要實(shí)時監(jiān)聽。但是對于工具欄中每一個按鈕我都進(jìn)行行為監(jiān)聽,適配器模式也招架不住程序的紊亂。于是寫一個類,繼承MouseAdapter、ActionListener,重寫部分監(jiān)聽方法。

對于行為監(jiān)聽、鼠標(biāo)抓取,進(jìn)行了一些操作,下面類的設(shè)計(jì)會詳細(xì)講解。在這個過程中我對所有圖形特征進(jìn)行了分析,順著這個我也創(chuàng)建了一個Shape類,類屬性包含了所有圖形的特征??墒枪ぞ邫诓粏螁斡袌D形構(gòu)畫,還有橡皮擦、顏色、粗細(xì),為此我對Shape里面的屬性做了調(diào)整,可以存儲當(dāng)前線條顏色、粗細(xì)。

對于菜單的設(shè)計(jì)較為簡單,因?yàn)闆]有太強(qiáng)邏輯可言,你想讓它如何展現(xiàn),展現(xiàn)什么內(nèi)容,就怎樣重寫監(jiān)聽方法。我設(shè)計(jì)了文件保存、打開以及畫圖的屬性、幫助、界面風(fēng)格。寫了一個MyMenu類,進(jìn)行相關(guān)設(shè)計(jì)組裝,下面也會具體講解。

圖畫刷新展示需要進(jìn)行repaint,我寫了MyFrame類繼承JFrame,重寫paint方法。在MyJFrame類中有參構(gòu)造的同時,我也進(jìn)行了畫圖的圖標(biāo)處理,這樣更加更美觀。

最終就是拼裝完成,設(shè)置界面,進(jìn)行顯示。

總結(jié):利用java中的現(xiàn)有類,創(chuàng)建主窗口、創(chuàng)建主窗口中內(nèi)容、設(shè)置事件響應(yīng)機(jī)制、顯示主窗口、進(jìn)入消息循環(huán)接收處理。

用JAVA寫一個畫圖小程序(JAVA 大作業(yè))

?用JAVA寫一個畫圖小程序(JAVA 大作業(yè))

輸入java Painter conf/Painter-1.ini 展示圓、矩形

用JAVA寫一個畫圖小程序(JAVA 大作業(yè))

輸入java Painter conf/Painter-2.ini 展示圓、矩形、三角形、菱形、多邊形

用JAVA寫一個畫圖小程序(JAVA 大作業(yè))

其中功能按鈕、曲線、直線會一直展現(xiàn)。

  • 類的設(shè)計(jì)

(一)

  1. MyMouseListener

繼承MouseAdapter適配器和MouseListner接口,進(jìn)行一些方法重寫。通過重寫actionPerformed,先行獲取按鈕內(nèi)容,設(shè)置屬性。

(1)曲線、橡皮擦、噴槍、毛筆

在mouseDragged方法中進(jìn)行行為監(jiān)聽。這個拖拽的過程是需要實(shí)時更新的,坐標(biāo)也需要實(shí)時更新。

<1>曲線:是由無數(shù)直線拼接而來,不斷創(chuàng)建shape,draw。這里我最開始也是用的實(shí)心圓,但是太曲折了,在網(wǎng)上資源也都是直線。

直線:用JAVA寫一個畫圖小程序(JAVA 大作業(yè))

實(shí)心圓:用JAVA寫一個畫圖小程序(JAVA 大作業(yè))

這里對比明顯直線更勝一籌。

<2>橡皮擦:我的思路是在鼠標(biāo)拖拽相應(yīng)位置同樣創(chuàng)建shape,而這些shape對象的顏色則為畫布初始顏色,draw,實(shí)現(xiàn)橡皮擦功能。

<3>噴槍、毛筆:都是范圍內(nèi)進(jìn)行噴畫,可以用循環(huán)畫無數(shù)條線的方式解決,并且這些直線是不連續(xù)的、隨機(jī)的??梢允褂肦andom循環(huán)一次次創(chuàng)建shape,draw。毛筆與噴槍不同的一點(diǎn)就是墨水會減少,需要記錄刷新,畫筆變細(xì),最后為空,當(dāng)再次pressed、released刷新“墨水”。

  1. 刷新、上一步

在actionPerformed中獲取按鈕內(nèi)容之后,根據(jù)if條件,對vector中的數(shù)據(jù)進(jìn)行更新。這里刷新之后,上一次vector數(shù)據(jù)要存起來,防止下次點(diǎn)擊上一步不展示任何內(nèi)容,利用兩個vector互相轉(zhuǎn)換,repaint。

  1. 直線、矩形、圓、三角形、菱形

重寫mousePressed和mouseReleased方法,獲取兩頂點(diǎn)坐標(biāo),算法得出左上角坐標(biāo)與右下角坐標(biāo)。

<1>直線、矩形、圓、橢圓

在庫中有相應(yīng)的draw方法,對于直線、矩形,在已知坐標(biāo)的情況,創(chuàng)建shape,draw;對于圓,我設(shè)置圓心為pressed點(diǎn),計(jì)算拖拽距離為r,創(chuàng)建shape,draw;對于橢圓,我則是借鑒Windows畫圖中的畫法,通過拖拽坐標(biāo)得寬高,創(chuàng)建shape,draw。

<2>三角形、菱形

三角形:直角三角形、等腰三角形,根據(jù)拖拽坐標(biāo),找尋第三個點(diǎn),創(chuàng)建三個type為直線的shape,draw三條線。

菱形:根據(jù)拖拽點(diǎn)計(jì)算四個點(diǎn)坐標(biāo),創(chuàng)建四個type為直線的type,draw四條直線。

  1. 多邊形

對于多邊形,獲取坐標(biāo),相鄰的點(diǎn)進(jìn)行聯(lián)接,創(chuàng)建多個type為直線的shape。并且存著首個坐標(biāo)點(diǎn),雙擊鼠標(biāo),可將圖形封閉為多邊形。

  1. 畫筆粗細(xì)、顏色編輯

畫筆粗細(xì):根據(jù)按鈕對象,創(chuàng)建stroke對象,在下次畫圖時傳入shape中。

畫布顏色:調(diào)用JColorChooser.showDialog進(jìn)行選擇,改變背景顏色,同時改變按鈕邊框顏色。

畫筆顏色:根據(jù)點(diǎn)擊的按鈕,設(shè)置畫筆相應(yīng)的顏色,存入color對象,傳入shape中。另外對點(diǎn)擊的圖形按鈕設(shè)置相應(yīng)的邊框顏色。

按鈕顏色編輯:自選顏色后可填入按鈕中,并且設(shè)置循環(huán),可反復(fù)覆蓋。

  1. Shape

這個類實(shí)現(xiàn)了每一個圖形的數(shù)據(jù)存儲,包含兩個坐標(biāo)點(diǎn),畫筆顏色,圖形類型,畫筆粗細(xì)。

對于直線、橢圓、圓、矩形,兩個坐標(biāo)即可畫出圖形。多邊形、三角形、噴槍、毛筆、橡皮擦,則是由若干條線段構(gòu)成的,只需創(chuàng)建多個類型為直線的shape對象。color,stroke對象記錄當(dāng)前畫筆顏色,畫筆粗細(xì)。

  1. MyFrame

繼承JFrame類,設(shè)置兩個vector,v和v1的目的 v和v2都有存儲圖形的功能 用于遍歷repaint。另外我可以當(dāng)刷新時,將v的所有數(shù)據(jù)送給v1?;赝藭r,我可以遍歷v1,避免空畫。

有參(title)構(gòu)造MyFrame,并且在其中進(jìn)行圖標(biāo)的設(shè)置。對paint方法進(jìn)行重寫,首先調(diào)用父類中的方法。其次將Graphics強(qiáng)制轉(zhuǎn)換為Graphics2D,為了實(shí)現(xiàn)畫筆粗細(xì)。在遍歷過程中對shape中stroke,color進(jìn)行獲取,根據(jù)type畫圖。

其中直線、曲線、三角形、多邊形的type都是直線,drawLine即可;圓、橢圓、矩形,則根據(jù)shape中兩個坐標(biāo)獲取左上角坐標(biāo),計(jì)算大小,調(diào)用draw或fill方法。

最后若存在image,則drawImage,打開文件照片之后畫布可以顯示圖片信息。

  1. MyMenu

構(gòu)建菜單,設(shè)置菜單條,創(chuàng)建MyMouseListener對象。在類中構(gòu)造方法,創(chuàng)建菜單條。

文件菜單下創(chuàng)建打開、保存、屬性、幫助等menuItem,并且過程中直接設(shè)置行為監(jiān)聽。

其中文件打開,JFileChooser默認(rèn)為當(dāng)前目錄,選取文件進(jìn)行獲取,repaint圖片到畫布;文件保存,可在一定的區(qū)間范圍內(nèi),畫布保存為圖片,默認(rèn)保存路徑為當(dāng)前目錄,獲取選擇文件路徑,圖片格式為jpg,如果保存了,則設(shè)置flag為真,關(guān)閉程序不會彈出窗口。

屬性和幫助則是彈出窗口顯示相關(guān)說明性信息。

格式菜單下設(shè)置了幾種風(fēng)格,可以進(jìn)行選擇刷新組件外觀,更換界面主題,并且repaint,將圖畫信息轉(zhuǎn)移到當(dāng)前畫布。

最后所有菜單裝入菜單條,組裝至容器中。

  1. MyJToolbar

繼承JToolbar類。創(chuàng)建一個初始化方法,對于按鈕則可以設(shè)計(jì)for循環(huán),進(jìn)行創(chuàng)建加入圖片,監(jiān)聽,裝入工具欄;對于線條粗細(xì)的按鈕,設(shè)置了一個垂直的Box拼裝,監(jiān)聽,裝入工具欄;對于顏色按鈕,則僅僅設(shè)置顏色,監(jiān)聽,裝入工具欄。

最后將工具欄裝入JFrame的頂部。

  1. Main

創(chuàng)建上述幾個類的對象,調(diào)用各類初始化方法,組裝,展示。

(二)

類之間的聯(lián)系

???? 我并沒有采用復(fù)雜的繼承關(guān)系和設(shè)置抽象的類與接 口,只是繼承了java中的一些原有的類和接口,便于 更好地實(shí)現(xiàn)自己寫的一些類以及繼承相應(yīng)的父類不可 少的方法。其次對于自己寫的幾個類,我的耦合度可 能高一點(diǎn),不太好可能,可能也不是,因?yàn)楦黝愔卸?有創(chuàng)建其他類的對象解決一些問題,各類中有創(chuàng)建相 應(yīng)變量進(jìn)行關(guān)聯(lián),改變窗口界面。

簡單地繼承:用JAVA寫一個畫圖小程序(JAVA 大作業(yè))

類之間的一些聯(lián)系:用JAVA寫一個畫圖小程序(JAVA 大作業(yè))

?代碼實(shí)現(xiàn)

1.Painter 主函數(shù)

package com.zzu;

import javax.swing.*;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

//框架:最上層Menu --->文件保存 導(dǎo)入 界面刷新(清除功能) 風(fēng)格更換
//     Menu下面放工具欄 繪制各種圖形 顏色 線條粗細(xì) 橡皮擦 字體模式大小
//     關(guān)閉界面可以彈出警告窗口 設(shè)置監(jiān)聽器是否保存
//     畫布 默認(rèn)CENTER

//Content:
//          一個shape類存儲Point color type
//          矩形: press、release為兩側(cè)頂點(diǎn)坐標(biāo) 通過計(jì)算可得左上角右下角坐標(biāo)及長寬 drawRect(Math.min(x1,x2), Math.min(y1,y2), Math.abs(x2-x1),Math.abs(y2-y1));
//          直線: Mouse press release   drawLine
//          圓: Mouse press release   drawOval
//          菱形: Mouse press release   drawLine
//          噴槍: random 的實(shí)心圓 或 坐標(biāo)點(diǎn)  fillOval
//          曲線: 這就需要MouseDrag監(jiān)聽不斷更新起點(diǎn)和終點(diǎn) Point1->Point2 Point2->新Point 無限小直線 drawLine
//          多邊形:release clicked drawLine
//          橡皮擦:區(qū)域內(nèi)添加新圖形 顏色為畫布顏色 橡皮擦大小也跟畫筆粗細(xì)相關(guān)聯(lián)
//          回退:返回上一步
//          刷新:畫布刪除所有圖形
//          粗細(xì):  Graphics2D Stroke
//          畫布背景顏色:  JColorChooser

public class Painter {

    //創(chuàng)建窗口對象
    MyFrame jf = new MyFrame("畫圖");

    //創(chuàng)建畫圖內(nèi)容監(jiān)聽對象
    MyMouseListener myMouseListener = new MyMouseListener();

    //彈出文件窗口放在JPanel 防止保存圖片時出現(xiàn)問題
    JPanel jPanel = new JPanel();

    //創(chuàng)建菜單對象
    MyMenu myMenu = new MyMenu(jf,jPanel);

    //創(chuàng)建工具欄對象
    MyJToolbar myJToolbar =  new MyJToolbar(jf,myMouseListener);

    //空參構(gòu)造
    public Painter(){
    }

    /**
     * @param file
     * @return ArrayList 文件內(nèi)容以若干個字符串傳出
     * @throws IOException
     */
    public static ArrayList<String> getFileContent(String file) throws IOException {

        BufferedReader reader = new BufferedReader(new FileReader(file));
        //這里ArrayList是為了存儲不確定個數(shù)的String
        ArrayList<String> content = new ArrayList<>();
        //獲取文件中字符串
        String line = "";
        try{
            while((line=reader.readLine())!=null){
                //首個屬性值
                if(line.contains("[")) {
                    continue;
                }
                String str[] = line.split("=");//分割出內(nèi)容
                if(str.length>1)  line = str[1];
                else line = str[0];

                line = line.trim();//去除首尾空格
                String str1[] = line.split(",");//逗號分隔開若干個
                //遍歷加入list
                for (String s : str1) {
                    content.add(s);
                }
            }
            return content;
        }finally{//始終保持文件最終關(guān)閉
            reader.close();
        }

    }


    /**
     * 展示界面
     * @throws Exception
     */
    public void showUI() throws Exception {

        //讀取圖形數(shù)據(jù)
        Scanner sc = new Scanner(System.in);
        String file = sc.next();
        ArrayList<String> list = getFileContent(file);
        myJToolbar.setList(list);

        //JFrame設(shè)置監(jiān)聽 可以任意畫曲線
        //添加鼠標(biāo)監(jiān)聽器
        jf.addMouseListener(myMouseListener);
        jf.addMouseMotionListener(myMouseListener);
        //將JFrame傳過去 實(shí)現(xiàn)repaint
        myMouseListener.setMyFrame(jf);

        //初始化菜單加入到JFrame中
        myMenu.init();

        //初始化工具欄加入JFrame中
        myJToolbar.init();

        //設(shè)置界面大小
        jf.setSize(1100,800);
        //居中顯示
        jf.setLocationRelativeTo(null);
        //設(shè)置可見
        jf.setVisible(true);
        //關(guān)閉進(jìn)程
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) throws Exception {
        new Painter().showUI();
    }
}


2.MyMenu 菜單類

package com.zzu;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;

public class MyMenu {
    private MyFrame jf;
    private JPanel jPanel;

    //菜單項(xiàng)組件
    //菜單條
    public JMenuBar jMenuBar = new JMenuBar();

    //兩個菜單
    public JMenu fileMenu = new JMenu("文件");
    public JMenu styleMenu = new JMenu("界面風(fēng)格");

    //確定文件是否被保存
    public boolean flag = false;

    //獲取畫布圖片信息或者獲取文件中圖片信息
    public BufferedImage image;

    public MyMenu() {
    }

    public MyMenu(MyFrame jf, JPanel jPanel) {
        this.jf = jf;
        this.jPanel = jPanel;
    }

    /**
     * 組裝菜單
     * @throws Exception
     */
    public void init() throws Exception {
        //fileMenu下的條目菜單 對應(yīng)設(shè)置行為監(jiān)聽
        //圖片打開
        JMenuItem open = new JMenuItem(new AbstractAction("打開",new ImageIcon("打開.png")) {
            @Override
            public void actionPerformed(ActionEvent e) {
                //顯示一個文件選擇器 當(dāng)前目錄
                JFileChooser fileChooser = new JFileChooser(".");
                fileChooser.showOpenDialog(jPanel);
                //獲取選擇的文件
                File file = fileChooser.getSelectedFile();
                //如果選擇了文件 就進(jìn)行相關(guān)操作
                if(file != null){
                    //進(jìn)行顯示
                    try {
                        image = ImageIO.read(file);
                        //將信息傳進(jìn)MyFrame中
                        jf.setImage(image);
                        jf.setIg(true);
                        jf.repaint();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });
        //圖片保存
        JMenuItem save = new JMenuItem(new AbstractAction("保存",new ImageIcon("保存.png")) {
            @Override
            public void actionPerformed(ActionEvent e) {
                //顯示一個文件選擇器 當(dāng)前目錄
                JFileChooser fileChooser = new JFileChooser(".");
                fileChooser.showSaveDialog(jPanel);
                //獲取用戶選擇的保存文件路徑
                File file = fileChooser.getSelectedFile();
                //如果只是打開目錄沒有保存 則不進(jìn)行下面操作
                if(file!=null){
                //保存
                try {
                    try {
                        //畫布保存為圖片 設(shè)置區(qū)域范圍大小
                        image = new Robot().createScreenCapture(new Rectangle(jf.getX(),jf.getY()+250, jf.getWidth(),jf.getHeight()-250));
                    } catch (AWTException ex) {
                        throw new RuntimeException(ex);
                    }
                    ImageIO.write(image,"jpg",file);//存入文件
                    flag = true;//保存成功
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            }
        });
        //關(guān)于畫圖
        JMenuItem attribute = new JMenuItem(new AbstractAction("關(guān)于畫圖",new ImageIcon("關(guān)于畫圖.png")) {
            //展示特性
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(jf,null,"關(guān)于畫圖",JOptionPane.DEFAULT_OPTION,new ImageIcon("屬性.png"));
            }
        });
        //幫助
        JMenuItem help = new JMenuItem(new AbstractAction("幫助",new ImageIcon("幫助.png")) {
            //展示內(nèi)容
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(null, "" + "******************\n" + "#畫圖軟件使用說明書#\r\n"
                        + "******************\n"
                        + "1.本軟件主要分為四個模塊:菜單、工具欄、調(diào)色板、和畫布\n"
                        + "(1)菜單欄的文件子菜單包括打開、保存圖片以及幫助,關(guān)于我們\r\n"
                        + "(2)工具主要包括清空畫板、撤回操作、圖形繪制\n"
                        + "(3)調(diào)色板位于界面的頂側(cè)工具欄,用于改變畫布背景顏色或設(shè)置畫筆的顏色\n"
                        + "(4)畫布用于圖形繪制,使用鼠標(biāo)選中要繪制的圖形即可進(jìn)行繪制\n"
                        +"2.具體操作:\n"
                        +"(1)可在畫布繪制任意曲線\n"
                        +"(2)矩形、三角形、菱形、箭頭:鼠標(biāo)拖拽 獲得兩頂點(diǎn)系統(tǒng)會算法確定位置大小\r\n"
                        +"(3)圓:鼠標(biāo)拖拽 press點(diǎn)和release點(diǎn)分別為圓心和圓上一點(diǎn)\n"
                        +"(4)多邊形:相鄰的兩點(diǎn)連接,雙擊則可形成封閉圖形\n"
                        +"(5)橡皮擦、噴槍 鼠標(biāo)點(diǎn)擊拖拽即可\n"
                        +"(6)畫筆粗細(xì)選擇\n"
                        +"(7)背景顏色、畫筆顏色可自動選擇 選擇之后點(diǎn)擊按鈕 按鈕邊框也會變色\n"
                        +"(8)最后的編輯顏色可以配色進(jìn)行選擇\n", "使用說明", JOptionPane.PLAIN_MESSAGE);
            }
        });

        //styleMenu風(fēng)格單選
        ButtonGroup buttonGroup = new ButtonGroup();
        JRadioButtonMenuItem metalItem = new JRadioButtonMenuItem("Metal 風(fēng)格");
        JRadioButtonMenuItem windowsItem = new JRadioButtonMenuItem("Windows 風(fēng)格",true);//默認(rèn)
        JRadioButtonMenuItem windowsClassicItem = new JRadioButtonMenuItem("Windows 經(jīng)典風(fēng)格");
        JRadioButtonMenuItem motifItem = new JRadioButtonMenuItem("Motif 風(fēng)格");

        //風(fēng)格選擇監(jiān)聽 避免多次重寫
        ActionListener listener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    //獲得內(nèi)容 傳送設(shè)置風(fēng)格
                    changeFlavor(e.getActionCommand());
                    //風(fēng)格改變后需要重畫
                    jf.repaint();
                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
            }
        };
        //退出若未保存則彈出提示窗口
        jf.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                if (!flag) {
                    // 彈出對話框 提示未保存
                     JOptionPane.showOptionDialog(jf,"你還沒保存,確定要退出嗎?","BBQ",JOptionPane.DEFAULT_OPTION
                            ,JOptionPane.WARNING_MESSAGE,null,new String[]{"確定","非常確定"},"確定");
                }
            }
        });

        //組裝風(fēng)格菜單
        buttonGroup.add(metalItem);
        buttonGroup.add(windowsItem);
        buttonGroup.add(windowsClassicItem);
        buttonGroup.add(motifItem);
        //添加監(jiān)聽器
        metalItem.addActionListener(listener);
        windowsItem.addActionListener(listener);
        windowsClassicItem.addActionListener(listener);
        motifItem.addActionListener(listener);
        //加入styleMenu
        styleMenu.add(metalItem);
        styleMenu.add(windowsItem);
        styleMenu.add(windowsClassicItem);
        styleMenu.add(motifItem);

        //文件以及幫助菜單
        fileMenu.add(open);
        fileMenu.add(save);
        fileMenu.add(attribute);
        fileMenu.add(help);

        //菜單欄
        jMenuBar.add(fileMenu);
        jMenuBar.add(styleMenu);

        //將組裝好的菜單欄裝入JFrame中
        jf.setJMenuBar(jMenuBar);
    }

    /**
     *
     * @param command
     * @throws Exception
     * 此方法用于改變界面風(fēng)格
     */
    public void changeFlavor(String command) throws Exception {
        switch (command) {
            case "Metal 風(fēng)格":
                UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
                break;
            case "Windows 風(fēng)格":
                UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
                break;
            case "Windows 經(jīng)典風(fēng)格":
                UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel");
                break;
            case "Motif 風(fēng)格":
                UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
                break;
        }

        //刷新組件的外觀
        SwingUtilities.updateComponentTreeUI(jf.getContentPane());
        SwingUtilities.updateComponentTreeUI(jMenuBar);

    }

    public MyFrame getJf() {
        return jf;
    }

    public void setJf(MyFrame jf) {
        this.jf = jf;
    }

    public JPanel getjPanel() {
        return jPanel;
    }

    public void setjPanel(JPanel jPanel) {
        this.jPanel = jPanel;
    }

}

3.MyJToolbar?工具欄類

package com.zzu;

import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

public class MyJToolbar extends JToolBar{
    static int num = 12;//當(dāng)前第幾個顏色選擇框
    private MyFrame jf;
    private MyMouseListener myMouseListener;
    private ArrayList<String> list;

    public MyJToolbar() {
    }


    public MyJToolbar(MyFrame jf, MyMouseListener myMouseListener) {
        //聲明工具條相關(guān)內(nèi)容
        super("工具欄",SwingConstants.HORIZONTAL);
        this.setBackground(new Color(0xCFFCE6));
        this.jf = jf;
        this.myMouseListener = myMouseListener;
    }

    //TODO 工具條拖動畫布內(nèi)容消失問題
    @Override
    public void setFloatable(boolean b) {
        super.setFloatable(b);
        if(b) jf.repaint();
    }

    /**
     * 組裝工具欄
     */
    public void init(){
        //組裝工具欄
        //工具欄內(nèi)容從最左側(cè)開始填充
        this.setLayout(new FlowLayout(FlowLayout.LEFT));
        for (int i = 0; i < 3; i++) {
            //設(shè)置間隔 美觀清晰
            this.addSeparator();
        }

        //第一行的這些圖形功能是剛需的 不需要判斷
        //第二行的需要根據(jù)文件讀取圖形數(shù)據(jù)判斷是否加入
        String[] image1 = {"直線.png", "曲線.png","空心矩形.png", "實(shí)心矩形.png", "空心圓.png","實(shí)心圓.png","空心橢圓.png","實(shí)心橢圓.png",
                "直角三角形.png","等腰三角形.png","菱形.png", "多邊形.png"};
        Box vBox = Box.createVerticalBox();
        JLabel jLabel1 = new JLabel("圖形選擇");
        JPanel jPanel1 = new JPanel();
        JPanel jPanel2 = new JPanel();
        //遍歷組裝圖形功能按鈕
        for (int i = 0; i < image1.length; i++) {
            boolean contain = false;
            if(i<2)   contain = true;//前幾個圖形不需要判定是否存在在文件中
            else {//文件中是否存在后面圖形
                for(String s:list){
                    if(image1[i].contains(s))   {
                        contain = true;
                        break;
                    }
                }
            }

            if(contain){
                //JButton圖片內(nèi)容
                JButton jbt = new JButton();
                ImageIcon icon = new ImageIcon(image1[i]);//實(shí)例化ImageIcon對象
                icon.setImage(icon.getImage().getScaledInstance(30,30,Image.SCALE_DEFAULT));//設(shè)置圖片大小與JButton大小匹配
                jbt.setIcon(icon);//加入JButton中
                //按鈕大小
                jbt.setPreferredSize(new Dimension(35,35));
                //設(shè)置監(jiān)聽器
                jbt.addActionListener(myMouseListener);
                //默認(rèn)邊框藍(lán)色
                jbt.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
                if(i<6) jPanel1.add(jbt);
                else    jPanel2.add(jbt);
            }
        }
        vBox.add(jPanel1);
        vBox.add(jPanel2);
        vBox.add(jLabel1);
        //vBox.setSize(210,80);
        vBox.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED, Color.RED, Color.GREEN));
        this.add(vBox);
        for (int i = 0; i < 3; i++) {
            //設(shè)置間隔 美觀清晰
            this.addSeparator();
        }

        //工具按鈕
        //水平Box存取工具 線條
        Box hBox = Box.createHorizontalBox();
        //設(shè)置邊框
        hBox.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED, Color.RED, Color.GREEN));
        //存取按鈕
        JPanel jPanel3 = new JPanel();
        JLabel jLabel2 = new JLabel("工具");
        String[] image2 = {"噴槍.png","毛筆.png", "橡皮擦.png","上一步.png","刷新.png"};
        //遍歷組裝圖形功能按鈕
        for (int i = 0; i < image2.length; i++) {
            //JButton圖片內(nèi)容
            JButton jbt = new JButton();
            ImageIcon icon = new ImageIcon(image2[i]);//實(shí)例化ImageIcon對象
            icon.setImage(icon.getImage().getScaledInstance(35,35,Image.SCALE_DEFAULT));//設(shè)置圖片大小與JButton大小匹配
            jbt.setIcon(icon);//加入JButton中
            //按鈕大小
            jbt.setPreferredSize(new Dimension(40,40));
            //設(shè)置監(jiān)聽器
            jbt.addActionListener(myMouseListener);
            //默認(rèn)邊框藍(lán)色
            jbt.setBorder(BorderFactory.createLineBorder(Color.CYAN, 2));
            jPanel3.add(jbt);
        }

        //Vbox用來處置組裝線條粗細(xì)按鈕
        Box vBox2 = Box.createVerticalBox();
        //線條粗細(xì)
        String[] stroke = {"stroke1.png","stroke2.png","stroke3.png","stroke4.png"};
        //遍歷設(shè)置監(jiān)聽和屬性
        for(int i = 0;i<stroke.length;i++){
            //JButton粗細(xì)內(nèi)容
            JButton jbt = new JButton();
            //實(shí)例化對象
            ImageIcon icon = new ImageIcon(stroke[i]);
            //設(shè)置圖片大小與JButton大小匹配 加入按鈕
            icon.setImage(icon.getImage().getScaledInstance(50,20,Image.SCALE_DEFAULT));
            jbt.setIcon(icon);
            //按鈕大小
            jbt.setPreferredSize(new Dimension(50,20));
            //監(jiān)聽
            jbt.addActionListener(myMouseListener);
            vBox2.add(jbt);
        }
        vBox2.add(jLabel2);
        //hBox.setSize(210,80);
        hBox.add(jPanel3);
        hBox.add(vBox2);
        //加入工具條
        this.add(hBox);
        for (int i = 0; i < 3; i++) {
            //設(shè)置間隔 美觀清晰
            this.addSeparator();
        }

        //設(shè)置背景顏色選擇按鈕
        JButton colorBack = new JButton(new ImageIcon("顏色.png"));
        colorBack.setBorder(BorderFactory.createLineBorder(Color.CYAN, 3));
        //設(shè)置監(jiān)聽
        colorBack.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //彈出顏色選擇器
                Color color =  JColorChooser.showDialog(jf,"背景顏色選擇器",Color.PINK);
                colorBack.setBorder(BorderFactory.createLineBorder(color, 3));
                //修改背景顏色 同時需要重畫
                jf.getContentPane().setBackground(color);
                jf.repaint();
            }
        });
        this.add(colorBack);

        //三行顏色選擇按鈕
        Box vBox3 = Box.createVerticalBox();
        //vBox3.setSize(new Dimension(150,75));
        //三個JPanel分別裝一行顏色按鈕
        JPanel jPanel6 = new JPanel();
        JPanel jPanel7 = new JPanel();
        JPanel jPanel8 = new JPanel();
        //創(chuàng)建畫筆顏色按鈕
        Color[] color = {Color.WHITE,Color.BLACK,Color.CYAN,Color.BLUE,Color.PINK,Color.RED,
                Color.ORANGE,Color.MAGENTA,Color.GREEN,Color.GRAY,Color.DARK_GRAY,Color.LIGHT_GRAY,
                Color.WHITE,Color.WHITE,Color.WHITE,Color.WHITE,Color.WHITE,Color.WHITE};
        //設(shè)置n個按鈕 這樣實(shí)例化為了后面改變顏色選擇按鈕顏色
        JButton jbt[] = new JButton[color.length];
        //遍歷組裝按鈕
        for (int i = 0; i < color.length; i++) {
            jbt[i] = new JButton(new ImageIcon(""));
            //按鈕大小
            jbt[i].setPreferredSize(new Dimension(25,25));
            //按鈕添加相應(yīng)背景色
            jbt[i].setBackground(color[i]);
            //監(jiān)聽點(diǎn)擊的背景色
            jbt[i].addActionListener(myMouseListener);
            if(i<6)  jPanel6.add(jbt[i]);
            else if(i<12) jPanel7.add(jbt[i]);
            else jPanel8.add(jbt[i]);
        }
        //將三個JPanel加入vBOX中
        vBox3.add(jPanel6);
        vBox3.add(jPanel7);
        vBox3.add(jPanel8);
        //設(shè)置邊框以及一些邊框?qū)傩?        vBox3.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.RED, Color.GREEN, Color.BLUE, Color.GRAY));
        //加入工具條
        this.add(vBox3);

        //設(shè)置背景顏色選擇按鈕
        JButton colorEdit = new JButton(new ImageIcon("編輯顏色.png"));
        colorEdit.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED, Color.RED, Color.GREEN));
        //設(shè)置監(jiān)聽
        colorEdit.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //彈出顏色選擇器
                Color color =  JColorChooser.showDialog(jf,"按鈕顏色編輯器",Color.PINK);
                //修改最后一行按鈕顏色
                if(num==18){//都已經(jīng)修改過 從頭開始
                    num = 12;
                    jbt[num++].setBackground(color);
                }
                else  jbt[num++].setBackground(color);
            }
        });
        //加入工具條
        this.add(colorEdit);

        //TODO 界面為什么會為空 在哪repaint解決
        //讓工具條可以拖動
        //this.setFloatable(true);

        //讓工具條不可以拖動
        this.setFloatable(false);
        //工具欄居上
        jf.add(this,BorderLayout.NORTH);
    }



    public MyFrame getJf() {
        return jf;
    }

    public void setJf(MyFrame jf) {
        this.jf = jf;
    }

    public MyMouseListener getMyMouseListener() {
        return myMouseListener;
    }

    public void setMyMouseListener(MyMouseListener myMouseListener) {
        this.myMouseListener = myMouseListener;
    }

    public ArrayList<String> getList() {
        return list;
    }

    public void setList(ArrayList<String> list) {
        this.list = list;
    }
}

4.MyMouseListener?監(jiān)聽器類

package com.zzu;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

class MyMouseListener extends MouseAdapter implements ActionListener {
    //記錄當(dāng)前所選顏色 默認(rèn)為藍(lán)色
    public Color color = Color.BLACK;

    //Point1 Point2
    public int x1=0,y1=0,x2=0,y2=0;

    //ployX,ployY是多邊形的第一個點(diǎn)
    public int ployX,ployY, ployX1, ployY1;

    //按鈕名稱 默認(rèn)為null 可直接畫曲線
    public String ActionCommand="";

    //判斷多邊形第一條邊是否畫出
    public boolean first;


    //毛筆模擬計(jì)時器 控制“墨汁”
    public int time,t;

//    //鼠標(biāo)是否是靜態(tài)
//    public int status;

    //毛筆是否已經(jīng)完成上一次畫線 默認(rèn)為真
    boolean last = true;

    //數(shù)據(jù)存儲
    public Vector<Shape> v = new Vector<>();

    //最多有四個shape(菱形四條邊)
    public Shape s=null;
    public Shape s1=null;
    public Shape s2=null;
    public Shape s3=null;

    //字體粗細(xì)
    public Stroke stroke = new BasicStroke(1);//默認(rèn)粗細(xì)為1

    //獲得容器
    private MyFrame myFrame;

    //實(shí)時畫圖
    private Graphics2D g;

    public MyMouseListener() {
    }

    public MyMouseListener(MyFrame myFrame, Graphics2D g) {
        this.myFrame = myFrame;
        this.g = g;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        g = (Graphics2D) myFrame.getGraphics();
        g.setXORMode(myFrame.getBackground());
        //獲取圖片名字
        JButton jButton = (JButton)e.getSource();
        String command = jButton.getIcon().toString();
        //此處防止上次的點(diǎn)干擾此次作圖
        x1=x2;
        y1=y2;
        if(command.equals("")){
            //提取顏色
            color = jButton.getBackground();
        }
        else if(command.equals("刷新.png")){
            //這里寫if可以保證多次刷新數(shù)據(jù)也不會丟失
            if(v.size()>0){
            //保留刷新前的點(diǎn) 避免回退什么也不打印
            Vector<Shape> v1 = new Vector<>(v);
            myFrame.setV1(v1);
            }
            //刪除所有點(diǎn)
            v.removeAllElements();
            //這里將back重置為false 不然會出現(xiàn)bug
            myFrame.setBack(false);
            myFrame.setV(v);
            myFrame.repaint();
        }
        else if (command.equals("上一步.png")) {
            int size = v.size();
            //有圖形則刪 無則不管
            if(size>0){
                v.remove(v.size()-1);
                myFrame.setV(v);
                myFrame.repaint();
            }
            else if(myFrame.getV1().size()>0){
                myFrame.setBack(true);
                myFrame.repaint();
            }
        }//字體粗細(xì) 并設(shè)置當(dāng)前畫筆粗細(xì)
        else if(command.equals("stroke1.png")){
            stroke = new BasicStroke(1);
            g.setStroke(stroke);
        }
        else if(command.equals("stroke2.png")){
            stroke = new BasicStroke(2);
            g.setStroke(stroke);
        }
        else if(command.equals("stroke3.png")){
            stroke = new BasicStroke(4);
            g.setStroke(stroke);
        }
        else if(command.equals("stroke4.png")){
            stroke = new BasicStroke(7);
            g.setStroke(stroke);
        }
        else{//橡皮擦就不要設(shè)置邊框了
            if(!command.equals("橡皮擦.png")){
                JButton jbt = (JButton) e.getSource();
                //設(shè)置邊框顏色 提醒畫筆顏色
                //將所選按鈕框改變?yōu)楫?dāng)前已選顏色
                jbt.setBorder(BorderFactory.createLineBorder(color, 2));
                jbt.setBackground(color);
            }
            //畫筆顏色
            g.setColor(color);
            //獲取圖形
            ActionCommand=command;
            if(ActionCommand.equals("多邊形.png")){
                //第一條邊未畫
                first = false;
            }
            else if(ActionCommand.equals("毛筆.png")) {
                //計(jì)時器0
                time = 0;
            }
        }
    }

    //得到按壓起點(diǎn)坐標(biāo)
    @Override
    public void mousePressed(MouseEvent e) {
        x1 = e.getX();
        y1 = e.getY();
    }
    //得到釋放終點(diǎn)坐標(biāo)
    @Override
    public void mouseReleased(MouseEvent e) {
        ployX1 = x2;
        ployY1 = y2;
        x2 = e.getX();
        y2 = e.getY();

        //如果released 那么毛筆墨汁刷新
        //計(jì)時器都刷新
        t=time=0;
        last = true;

        if(ActionCommand.equals("直角三角形.png")){
            Shape s = new Shape(x1,y1,x2,y2,color,"直線",stroke);
            v.addElement(s);
            g.drawLine(x1,y1,x2,y2);
            Shape s1 = new Shape(Math.min(x1,x2),Math.max(y1,y2),x1,y1,color,"直線",stroke);
            v.addElement(s1);
            g.drawLine(Math.min(x1,x2),Math.max(y1,y2),x1,y1);
            Shape s2 = new Shape(Math.min(x1,x2),Math.max(y1,y2),x2,y2,color,"直線",stroke);
            v.addElement(s2);
            g.drawLine(Math.min(x1,x2),Math.max(y1,y2),x2,y2);

        }
        else if(ActionCommand.equals("等腰三角形.png")){
            Shape s = new Shape(x1,y1,x2,y2,color,"直線",stroke);
            v.addElement(s);
            g.drawLine(x1,y1,x2,y2);
            Shape s1 = new Shape(2*x1-x2,y2,x1,y1,color,"直線",stroke);
            v.addElement(s1);
            g.drawLine(2*x1-x2,y2,x1,y1);
            Shape s2 = new Shape(2*x1-x2,y2,x2,y2,color,"直線",stroke);
            v.addElement(s2);
            g.drawLine(2*x1-x2,y2,x2,y2);
        }
        else if(ActionCommand.equals("菱形.png")){
            int x3 = (x1+x2)/2;
            int y3 = (y1+y2)/2;
            Shape s = new Shape(x1,y3,x3,y1,color,"直線",stroke);
            v.addElement(s);
            g.drawLine(x1,y3,x3,y1);
            Shape s1 = new Shape(x1,y3,x3,y2,color,"直線",stroke);
            v.addElement(s1);
            g.drawLine(x1,y3,x3,y2);
            Shape s2 = new Shape(x2,y3,x3,y1,color,"直線",stroke);
            v.addElement(s2);
            g.drawLine(x2,y3,x3,y1);
            Shape s3 = new Shape(x2,y3,x3,y2,color,"直線",stroke);
            v.addElement(s3);
            g.drawLine(x2,y3,x3,y2);
        }
        else if(ActionCommand.equals("空心矩形.png")){
            Shape s=new Shape(x1, y1, x2, y2,color,"空心矩形",stroke);
            v.addElement(s);
            g.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));
        }
        else if(ActionCommand.equals("實(shí)心矩形.png")){
            Shape s=new Shape(x1, y1, x2, y2,color,"實(shí)心矩形",stroke);
            v.addElement(s);
            g.fillRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));
        }
        else if(ActionCommand.equals("空心圓.png")){
            int r = (int)Math.sqrt(Math.pow(x1-x2,2)+Math.pow(y1-y2,2));//半徑
            Shape s=new Shape(x1, y1, r, r,color,"空心圓",stroke);
            v.addElement(s);
            g.drawOval(x1,y1,r,r);
        }
        else if(ActionCommand.equals("實(shí)心圓.png")){
            int r = (int)Math.sqrt(Math.pow(x1-x2,2)+Math.pow(y1-y2,2));//半徑
            Shape s=new Shape(x1, y1, r, r,color,"實(shí)心圓",stroke);
            v.addElement(s);
            g.fillOval(x1,y1,r,r);
        }
        else if(ActionCommand.equals("空心橢圓.png")){
            Shape s=new Shape(x1, y1, x2, y2,color,"空心橢圓",stroke);
            v.addElement(s);
            g.drawOval(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));
        }
        else if(ActionCommand.equals("實(shí)心橢圓.png")){
            Shape s=new Shape(x1, y1, x2, y2,color,"實(shí)心橢圓",stroke);
            v.addElement(s);
            g.fillOval(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));
        }
        else if(ActionCommand.equals("直線.png")) {
            Shape s=new Shape(x1, y1, x2, y2,color,"直線",stroke);
            v.addElement(s);
            g.drawLine(x1,y1,x2,y2);
        }
        else if(ActionCommand.equals("多邊形.png")&&!first){
            //存起始點(diǎn)
            ployX=x1;
            ployY=y1;
            Shape s=new Shape(x1, y1, x2, y2,color,"直線",stroke);
            v.addElement(s);
            //畫多邊形的第一條邊
            g.drawLine(x1,y1,x2,y2);
            first =true;
        }
        else if(ActionCommand.equals("多邊形.png")){
            //雙擊形成封閉圖形
            if(e.getClickCount()==2){
                Shape s=new Shape(x2, y2,ployX,ployY,color,"直線",stroke);
                v.addElement(s);
                //首尾點(diǎn)相連
                g.drawLine(x2, y2,ployX,ployY);
                first =false;
            }//否則繼續(xù)循序連接
            else {
                Shape s=new Shape(x1, y1, ployX1, ployY1,color,"直線",stroke);
                v.addElement(s);
                g.drawLine(x1, y1, ployX1, ployY1);
            }
        }

        myFrame.setV(v);
    }


    //監(jiān)視曲線 畫布 橡皮擦 噴槍
    //這里都是Point1->Point2 Point2更新 若干個Shape
    @Override
    public void mouseDragged(MouseEvent e) {
        g = (Graphics2D) myFrame.getGraphics();
        g.setColor(color);//畫筆顏色
        g.setStroke(stroke);//畫筆粗細(xì)
        ployX1 = x2;
        ployY1 = y2;
        x2 = e.getX();
        y2 = e.getY();
        if( ActionCommand.equals("曲線.png")||ActionCommand.equals("")){
            //添加若干條直線
            s=new Shape(x1, y1,x2, y2,color,"直線",stroke);
            v.addElement(s);
            g.drawLine(x1,y1,x2,y2);
            x1=x2;
            y1=y2;
        }
        else if( ActionCommand.equals("橡皮擦.png")){
            //區(qū)域添加背景色的圖形
            s=new Shape(x1, y1,x2, y2,UIManager.getColor("control"),"實(shí)心圓",stroke);
            g.setColor(UIManager.getColor("control"));
            v.addElement(s);
            g.drawLine(x1,y1,x2,y2);
            x1=x2;
            y1=y2;
        }
        else if( ActionCommand.equals("噴槍.png")){
            //隨機(jī)在區(qū)域內(nèi)畫線
            Random r=new Random();
            //遍歷隨機(jī)畫線
            for(int i=0;i<30;i++){
                int a=r.nextInt(20);
                int b=r.nextInt(20);
                s=new Shape(x1+a, y1+b,x2+a, y2+b,color,"直線",stroke);
                v.addElement(s);
                g.drawLine(x1+a,y1+b,x2+a,y2+b);
                x1=x2;
                y1=y2;
            }
        }
        else if( ActionCommand.equals("毛筆.png")){
            //隨機(jī)在區(qū)域內(nèi)畫線
            Random r=new Random();
            for(int i=0;i<60;i++){
                if(t<=15&&last){
                    int a=r.nextInt(20-t);//ab就當(dāng)成墨汁了
                    int b=r.nextInt(20-t);
                    s=new Shape(x1+a, y1+b,x2+a, y2+b,color,"直線",stroke);
                    v.addElement(s);
                    g.drawLine(x1+a,y1+b,x2+a,y2+b);
                    x1=x2;
                    y1=y2;
                    time++;//計(jì)時器++
                }else; //啥也不畫 沒墨汁了 再次press重畫獲得墨汁
            }
            //刷新t 墨汁變少
            t = time/1000;
        }

        myFrame.setV(v);
    }

    public MyFrame getMyFrame() {
        return myFrame;
    }

    public void setMyFrame(MyFrame myFrame) {
        this.myFrame = myFrame;
    }

    public Graphics2D getG() {
        return g;
    }

    public void setG(Graphics2D g) {
        this.g = g;
    }

}

5.MyFrame?類

package com.zzu;

import javax.swing.*;
import java.awt.*;
import java.util.*;

public class MyFrame extends JFrame {
    //所有數(shù)據(jù)存放至此 進(jìn)行repaint
    private Vector<Shape> v = new Vector<>(); //設(shè)置v和v1的目的 v和v1都有存儲圖形的功能 用于遍歷repaint
    private Vector<Shape> v1 = new Vector<>(); //另外我可以當(dāng)刷新時 將v的所有數(shù)據(jù)送給v1 回退時 我可以遍歷v1 不然會什么也不畫
    private boolean back = false; //是否滿足回退且v1不為空的條件
    private Image image;//文件中圖片
    private boolean ig;//保證圖片也能被刪除

    public MyFrame(){
    }

    public MyFrame(String title){
        //窗體名稱
        super(title);
        this.getContentPane().setBackground(new Color(204,255,204));
        //TODO 設(shè)置窗體圖標(biāo)
        try {
            ImageIcon icon = new ImageIcon("畫圖.png");
            Image image = icon.getImage();
            this.setIconImage(image);
        } catch (Exception e) {//跳出對話框提示
            JOptionPane.showMessageDialog(null, "圖標(biāo)異常");
        }
    }

    /**
     *
     * @param g the specified Graphics window
     *          重寫repaint方法
     */
    @Override
    public void paint(Graphics g) {
        //父類中的方法
        super.paint(g);
        //如果此時v1中有Shape 則說明已經(jīng)刷新了
        //判斷是否回退 回退則將這倆換一下 并且判定是否有圖片回退打印
        if(v1.size()>0) {
            ig = false;
            if(back){
                v.addAll(v1);
                v1.removeAllElements();
                //ig = true;
            }
        }
        Graphics2D g1 = (Graphics2D) g;
        //遍歷畫出內(nèi)容
        for (Shape type: v) {
            g1.setStroke(type.getStroke());//當(dāng)前圖形粗細(xì)
            g1.setColor(type.getColor());//當(dāng)前顏色
            int x1 = type.getX1();
            int y1 = type.getY1();
            int x2 = type.getX2();
            int y2 = type.getY2();
            //根據(jù)image選擇draw
            if(type.getImage().equals("空心圓")){//圓
                g1.drawOval(x1,y1,x2,y2);//這里x2=y2=r
            }
            else if(type.getImage().equals("實(shí)心圓")){//實(shí)心圓
                g1.fillOval(x1,y1,x2,y2);//這里x2=y2=r
            }
            else if(type.getImage().equals("空心橢圓")){//橢圓
                g1.drawOval(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));
            }
            else if(type.getImage().equals("實(shí)心橢圓")){//實(shí)心橢圓
                g1.fillOval(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));
            }
            else if (type.getImage().equals("空心矩形")) {//矩形
                //左上角坐標(biāo) 長寬
                g1.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));
            }
            else if (type.getImage().equals("實(shí)心矩形")){//實(shí)心矩形
                //左上角坐標(biāo) 長寬
                g1.fillRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));
            }
            else{//線(其他多邊形 曲線都是由若干條線組成的)
                g1.drawLine(x1,y1,x2,y2); //連接兩端點(diǎn)
            }
        }
        if(ig) g1.drawImage(image,this.getX()+200,this.getY()+200,this);
    }

    public Vector<Shape> getV() {
        return v;
    }

    public void setV(Vector<Shape> v) {
        this.v = v;
    }

    public Vector<Shape> getV1() {
        return v1;
    }
    public void setV1(Vector<Shape> v1) {
        this.v1 = v1;
    }

    public boolean isBack() {
        return back;
    }

    public void setBack(boolean back) {
        this.back = back;
    }

    public Image getImage() {
        return image;
    }

    public void setImage(Image image) {
        this.image = image;
    }

    public boolean isIg() {
        return ig;
    }

    public void setIg(boolean ig) {
        this.ig = ig;
    }
}

最終效果

用JAVA寫一個畫圖小程序(JAVA 大作業(yè))

程序所需圖片如下:

用JAVA寫一個畫圖小程序(JAVA 大作業(yè))

?這里要實(shí)現(xiàn)拉伸功能,大家可以去學(xué)一下GUI中的異或操作。

  • 面向?qū)ο?

設(shè)計(jì)

  1. 在問題領(lǐng)域中根據(jù)需求識別對象
  2. 將識別出的對象抽象為類
  3. 找出對象與對象之間的聯(lián)系
  4. 進(jìn)行類的設(shè)計(jì),屬性、方法、繼承等,建立類層次結(jié)構(gòu)
  5. 創(chuàng)建各類對象,傳遞參數(shù),調(diào)用類中方法,根據(jù)對象間的聯(lián)系,在主函數(shù)中展示組裝。

優(yōu)秀的面向?qū)ο缶幊?,合理的進(jìn)行類的設(shè)計(jì),各種抽象的類、接口,那是必不可少的。

優(yōu)勢

在此次程序,通過面向?qū)ο缶幊?,對于窗口的處理,我可以抽象出類來解決。我可以獨(dú)立的分成幾個類,分解若干個對象,描述事物在整個解決問題的步驟中的行為。我根據(jù)程序的目的,抽象出了菜單、工具欄、監(jiān)聽器、圖形、頂級容器類,通過創(chuàng)建他們的對象,關(guān)聯(lián)組裝,就可以完成這個程序設(shè)計(jì),并且層次較為清晰。

我目前沒有用面向過程的編程進(jìn)行過此類圖形化界面程序的實(shí)現(xiàn),但是也有寫過一次千行的大作業(yè),其中全是邏輯算法問題,單純各種函數(shù)的書寫,解決某一步的問題,與此程序書寫風(fēng)格大相徑庭。

因此通過此程序,也可以感受到面向?qū)ο蟮囊恍﹥?yōu)勢。也多少能體會到兩種編程的一些差別。用面向過程的語言書寫代碼,更偏向于順序完成,調(diào)用函數(shù)。面向?qū)ο缶团c此有大的差別,思路不同、解決方法的實(shí)現(xiàn)可能現(xiàn)在對我而言是差不多,但是解決方法的路徑與過程差距很大。

面向過程中的解決問題的方法主要是函數(shù),而面向?qū)ο笾饕穷悾ㄟ@是面向過程編程所不具備的),抽象成類,構(gòu)造類屬性、方法,創(chuàng)建對象,解決問題,且?guī)в嗅槍π浴?mark hidden color="red">文章來源:http://www.zghlxwxcb.cn/news/detail-475674.html

另外面向過程是一種以過程為中心的編程思想,缺點(diǎn)就是重用率低,擴(kuò)展能力差。而面向?qū)ο缶幊虅t更容易設(shè)計(jì)出清晰、耦合度低的系統(tǒng),并且便于程序修改更新。對我這個程序而言最關(guān)鍵的是易復(fù)用,可繼承,能更好的聯(lián)系,這同時也是面向?qū)ο缶幊痰囊恍﹥?yōu)勢。文章來源地址http://www.zghlxwxcb.cn/news/detail-475674.html

到了這里,關(guān)于用JAVA寫一個畫圖小程序(JAVA 大作業(yè))的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • shell第一次作業(yè)

    shell第一次作業(yè)

    1、判斷當(dāng)前磁盤剩余空間是否有20G,如果小于20G,則將報(bào)警郵件發(fā)送給管理員,每天檢查次磁盤剩余空間。 2、判斷web服務(wù)是否運(yùn)行 ? ?1、查看進(jìn)程的方式判斷該程序是否運(yùn)行, ? ?2、通過查看端口的方式判斷該程序是否運(yùn)行,如果沒有運(yùn)行,則啟動該服務(wù)并配置防火墻規(guī)

    2024年02月09日
    瀏覽(24)
  • 第一次作業(yè)

    第一次作業(yè)

    作業(yè)內(nèi)容:1,atd和crond的區(qū)別 ? ? ? ? ? ? ? ? ? 2,指定在2023/08/26 09:00將時間寫入testmail.txt文件中 ? ? ? ? ? ? ? ? ? 3,指定在每天凌晨4:00將該時間點(diǎn)之前的系統(tǒng)日志信息備份到個目錄下(/var/log/messages ),備份后日志文件名顯示格式logfileYY-MM-DD HH-MM 1、運(yùn)行方式不同

    2023年04月20日
    瀏覽(21)
  • docker第一次作業(yè)

    docker第一次作業(yè) 1.安裝docker服務(wù),配置鏡像加速器 ?yum install -y yum-utils device-mapper-persistent-data lvm2 y um-config-manager --add-repo https: //mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sed -i \\\'s+download.docker.com+mirrors.aliyun.com/docker-ce+\\\' ?/etc/yum.repos.d/docker-ce.repo yum makecache fast yum -y install docke

    2024年02月12日
    瀏覽(26)
  • Python第一次作業(yè)練習(xí)

    Python第一次作業(yè)練習(xí)

    ?輸入:101?-成績不及格/輸入錯誤(超過100)? 輸入:87?-成績良好 ? ? ?

    2024年02月09日
    瀏覽(26)
  • web集群第一次作業(yè)

    web集群第一次作業(yè)

    ?目錄 一. 簡述靜態(tài)網(wǎng)頁和動態(tài)網(wǎng)頁的區(qū)別 二. 簡述 Web1.0 和 Web2.0 的區(qū)別 三. 安裝tomcat8,配置服務(wù)啟動腳本,部署jpress應(yīng)用。 1. 首先,兩者的 頁面資源特征 不同: 靜態(tài)網(wǎng)頁處理文件類型有.html、.jpg、.gif、.mp4、.swf、.avi、.wmv、.flv等,而動態(tài)網(wǎng)頁后綴常見為.asp、.aspx、.php、

    2024年02月04日
    瀏覽(18)
  • 數(shù)據(jù)庫第一次作業(yè)

    數(shù)據(jù)庫第一次作業(yè)

    1.創(chuàng)建一個英雄表 create table t_hero ( ? ? ?id int primary key auto_increment, ? ? ?name varchar(10) unique not null, ? ? ?gender char(5) check (gender in (\\\'男\(zhòng)\\',\\\'女\\\')), ? ? ?grade char(5) default \\\'5星\\\', ? ? ?`groups` char(5) check (`groups` in (\\\'毀滅\\\',\\\'巡獵\\\',\\\'智識\\\',\\\'存護(hù)\\\',\\\'虛無\\\',\\\'豐饒\\\')), ? ? ?tel char(11) ? default \\\'

    2024年01月18日
    瀏覽(66)
  • 網(wǎng)絡(luò)安全第一次作業(yè)

    網(wǎng)絡(luò)安全第一次作業(yè)

    1、什么是防火墻 防火墻是一種網(wǎng)絡(luò)安全系統(tǒng),它根據(jù)預(yù)先確定的安全規(guī)則監(jiān)視和控制傳入和傳出的網(wǎng)絡(luò)流量。其主要目的是阻止對計(jì)算機(jī)或網(wǎng)絡(luò)的未經(jīng)授權(quán)的訪問,同時允許合法通信通過。 防火墻可以在硬件、軟件或兩者的組合中實(shí)現(xiàn),并且可以配置為根據(jù)各種條件(如

    2024年02月07日
    瀏覽(38)
  • 2023-5-6第一次創(chuàng)建博客的第一篇文章

    關(guān)于最近學(xué)習(xí)記下來的一些要點(diǎn)以及模糊的地方總結(jié) 對象類型和引用類型可以用鏈?zhǔn)浇Y(jié)構(gòu) 2進(jìn)制是toBinaryString 10進(jìn)制是Decimal 16進(jìn)制是toHexString 8進(jìn)制是octal final 1.修飾類 不能被繼承 2.修飾方法 不能被重寫,能被重載 3.修飾變量 值不可被重新賦值 屬性可以被修改 4.修飾引用數(shù)據(jù)

    2024年02月03日
    瀏覽(18)
  • 記第一次大作業(yè):校園導(dǎo)航系統(tǒng)

    記第一次大作業(yè):校園導(dǎo)航系統(tǒng)

    大二迎來了人生中的第一次大作業(yè),因?yàn)樯蟼€學(xué)期轉(zhuǎn)專業(yè)過來,學(xué)C的基礎(chǔ)不扎實(shí),湊巧這學(xué)期又初識了Java,可以算是我第一門系統(tǒng)學(xué)習(xí)的語言,本來是想用Java進(jìn)行設(shè)計(jì)的,沒想到我們的數(shù)據(jù)結(jié)構(gòu)老師十分的堅(jiān)持,一定要用C語言進(jìn)行實(shí)現(xiàn),那就沒辦法啦,就借著這個機(jī)會對

    2024年02月09日
    瀏覽(20)
  • 【網(wǎng)絡(luò)應(yīng)用與安全】第一次作業(yè)

    【網(wǎng)絡(luò)應(yīng)用與安全】第一次作業(yè)

    登錄賬號 登錄個人賬號,可以通過圖形界面和命令兩種方式。 圖形界面:當(dāng)前用戶 logout ,切換用戶,如果備選用戶中沒有自己的用戶名,點(diǎn)擊 not listed ,之后輸入用戶名和密碼登錄即可。 命令:使用 su your_username 方式,回車輸入密碼即可切換。 修改密碼 操作步驟 輸入

    2024年02月07日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包