一個用JAVA寫的畫圖程式
阿新 • • 發佈:2019-02-18
功能類似WINDOWS的畫圖程式,程式碼比較規範。對於剛剛接觸圖形介面開發的人很有幫助。(對我幫助也很大)
- import java.awt.*;
- import java.awt.event.*;
- import javax.swing.*;
- import java.io.*;
- //定義畫圖的基本圖形單元
- publicclass MiniDrawPad extends JFrame //主類,擴充套件了JFrame類,用來生成主介面
- {
- private ObjectInputStream input;
- private ObjectOutputStream output; //定義輸入輸出流,用來呼叫和儲存影象檔案
- private JButton choices[]; //按鈕陣列,存放以下名稱的功能按鈕
- private String names[] = {
- "New",
- "Open",
- "Save", //這三個是基本操作按鈕,包括"新建"、"開啟"、"儲存"
- /*接下來是我們的畫圖板上面有的基本的幾個繪圖單元按鈕*/
- "Pencil", //鉛筆畫,也就是用滑鼠拖動著隨意繪圖
- "Line", //繪製直線
- "Rect", //繪製空心矩形
- "fRect", //繪製以指定顏色填充的實心矩形
- "Oval", //繪製空心橢圓
- "fOval", //繪製以指定顏色填充的實心橢圓
- "Circle", //繪製圓形
- "fCircle", //繪製以指定顏色填充的實心圓形
- "RoundRect", //繪製空心圓角矩形
- "frRect", //繪製以指定顏色填充的實心圓角矩形
- "Rubber", //橡皮擦,可用來擦去已經繪製好的圖案
- "Color", //選擇顏色按鈕,可用來選擇需要的顏色
- "Stroke", //選擇線條粗細的按鈕,輸入需要的數值可以實現繪圖線條粗細的變化
- "Word"//輸入文字按鈕,可以在繪圖板上實現文字輸入
- };
- private String styleNames[] = {
- " 宋體 ", " 隸書 ", " 華文彩雲 ", " 仿宋_GB2312 ", " 華文行楷 ",
- " 方正舒體 ", " Times New Roman ", " Serif ", " Monospaced ",
- " SonsSerif ", " Garamond "
- }; //可供選擇的字型項
- //當然這裡的靈活的結構可以讓讀者自己隨意新增系統支援的字型
- private Icon items[];
- private String tipText[] = {
- //這裡是滑鼠移動到相應按鈕上面上停留時給出的提示說明條
- //讀者可以參照上面的按鈕定義對照著理解
- "Draw a new picture",
- "Open a saved picture",
- "Save current drawing",
- "Draw at will",
- "Draw a straight line",
- "Draw a rectangle",
- "Fill a ractangle",
- "Draw an oval",
- "Fill an oval",
- "Draw a circle",
- "Fill a circle",
- "Draw a round rectangle",
- "Fill a round rectangle",
- "Erase at will",
- "Choose current drawing color",
- "Set current drawing stroke",
- "Write down what u want"
- };
- JToolBar buttonPanel; //定義按鈕面板
- private JLabel statusBar; //顯示滑鼠狀態的提示條
- private DrawPanel drawingArea; //畫圖區域
- privateint width = 800, height = 550; //定義畫圖區域初始大小
- drawings[] itemList = new drawings[5000]; //用來存放基本圖形的陣列
- privateint currentChoice = 3; //設定預設畫圖狀態為隨筆畫
- int index = 0; //當前已經繪製的圖形數目
- private Color color = Color.black; //當前畫筆顏色
- int R, G, B; //用來存放當前色彩值
- int f1, f2; //用來存放當前字型風格
- String style1; //用來存放當前字型
- privatefloat stroke = 1.0f; //設定畫筆粗細,預設值為1.0f
- JCheckBox bold, italic; //定義字型風格選擇框
- //bold為粗體,italic為斜體,二者可以同時使用
- JComboBox styles;
- public MiniDrawPad() //建構函式
- {
- super("Drawing Pad");
- JMenuBar bar = new JMenuBar(); //定義選單條
- JMenu fileMenu = new JMenu("File");
- fileMenu.setMnemonic('F');
- //新建檔案選單條
- JMenuItem newItem = new JMenuItem("New");
- newItem.setMnemonic('N');
- newItem.addActionListener(
- new ActionListener() {
- publicvoid actionPerformed(ActionEvent e) {
- newFile(); //如果被觸發,則呼叫新建檔案函式段
- }
- });
- fileMenu.add(newItem);
- //儲存檔案選單項
- JMenuItem saveItem = new JMenuItem("Save");
- saveItem.setMnemonic('S');
- saveItem.addActionListener(
- new ActionListener() {
- publicvoid actionPerformed(ActionEvent e) {
- saveFile(); //如果被觸發,則呼叫儲存檔案函式段
- }
- });
- fileMenu.add(saveItem);
- //開啟檔案選單項
- JMenuItem loadItem = new JMenuItem("Load");
- loadItem.setMnemonic('L');
- loadItem.addActionListener(
- new ActionListener() {
- publicvoid actionPerformed(ActionEvent e) {
- loadFile(); //如果被觸發,則呼叫開啟檔案函式段
- }
- });
- fileMenu.add(loadItem);
- fileMenu.addSeparator();
- //退出選單項
- JMenuItem exitItem = new JMenuItem("Exit");
- exitItem.setMnemonic('X');
- exitItem.addActionListener(
- new ActionListener() {
- publicvoid actionPerformed(ActionEvent e) {
- System.exit(0); //如果被觸發,則退出畫圖板程式
- }
- });
- fileMenu.add(exitItem);
- bar.add(fileMenu);
- //設定顏色選單條
- JMenu colorMenu = new JMenu("Color");
- colorMenu.setMnemonic('C');
- //選擇顏色選單項
- JMenuItem colorItem = new JMenuItem("Choose Color");
- colorItem.setMnemonic('O');
- colorItem.addActionListener(
- new ActionListener() {
- publicvoid actionPerformed(ActionEvent e) {
- chooseColor(); //如果被觸發,則呼叫選擇顏色函式段
- }
- });
- colorMenu.add(colorItem);
- bar.add(colorMenu);
- //設定線條粗細選單條
- JMenu strokeMenu = new JMenu("Stroke");
- strokeMenu.setMnemonic('S');
- //設定線條粗細選單項
- JMenuItem strokeItem = new JMenuItem("Set Stroke");
- strokeItem.setMnemonic('K');
- strokeItem.addActionListener(
- new ActionListener() {
- publicvoid actionPerformed(ActionEvent e) {
- setStroke();
- }
- });
- strokeMenu.add(strokeItem);
- bar.add(strokeMenu);
- //設定提示選單條
- JMenu helpMenu = new JMenu("Help");
- helpMenu.setMnemonic('H');
- //設定提示選單項
- JMenuItem aboutItem = new JMenuItem("About this Drawing Pad!");
- aboutItem.setMnemonic('A');
- aboutItem.addActionListener(
- new ActionListener() {
- publicvoid actionPerformed(ActionEvent e) {
- JOptionPane.showMessageDialog(null,
- "This is a mini drawing pad!/nCopyright (c) 2002 Tsinghua University ",
- " 畫圖板程式說明 ",
- JOptionPane.INFORMATION_MESSAGE);
- }
- });
- helpMenu.add(aboutItem);
- bar.add(helpMenu);
- items = new ImageIcon[names.length];
- //建立各種基本圖形的按鈕
- drawingArea = new DrawPanel();
- choices = new JButton[names.length];
- buttonPanel = new JToolBar(JToolBar.VERTICAL);
- buttonPanel = new JToolBar(JToolBar.HORIZONTAL);
- ButtonHandler handler = new ButtonHandler();
- ButtonHandler1 handler1 = new ButtonHandler1();
- //匯入我們需要的圖形圖示,這些圖示都存放在與原始檔相同的目錄下面
- for (int i = 0; i < choices.length; i++) {//items[i]=new ImageIcon( MiniDrawPad.class.getResource(names[i] +".gif"));
- //如果在jbuilder下執行本程式,則應該用這條語句匯入圖片
- items[i] = new ImageIcon(names[i] + ".gif");
- //預設的在jdk或者jcreator下執行,用此語句匯入圖片
- choices[i] = new JButton("", items[i]);
- choices[i].setToolTipText(tipText[i]);
- buttonPanel.add(choices[i]);
- }
- //將動作偵聽器加入按鈕裡面
- for (int i = 3; i < choices.length - 3; i++) {
- choices[i].addActionListener(handler);
- }
- choices[0].addActionListener(
- new ActionListener() {
- publicvoid actionPerformed(ActionEvent e) {
- newFile();
- }
- });
- choices[1].addActionListener(
- new ActionListener() {
- publicvoid actionPerformed(ActionEvent e) {
- loadFile();
- }
- });
- choices[2].addActionListener(
- new ActionListener() {
- publicvoid actionPerformed(ActionEvent e) {
- saveFile();
- }
- });
- choices[choices.length - 3].addActionListener(handler1);
- choices[choices.length - 2].addActionListener(handler1);
- choices[choices.length - 1].addActionListener(handler1);
- //字型風格選擇
- styles = new JComboBox(styleNames);
- styles.setMaximumRowCount(8);
- styles.addItemListener(
- new ItemListener() {
- publicvoid itemStateChanged(ItemEvent e) {
- style1 = styleNames[styles.getSelectedIndex()];
- }
- });
- //字型選擇
- bold = new JCheckBox("BOLD");
- italic = new JCheckBox("ITALIC");
- checkBoxHandler cHandler = new checkBoxHandler();
- bold.addItemListener(cHandler);
- italic.addItemListener(cHandler);
- JPanel wordPanel = new JPanel();
- buttonPanel.add(bold);
- buttonPanel.add(italic);
- buttonPanel.add(styles);
- styles.setMinimumSize(new Dimension(50, 20));
- styles.setMaximumSize(new Dimension(100, 20));
- Container c = getContentPane();
- super.setJMenuBar(bar);
- c.add(buttonPanel, BorderLayout.NORTH);
- c.add(drawingArea, BorderLayout.CENTER);
- statusBar = new JLabel();
- c.add(statusBar, BorderLayout.SOUTH);
- statusBar.setText(" Welcome To The Little Drawing Pad!!! :)");
- createNewItem();
- setSize(width, height);
- show();
- }
- //按鈕偵聽器ButtonHanler類,內部類,用來偵聽基本按鈕的操作
- publicclass ButtonHandler implements ActionListener {
- publicvoid actionPerformed(ActionEvent e) {
- for (int j = 3; j < choices.length - 3; j++) {
- if (e.getSource() == choices[j]) {
- currentChoice = j;
- createNewItem();
- repaint();
- }
- }
- }
- }
- //按鈕偵聽器ButtonHanler1類,用來偵聽顏色選擇、畫筆粗細設定、文字輸入按鈕的操作
- publicclass ButtonHandler1 implements ActionListener {
- publicvoid actionPerformed(ActionEvent e) {
- if (e.getSource() == choices[choices.length - 3]) {
- chooseColor();
- }
- if (e.getSource() == choices[choices.length - 2]) {
- setStroke();
- }
- if (e.getSource() == choices[choices.length - 1]) {
- JOptionPane.showMessageDialog(null,
- "Please hit the drawing pad to choose the word input position",
- "Hint", JOptionPane.INFORMATION_MESSAGE);
- currentChoice = 14;
- createNewItem();
- repaint();
- }
- }
- }
- //滑鼠事件mouseA類,繼承了MouseAdapter,用來完成滑鼠相應事件操作
- class mouseA extends MouseAdapter {
- publicvoid mousePressed(MouseEvent e) {
- statusBar.setText(" Mouse Pressed @:[" + e.getX() +
- ", " + e.getY() + "]");//設定狀態提示
- itemList[index].x1 = itemList[index].x2 = e.getX();
- itemList[index].y1 = itemList[index].y2 = e.getY();
- //如果當前選擇的圖形是隨筆畫或者橡皮擦,則進行下面的操作
- if (currentChoice == 3 || currentChoice == 13) {
- itemList[index].x1 = itemList[index].x2 = e.getX();
- itemList[index].y1 = itemList[index].y2 = e.getY();
- index++;
- createNewItem();
- }
- //如果當前選擇的圖形式文字輸入,則進行下面操作
- if (currentChoice == 14) {
- itemList[index].x1 = e.getX();
- itemList[index].y1 = e.getY();
- String input;
- input = JOptionPane.showInputDialog(
- "Please input the text you want!");
- itemList[index].s1 = input;
- itemList[index].x2 = f1;
- itemList[index].y2 = f2;
- itemList[index].s2 = style1;
- index++;
- currentChoice = 14;
- createNewItem();
- drawingArea.repaint();
- }
- }
- publicvoid mouseReleased(MouseEvent e) {
- statusBar.setText(" Mouse Released @:[" + e.getX() +
- ", " + e.getY() + "]");
- if (currentChoice == 3 || currentChoice == 13) {
- itemList[index].x1 = e.getX();
- itemList[index].y1 = e.getY();
- }
- itemList[index].x2 = e.getX();
- itemList[index].y2 = e.getY();
- repaint();
- index++;
- createNewItem();
- }
- publicvoid mouseEntered(MouseEvent e) {
- statusBar.setText(" Mouse Entered @:[" + e.getX() +
- ", " + e.getY() + "]");
- }
- publicvoid mouseExited(MouseEvent e) {
- statusBar.setText(" Mouse Exited @:[" + e.getX() +
- ", " + e.getY() + "]");
- }
- }
- //滑鼠事件mouseB類繼承了MouseMotionAdapter,用來完成滑鼠拖動和滑鼠移動時的相應操作
- class mouseB extends MouseMotionAdapter {
- publicvoid mouseDragged(MouseEvent e) {
- statusBar.setText(" Mouse Dragged @:[" + e.getX() +
- ", " + e.getY() + "]");
- if (currentChoice == 3 || currentChoice == 13) {
- itemList[index - 1].x1 = itemList[index].x2 = itemList[index].x1 = e.getX();
- itemList[index - 1].y1 = itemList[index].y2 = itemList[index].y1 = e.getY();
- index++;
- createNewItem();
- } else {
- itemList[index].x2 = e.getX();
- itemList[index].y2 = e.getY();
- }
- repaint();
- }
- publicvoid mouseMoved(MouseEvent e) {
- statusBar.setText(" Mouse Moved @:[" + e.getX() +
- ", " + e.getY() + "]");
- }
- }
- //選擇字型風格時候用到的事件偵聽器類,加入到字型風格的選擇框中
- privateclass checkBoxHandler implements ItemListener {
- publicvoid itemStateChanged(ItemEvent e) {
- if (e.getSource() == bold) {
- if (e.getStateChange() == ItemEvent.SELECTED) {
- f1 = Font.BOLD;
- } else {
- f1 = Font.PLAIN;
- }
- }
- if (e.getSource() == italic) {
- if (e.getStateChange() == ItemEvent.SELECTED) {
- f2 = Font.ITALIC;
- } else {
- f2 = Font.PLAIN;
- }
- }
- }
- }
- //畫圖面板類,用來畫圖
- class DrawPanel extends JPanel {
- public DrawPanel() {
- setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
- setBackground(Color.white);
- addMouseListener(new mouseA());
- addMouseMotionListener(new mouseB());
- }
- @Override
- publicvoid paintComponent(Graphics g) {
- super.paintComponent(g);
- Graphics2D g2d = (Graphics2D) g; //定義畫筆
- int j = 0;
- while (j <= index) {
- draw(g2d, itemList[j]);
- j++;
- }
- }
- void draw(Graphics2D g2d, drawings i) {
- i.draw(g2d);//將畫筆傳入到各個子類中,用來完成各自的繪圖
- }
- }
- //新建一個畫圖基本單元物件的程式段
- void createNewItem() {
- if (currentChoice == 14)//進行相應的遊標設定
- {
- drawingArea.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
- } else {
- drawingArea.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
- }
- switch (currentChoice) {
- case3:
- itemList[index] = new Pencil();
- break;
- case4:
- itemList[index] = new Line();
- break;
- case5:
- itemList[index] = new Rect();
- break;
- case6:
- itemList[index] = new fillRect();
- break;
- case7:
- itemList[index] = new Oval();
- break;
- case8:
- itemList[index] = new fillOval();
- break;
- case9:
- itemList[index] = new Circle();
- break;
- case10:
- itemList[index] = new fillCircle();
- break;
- case11:
- itemList[index] = new RoundRect();
- break;
- case12:
- itemList[index] = new fillRoundRect();
- break;
- case13:
- itemList[index] = new Rubber();
- break;
- case14:
- itemList[index] = new Word();
- break;
- }
- itemList[index].type = currentChoice;
- itemList[index].R = R;
- itemList[index].G = G;
- itemList[index].B = B;
- itemList[index].stroke = stroke;
- }
- //選擇當前顏色程式段
- publicvoid chooseColor() {
- color = JColorChooser.showDialog(MiniDrawPad.this,
- "Choose a color", color);
- R = color.getRed();
- G = color.getGreen();
- B = color.getBlue();
- itemList[index].R = R;
- itemList[index].G = G;
- itemList[index].B = B;
- }
- //選擇當前線條粗細程式段
- publicvoid setStroke() {
- String input;
- input = JOptionPane.showInputDialog(
- "Please input a float stroke value! ( >0 )");
- stroke = Float.parseFloat(input);
- itemList[index].stroke = stroke;
- }
- //儲存圖形檔案程式段
- publicvoid saveFile() {
- JFileChooser fileChooser = new JFileChooser();
- fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
- int result = fileChooser.showSaveDialog(this);
- if (result == JFileChooser.CANCEL_OPTION) {
- return;
- }
- File fileName = fileChooser.getSelectedFile();
- fileName.canWrite();
- if (fileName == null || fileName.getName().equals("")) {
- JOptionPane.showMessageDialog(fileChooser, "Invalid File Name",
- "Invalid File Name", JOptionPane.ERROR_MESSAGE);
- } else {
- try {
- fileName.delete();
- FileOutputStream fos = new FileOutputStream(fileName);
- output = new ObjectOutputStream(fos);
- drawings record;
- output.writeInt(index);
- for (int i = 0; i < index; i++) {
- drawings p = itemList[i];
- output.writeObject(p);
- output.flush(); //將所有圖形資訊強制轉換成父類線性化儲存到檔案中
- }
- output.close();
- fos.close();
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- }
- //開啟一個圖形檔案程式段
- publicvoid loadFile() {
- JFileChooser fileChooser = new JFileChooser();
- fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
- int result = fileChooser.showOpenDialog(this);
- if (result == JFileChooser.CANCEL_OPTION) {
- return;
- }
- File fileName = fileChooser.getSelectedFile();
- fileName.canRead();
- if (fileName == null || fileName.getName().equals("")) {
- JOptionPane.showMessageDialog(fileChooser, "Invalid File Name",
- "Invalid File Name", JOptionPane.ERROR_MESSAGE);
- } else {
- try {
- FileInputStream fis = new FileInputStream(fileName);
- input = new ObjectInputStream(fis);
- drawings inputRecord;
- int countNumber = 0;
- countNumber = input.readInt();
- for (index = 0; index < countNumber; index++) {
- inputRecord = (drawings) input.readObject();
- itemList[index] = inputRecord;
- }
- createNewItem();
- input.close();
- repaint();
- } catch (EOFException endofFileException) {
- JOptionPane.showMessageDialog(this, "no more record in file",
- "class not found", JOptionPane.ERROR_MESSAGE);
- } catch (ClassNotFoundException classNotFoundException) {
- JOptionPane.showMessageDialog(this, "Unable to Create Object",
- "end of file", JOptionPane.ERROR_MESSAGE);
- } catch (IOException ioException) {
- JOptionPane.showMessageDialog(this, "error during read from file",
- "read Error", JOptionPane.ERROR_MESSAGE);
- }
- }
- }
- //新建一個檔案程式段
- publicvoid newFile() {
- index = 0;
- currentChoice = 3;
- color = Color.black;
- stroke = 1.0f;
- createNewItem();
- repaint();//將有關值設定為初始狀態,並且重畫
- }
- //主函式段
- publicstaticvoid main(String args[]) {
- try {
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- } catch (Exception e) {
- }//將介面設定為當前windows風格
- MiniDrawPad newPad = new MiniDrawPad();
- newPad.addWindowListener(
- new WindowAdapter() {
- publicvoid windowClosing(WindowEvent e) {
- System.exit(0);
- }
- });
- }
- }
- class drawings implements Serializable//父類,基本圖形單元,用到序列化介面,儲存時所用
- {
- int x1, y1, x2, y2; //定義座標屬性
- int R, G, B; //定義色彩屬性
- float stroke; //定義線條粗細屬性
- int type; //定義字型屬性
- String s1;
- String s2; //定義字型風格屬性
- void draw(Graphics2D g2d) {
- }
- ;//定義繪圖函式
- }
- /*******************************************************************************
- 下面是各種基本圖形單元的子類,都繼承自父類drawings,請仔細理解繼承的概念
- ********************************************************************************/
- class Line extends drawings //直線類
- {
- void draw(Graphics2D g2d) {
- g2d.setPaint(new Color(R, G, B));
- g2d.setStroke(new BasicStroke(stroke,
- BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
- g2d.drawLine(x1, y1, x2, y2);
- }
- }
- class Rect extends drawings//矩形類
- {
- void draw(Graphics2D g2d) {
- g2d.setPaint(new Color(R, G, B));
- g2d.setStroke(new BasicStroke(stroke));
- g2d.drawRect(Math.min(x1, x2), Math.min(y1, y2),
- Math.abs(x1 - x2), Math.abs(y1 - y2));
- }
- }
- class fillRect extends drawings//實心矩形類
- {
- void draw(Graphics2D g2d) {
- g2d.setPaint(new Color(R, G, B));
- g2d.setStroke(new BasicStroke(stroke));
- g2d.fillRect(Math.min(x1, x2), Math.min(y1, y2),
- Math.abs(x1 - x2), Math.abs(y1 - y2));
- }
- }
- class Oval extends drawings//橢圓類
- {
- void draw(Graphics2D g2d) {
- g2d.setPaint(new Color(R, G, B));
- g2d.setStroke(new BasicStroke(stroke));
- g2d.drawOval(Math.min(x1, x2), Math.min(y1, y2),
- Math.abs(x1 - x2), Math.abs(y1 - y2));
- }
- }
- class fillOval extends drawings//實心橢圓
- {
- void draw(Graphics2D g2d) {
- g2d.setPaint(new Color(R, G, B));
- g2d.setStroke(new BasicStroke(stroke));
- g2d.fillOval(Math.min(x1, x2), Math.min(y1, y2),
- Math.abs(x1 - x2), Math.abs(y1 - y2));
- }
- }
- class Circle extends drawings//圓類
- {
- void draw(Graphics2D g2d) {
- g2d.setPaint(new Color(R, G, B));
- g2d.setStroke(new BasicStroke(stroke));
- g2d.drawOval(Math.min(x1, x2), Math.min(y1, y2),
- Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)),
- Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)));
- }
- }
- class fillCircle extends drawings//實心圓
- {
- void draw(Graphics2D g2d) {
- g2d.setPaint(new Color(R, G, B));
- g2d.setStroke(new BasicStroke(stroke));
- g2d.fillOval(Math.min(x1, x2), Math.min(y1, y2),
- Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)),
- Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)));
- }
- }
- class RoundRect extends drawings//圓角矩形類
- {
- void draw(Graphics2D g2d) {
- g2d.setPaint(new Color(R, G, B));
- g2d.setStroke(new BasicStroke(stroke));
- g2d.drawRoundRect(Math.min(x1