Java版畫板的實(shí)現(xiàn)方法
Windows的畫圖板相信很多人都用過(guò),這次我們就來(lái)講講Java版本的簡(jiǎn)易畫板的實(shí)現(xiàn)。
基本的思路是這樣的:畫板實(shí)現(xiàn)大致分三部分:一是畫板界面的實(shí)現(xiàn),二是畫板的監(jiān)聽(tīng)以及畫圖的實(shí)現(xiàn),三是畫板的重繪。(文章較長(zhǎng),但是代碼是逐步遞進(jìn)的,可以按三部分分開(kāi)來(lái)看,實(shí)現(xiàn)了當(dāng)前部分再去看下一部分。)首先是畫板的界面實(shí)現(xiàn),因?yàn)槲覜](méi)有去找具體的圖標(biāo),界面上的所有組件都是Swing的自帶組件,所以界面略微有點(diǎn)簡(jiǎn)陋,不過(guò)如果想要優(yōu)化也簡(jiǎn)單,把界面上的組件都改成自定義的圖標(biāo)即可。界面實(shí)現(xiàn)后,就可以考慮給界面的組件加上監(jiān)聽(tīng),不同的圖形根據(jù)具體情況添加不同的監(jiān)聽(tīng)方法。然后編寫事件處理類依據(jù)不同的圖形編寫畫圖的具體算法。一個(gè)簡(jiǎn)易版本的畫圖板基本就差不多可以實(shí)現(xiàn)了。重繪這里先不提放到后面再講。
先來(lái)看看畫圖界面的實(shí)現(xiàn):
實(shí)現(xiàn)畫圖界面需要用的API類主要有:FlowLayout,GridLayout,Color,Dimension,JButton,JFrame,JPanel。
定義Draw類,讓Draw類繼承JFrame。設(shè)置它的大小,標(biāo)題,可見(jiàn)性等。需要注意的是這里如果添加的按鈕如果比較多,建議使用數(shù)組來(lái)完成按鈕的添加,因?yàn)槿绻苯右粋€(gè)一個(gè)的加按鈕,不僅會(huì)使得代碼量增大,而且不利于查找、添加和代碼的維護(hù)。為了使得界面不至于顯得那么簡(jiǎn)陋,這里使用了幾個(gè)Jpanel,和不同的布局管理器。主窗體使用的是流式布局管理器,然后使用三個(gè)面板,分別承裝圖形按鈕,顏色按鈕和畫布。承裝圖形按鈕和顏色按鈕的面板都使用表格布局。然后界面的實(shí)現(xiàn)就基本完成了。
package Cbs;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* Draw類,用于界面的初始化
* @author CBS
*/
@SuppressWarnings("serial")
public class Draw extends JFrame {
// 界面初始化方法
public void showUI() {
setTitle("畫圖");//窗體名稱
setSize(1200, 900);//窗體大小
setDefaultCloseOperation(3);
setLocationRelativeTo(null);//窗體居中
//流式布局左對(duì)齊
FlowLayout layout = new FlowLayout(FlowLayout.LEFT);
setLayout(layout);//窗體使用流式布局管理器
this.setResizable(false);//窗體大小不變
//使用數(shù)組保存按鈕名
String buttonName[] = { "畫直線", "畫橢圓", "畫曲線", "多邊形",
"橡皮擦", "拖動(dòng)線","三角形", "畫球形", "筆刷", "噴槍",
"色子", "立體矩形", "立體圓", "立體三角","迭代分形",
"現(xiàn)代分形", "楓葉", "畫樹(shù)", "mandelbrot集", "L-System",
"迭代畫線","迭代三角形", "謝爾賓斯基地毯", "畫字符", "清空",
"吸管" ,"矩形","五角星","多線","字符"};
//用于保存圖形按鈕,使用網(wǎng)格布局
JPanel jp1=new JPanel(new GridLayout(15, 2,10,10));
jp1.setPreferredSize(new Dimension(200, 800));
//循環(huán)為按鈕面板添加按鈕
for (int i = 0; i < buttonName.length; i++) {
JButton jbutton = new JButton(buttonName[i]);
jp1.add(jbutton);
}
JPanel jp2=new JPanel();//畫布面板
jp2.setPreferredSize(new Dimension(970, 800));
jp2.setBackground(Color.WHITE);
// 定義Color數(shù)組,用來(lái)存儲(chǔ)按鈕上要顯示的顏色信息
Color[] colorArray = { Color.BLUE, Color.GREEN, Color.RED,
Color.BLACK,Color.ORANGE,Color.PINK,Color.CYAN,
Color.MAGENTA,Color.DARK_GRAY,Color.GRAY,
Color.LIGHT_GRAY,Color.YELLOW};
//用于保存顏色按鈕的面板
JPanel jp3=newJPanel(newGridLayout(1,colorArray.length,3,3));
// 循環(huán)遍歷colorArray數(shù)組,根據(jù)數(shù)組中的元素來(lái)實(shí)例化按鈕對(duì)象
for (int i = 0; i < colorArray.length; i++) {
JButton button = new JButton();
button.setBackground(colorArray[i]);
button.setPreferredSize(new Dimension(30, 30));
jp3.add(button);
}
//將面板添加到主窗體
this.add(jp1);
this.add(jp2);
this.add(jp3);
//添加按鈕,作為當(dāng)前顏色
JButton nowColor=new JButton();
nowColor.setPreferredSize(new Dimension(40,40));
nowColor.setBackground(Color.BLACK);//默認(rèn)黑色
add(nowColor);
//設(shè)置窗體的組件可見(jiàn),如果為FALSE就看不到任何組件
setVisible(true);
}
}
這里還要一點(diǎn)要注意的地方,Jpanel面板的添加先后順序不要改變,這是根據(jù)流式布局算出來(lái)的面板大小,讀者可以自行更改調(diào)試。還有一個(gè)就是窗體的setSize方法只對(duì)窗體本身有效,如果要改變其他組件的大小要用setPreferredSize方法。這樣畫圖板的基本界面就實(shí)現(xiàn)。界面的按鈕和面板可以根據(jù)自身需要更改。
這是界面的大概樣子:

監(jiān)聽(tīng)的實(shí)現(xiàn):
當(dāng)然我們空有個(gè)界面并沒(méi)有什么用,我們需要的是點(diǎn)擊不同的按鈕能夠?qū)崿F(xiàn)不同的功能。這里就需要用到事件的監(jiān)聽(tīng)機(jī)制了。實(shí)現(xiàn)監(jiān)聽(tīng)的主要API類有: ActionListener,MouseListener,MouseMotionListener。添加事件監(jiān)聽(tīng)的方法根以前的步驟是一樣的:確定事件源對(duì)象,編寫事件處理類,添加監(jiān)聽(tīng)方法。畫圖板中的事件源對(duì)象有兩種,一種是按鈕,另一種就是畫布的面板,按鈕使用的是ActionListener,而畫布面板因?yàn)樨?fù)責(zé)的是繪圖,所以使用的是MouseListener和MouseMotionListener。為了實(shí)現(xiàn)事件的監(jiān)聽(tīng),我們需要定義一個(gè)事件處理類DrawListener,該類實(shí)現(xiàn)了以上的三個(gè)事件接口。之后在重寫的方法中實(shí)現(xiàn)不同圖形的繪制。圖形的繪制都可以通過(guò)Graphics對(duì)象的方法來(lái)實(shí)現(xiàn)。但是這里有一個(gè)問(wèn)題,如何分辨在Draw類中按下的是哪個(gè)按鈕呢?在定義Draw類的時(shí)候,我們使用了圖形按鈕和顏色按鈕,圖形類的按鈕在實(shí)例化對(duì)象的時(shí)候是使用了帶參數(shù)的構(gòu)造方法的,也就是圖形按鈕都是有文字的,而顏色按鈕則沒(méi)有。依據(jù)這一點(diǎn)就可以很容易的區(qū)分不同的按鈕了。
DrawListener類:
package Cbs;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JButton;
public class DrawListener implements ActionListener, MouseListener,
MouseMotionListener {
private Color color;//顏色屬性
private Graphics g;//畫筆屬性
private String str;//保存按鈕上的字符串,區(qū)分不同的按鈕
private int x1,y1,x2,y2;//(x1,y1),(x2,y2)分別為鼠標(biāo)的按下和釋放時(shí)的坐標(biāo)
private JButton nowColor;//當(dāng)前顏色按鈕
//獲取Draw類的畫筆對(duì)象
public void setG(Graphics g) {
this.g = g;
}
//獲取當(dāng)前顏色按鈕
public void setNowColor(JButton nowColor) {
this.nowColor = nowColor;
}
@Override
//鼠標(biāo)拖動(dòng)的方法
public void mouseDragged(MouseEvent e) {
//畫曲線的方法
if ("畫曲線".equals(str)) {
int x, y;
x = e.getX();
y = e.getY();
g.drawLine(x, y, x1, y1);
x1 = x;
y1 = y;
}
}
@Override
//鼠標(biāo)移動(dòng)方法
public void mouseMoved(MouseEvent e) {
}
@Override
//鼠標(biāo)單擊方法
public void mouseClicked(MouseEvent e) {
}
@Override
//鼠標(biāo)按下方法
public void mousePressed(MouseEvent e) {
g.setColor(color);//改變畫筆的顏色
x1=e.getX();//獲取按下時(shí)鼠標(biāo)的x坐標(biāo)
y1=e.getY();//獲取按下時(shí)鼠標(biāo)的y坐標(biāo)
}
@Override
//鼠標(biāo)釋放方法
public void mouseReleased(MouseEvent e) {
x2=e.getX();//獲取釋放時(shí)鼠標(biāo)的x坐標(biāo)
y2=e.getY();//獲取釋放時(shí)鼠標(biāo)的y坐標(biāo)
//畫直線的方法
if ("畫直線".equals(str)) {
g.drawLine(x1, y1, x2, y2);
}
}
@Override
//鼠標(biāo)進(jìn)入方法
public void mouseEntered(MouseEvent e) {
}
@Override
//鼠標(biāo)退出方法
public void mouseExited(MouseEvent e) {
}
@Override
//處理按鈕上的鼠標(biāo)點(diǎn)擊動(dòng)作
public void actionPerformed(ActionEvent e) {
//判斷是顏色按鈕還是圖形按鈕
if ("".equals(e.getActionCommand())) {
JButton jb = (JButton) e.getSource();
color = jb.getBackground();
nowColor.setBackground(color);//處理當(dāng)前顏色
} else {
str = e.getActionCommand();
}
}
}
Draw類也要做一些修改,為按鈕和面板添加監(jiān)聽(tīng):
package Cbs;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* Draw類,用于界面的初始化
* @author CBS
*/
@SuppressWarnings("serial")
public class Draw extends JFrame {
private DrawListener dl;
private Graphics g;
// 界面初始化方法
public void showUI() {
setTitle("畫圖");//窗體名稱
setSize(1200, 900);//窗體大小
setDefaultCloseOperation(3);
setLocationRelativeTo(null);//窗體居中
//流式布局左對(duì)齊
FlowLayout layout = new FlowLayout(FlowLayout.LEFT);
setLayout(layout);//窗體使用流式布局管理器
this.setResizable(false);//窗體大小不變
//使用數(shù)組保存按鈕名
String buttonName[] = { "畫直線", "畫橢圓", "畫曲線", "多邊形",
"橡皮擦", "拖動(dòng)線","三角形", "畫球形", "筆刷", "噴槍",
"色子", "立體矩形", "立體圓", "立體三角","迭代分形",
"現(xiàn)代分形", "楓葉", "畫樹(shù)", "mandelbrot集", "L-System",
"迭代畫線","迭代三角形", "謝爾賓斯基地毯", "畫字符", "清空",
"吸管" ,"矩形","五角星","多線","字符"};
//用于保存圖形按鈕,使用網(wǎng)格布局
JPanel jp1=new JPanel(new GridLayout(15, 2,10,10));
jp1.setPreferredSize(new Dimension(200, 800));
//實(shí)例化DrawListener對(duì)象
dl=new DrawListener();
//循環(huán)為按鈕面板添加按鈕
for (int i = 0; i < buttonName.length; i++) {
JButton jbutton = new JButton(buttonName[i]);
jbutton.addActionListener(dl);//為按鈕添加監(jiān)聽(tīng)
jp1.add(jbutton);
}
JPanel jp2=new JPanel();//畫布面板
jp2.setPreferredSize(new Dimension(970, 800));
jp2.setBackground(Color.WHITE);
// 定義Color數(shù)組,用來(lái)存儲(chǔ)按鈕上要顯示的顏色信息
Color[] colorArray = { Color.BLUE, Color.GREEN,
Color.RED, Color.BLACK,Color.ORANGE,Color.PINK,Color.CYAN,
Color.MAGENTA,Color.DARK_GRAY,Color.GRAY,Color.LIGHT_GRAY,
Color.YELLOW};
//用于保存顏色按鈕的面板
JPanel jp3=new JPanel(new GridLayout(1,colorArray.length,3,3));
// 循環(huán)遍歷colorArray數(shù)組,根據(jù)數(shù)組中的元素來(lái)實(shí)例化按鈕對(duì)象
for (int i = 0; i < colorArray.length; i++) {
JButton button = new JButton();
button.setBackground(colorArray[i]);
button.setPreferredSize(new Dimension(30, 30));
button.addActionListener(dl);//為按鈕添加監(jiān)聽(tīng)
jp3.add(button);
}
//將面板添加到主窗體
this.add(jp1);
this.add(jp2);
this.add(jp3);
//添加按鈕,作為當(dāng)前顏色
JButton nowColor=new JButton();
nowColor.setPreferredSize(new Dimension(40,40));
nowColor.setBackground(Color.BLACK);//默認(rèn)黑色
add(nowColor);
//設(shè)置窗體的組件可見(jiàn),如果為FALSE就看不到任何組件
setVisible(true);
//獲取畫筆對(duì)象
g=jp2.getGraphics();
dl.setG(g);
dl.setNowColor(nowColor);
//為面板添加鼠標(biāo)監(jiān)聽(tīng),用于繪制圖形
jp2.addMouseListener(dl);
jp2.addMouseMotionListener(dl);
}
}
drawDrawListener里面只寫了畫直線和曲線的方法,讀者可以根據(jù)自己的需求添加,思路和方式都是一樣的。Draw類里面有些需要注意的地方在這里提一下:一個(gè)是畫筆g的獲取一定要在窗體的可見(jiàn)之后采取獲取,不然獲取的畫筆對(duì)象返回值會(huì)是null。二是要為圖形按鈕添加監(jiān)聽(tīng),DrawListener的實(shí)例化需要在setVisible方法之前,所以不建議使用構(gòu)造方法直接傳入g畫筆參數(shù),我使用的是set方法。最后是注意一下使用哪個(gè)添加方法,按鈕使用的是addActionListener方法,畫板面板使用的是addMouseListener和addMouseMotionListener方法。使用畫板面板來(lái)獲取畫筆并給畫面面板添加監(jiān)聽(tīng)是為了讓繪圖的時(shí)候圖形不會(huì)跑出面板外,這里的畫筆和監(jiān)聽(tīng)都由主窗體獲得也是可以的,不過(guò)繪制時(shí)會(huì)出現(xiàn)線畫出面板的問(wèn)題。
畫板的重繪:
到這里畫板的制作已經(jīng)基本實(shí)現(xiàn)了,我們已經(jīng)可以在上面繪制各種各樣的圖形了。但是細(xì)心的人可能會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題,那就是如果把窗體最小化之后再次打開(kāi),畫板上原本已經(jīng)畫好的東西會(huì)全部都消失了。這樣子肯定是不行的,辛辛苦苦畫的“大作”怎么能說(shuō)說(shuō)沒(méi)就沒(méi)了呢。那么為什么會(huì)出現(xiàn)這樣的問(wèn)題呢?要回答這個(gè)問(wèn)題我們就需要先了解Java的繪圖機(jī)制。做畫圖板我們使用的是Swing組件,這套組件是基于原先的AWT組件開(kāi)發(fā),在繪制的時(shí)候會(huì)調(diào)用系統(tǒng)的畫圖函數(shù),這就是為什么我們可以從面板或者是窗體中獲取畫筆對(duì)象的原因。這也就是說(shuō)Java中你所能夠看到窗體,按鈕或者其它的所有組件其實(shí)都是畫出來(lái)。所以當(dāng)我們點(diǎn)擊窗體使它最小化或者改變大小的時(shí)候,原來(lái)的畫的窗體就不能適應(yīng)需要了,這時(shí)系統(tǒng)會(huì)調(diào)用JFrame的paint方法實(shí)現(xiàn)窗體的重繪,也就是再次畫了一個(gè)新的窗體,而JFrame的paint方法只對(duì)窗體已經(jīng)添加的組件有效,我們自己繪制的東西并沒(méi)有寫在paint方法里面,所以窗體重繪之后,我們?cè)壤L制的圖形也就消失了。要解決這個(gè)問(wèn)題我們需要重寫父類的paint方法。但是這樣的話問(wèn)題又來(lái)了,畫圖是在DrawListener類里面實(shí)現(xiàn)的,要怎么把它們弄到paint方法里面去呢?
當(dāng)然方法可能有很多,這里我只介紹我所知道的:要把畫出來(lái)的圖形在paint方法中再次畫出來(lái),就需要有東西來(lái)保存畫過(guò)的圖形。保存可以使用數(shù)組或者集合,這里推薦使用集合,可以很方便的實(shí)現(xiàn)添加,而不需要去考慮大小的問(wèn)題。數(shù)組的實(shí)現(xiàn)也大同小異,這里就不多做介紹。確定了使用集合,那么集合內(nèi)保存什么類型的數(shù)據(jù)呢?毫無(wú)疑問(wèn)應(yīng)該保存的是圖形的數(shù)據(jù),但是集合使用泛型的話也只能保存同一種類型的數(shù)據(jù),我們卻有那么多種圖形?這里就可以使用接口或者抽象類,我們只需要?jiǎng)?chuàng)建不同得圖形類,讓它繼承抽象類或者是實(shí)現(xiàn)接口。然后每畫一個(gè)圖形就實(shí)例化一個(gè)圖形的對(duì)象,存入集合中,最后在paint方法中遍歷集合,重新繪制圖形即可。
下面直接貼最終代碼(仍然只寫了直線和曲線),只是添加了幾行代碼,注意與前面比較。
//圖形接口
package Cbs;
//圖形集合
public interface NetJavaShape {
public abstract void draw();
}
//直線類
package Cbs;
import java.awt.Color;
import java.awt.Graphics;
import Cbs.NetJavaShape;
public class ImpLine implements NetJavaShape{
Graphics g;
int x1, y1,x2, y2;
Color c;
public ImpLine(Graphics g,int x1,int y1,int x2,int y2,Color c){
this.g=g;
this.c=c;
this.x1=x1;
this.y1=y1;
this.x2=x2;
this.y2=y2;
}
public void draw() {
g.setColor(c);
g.drawLine(x1, y1, x2, y2);
}
}
//DrawListener類
package Cbs;
import java.awt.Color;
import java.awt.Graphics;
import java.util.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import Cbs.NetJavaShape;
import javax.swing.JButton;
public class DrawListener implements ActionListener, MouseListener,
MouseMotionListener {
private Color color=Color.BLACK;//顏色屬性,初始值為黑色
private Graphics g;//畫筆屬性
private String str;//保存按鈕上的字符串,區(qū)分不同的按鈕
private int x1,y1,x2,y2;//(x1,y1),(x2,y2)分別為鼠標(biāo)的按下和釋放時(shí)的坐標(biāo)
private JButton nowColor;//當(dāng)前顏色按鈕
//保存圖形對(duì)象的集合
private List<NetJavaShape> shapesArray = new ArrayList<NetJavaShape>();
//圖形
private NetJavaShape shape;
//在draw類中獲取集合
public List<NetJavaShape> getShapesArray() {
return shapesArray;
}
//獲取Draw類的畫筆對(duì)象
public void setG(Graphics g) {
this.g = g;
}
//獲取當(dāng)前顏色按鈕
public void setNowColor(JButton nowColor) {
this.nowColor = nowColor;
}
@Override
//鼠標(biāo)拖動(dòng)的方法
public void mouseDragged(MouseEvent e) {
//畫曲線的方法
if ("畫曲線".equals(str)) {
int x, y;
x = e.getX();
y = e.getY();
//實(shí)例化對(duì)象,曲線也是直線畫的所以不同新建一個(gè)曲線類了
shape=new ImpLine(g,x,y,x1,y1,color);
//調(diào)用畫圖方法
shape.draw();
//將圖形存入集合中
shapesArray.add(shape);
// g.drawLine(x, y, x1, y1);
x1 = x;
y1 = y;
}
}
@Override
//鼠標(biāo)移動(dòng)方法
public void mouseMoved(MouseEvent e) {
}
@Override
//鼠標(biāo)單擊方法
public void mouseClicked(MouseEvent e) {
}
@Override
//鼠標(biāo)按下方法
public void mousePressed(MouseEvent e) {
g.setColor(color);//改變畫筆的顏色
x1=e.getX();//獲取按下時(shí)鼠標(biāo)的x坐標(biāo)
y1=e.getY();//獲取按下時(shí)鼠標(biāo)的y坐標(biāo)
}
@Override
//鼠標(biāo)釋放方法
public void mouseReleased(MouseEvent e) {
x2=e.getX();//獲取釋放時(shí)鼠標(biāo)的x坐標(biāo)
y2=e.getY();//獲取釋放時(shí)鼠標(biāo)的y坐標(biāo)
//畫直線的方法
if ("畫直線".equals(str)) {
//實(shí)例化對(duì)象,
shape=new ImpLine(g,x1,y1,x2,y2,color);
//調(diào)用畫圖方法
shape.draw();
//將圖形存入集合中
shapesArray.add(shape);
// g.drawLine(x1, y1, x2, y2);
}
}
@Override
//鼠標(biāo)進(jìn)入方法
public void mouseEntered(MouseEvent e) {
}
@Override
//鼠標(biāo)退出方法
public void mouseExited(MouseEvent e) {
}
@Override
//處理按鈕上的鼠標(biāo)點(diǎn)擊動(dòng)作
public void actionPerformed(ActionEvent e) {
if ("".equals(e.getActionCommand())) {
JButton jb = (JButton) e.getSource();
color = jb.getBackground();
nowColor.setBackground(color);//處理當(dāng)前顏色
} else {
str = e.getActionCommand();
}
}
}
//draw類
package Cbs;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* Draw類,用于界面的初始化
* @author CBS
*/
@SuppressWarnings("serial")
public class Draw extends JFrame {
private DrawListener dl;
private Graphics g;
//保存圖形對(duì)象的集合
private List<NetJavaShape> shapesArray = new ArrayList<NetJavaShape>();
// 界面初始化方法
public void showUI() {
setTitle("畫圖");//窗體名稱
setSize(1200, 900);//窗體大小
setDefaultCloseOperation(3);
setLocationRelativeTo(null);//窗體居中
FlowLayout layout = new FlowLayout(FlowLayout.LEFT);//流式布局左對(duì)齊
setLayout(layout);//窗體使用流式布局管理器
this.setResizable(false);//窗體大小不變
//使用數(shù)組保存按鈕名
String buttonName[] = { "畫直線", "畫橢圓", "畫曲線", "多邊形", "橡皮擦", "拖動(dòng)線","三角形", "畫球形", "筆刷", "噴槍", "色子", "立體矩形", "立體圓", "立體三角","迭代分形", "現(xiàn)代分形", "楓葉", "畫樹(shù)", "mandelbrot集", "L-System", "迭代畫線","迭代三角形", "謝爾賓斯基地毯", "畫字符", "清空","吸管" ,"矩形","五角星","多線","字符"};
JPanel jp1=new JPanel(new GridLayout(15, 2,10,10));//用于保存圖形按鈕,使用網(wǎng)格布局
jp1.setPreferredSize(new Dimension(200, 800));
//實(shí)例化DrawListener對(duì)象
dl=new DrawListener();
//循環(huán)為按鈕面板添加按鈕
for (int i = 0; i < buttonName.length; i++) {
JButton jbutton = new JButton(buttonName[i]);
jbutton.addActionListener(dl);//為按鈕添加監(jiān)聽(tīng)
jp1.add(jbutton);
}
JPanel jp2=new JPanel();//畫布面板
jp2.setPreferredSize(new Dimension(970, 800));
jp2.setBackground(Color.WHITE);
// 定義Color數(shù)組,用來(lái)存儲(chǔ)按鈕上要顯示的顏色信息
Color[] colorArray = { Color.BLUE, Color.GREEN, Color.RED, Color.BLACK,Color.ORANGE,Color.PINK,Color.CYAN,Color.MAGENTA,Color.DARK_GRAY,Color.GRAY,Color.LIGHT_GRAY,Color.YELLOW};
//用于保存顏色按鈕的面板
JPanel jp3=new JPanel(new GridLayout(1,colorArray.length,3,3));
// 循環(huán)遍歷colorArray數(shù)組,根據(jù)數(shù)組中的元素來(lái)實(shí)例化按鈕對(duì)象
for (int i = 0; i < colorArray.length; i++) {
JButton button = new JButton();
button.setBackground(colorArray[i]);
button.setPreferredSize(new Dimension(30, 30));
button.addActionListener(dl);//為按鈕添加監(jiān)聽(tīng)
jp3.add(button);
}
//將面板添加到主窗體
this.add(jp1);
this.add(jp2);
this.add(jp3);
//添加按鈕,作為當(dāng)前顏色
JButton nowColor=new JButton();
nowColor.setPreferredSize(new Dimension(40,40));
nowColor.setBackground(Color.BLACK);//默認(rèn)黑色
add(nowColor);
//設(shè)置窗體的組件可見(jiàn),如果為FALSE就看不到任何組件
setVisible(true);
//獲取畫筆對(duì)象
g=jp2.getGraphics();
dl.setG(g);
dl.setNowColor(nowColor);
//獲取保存的集合
shapesArray=dl.getShapesArray();
//為面板添加鼠標(biāo)監(jiān)聽(tīng),用于繪制圖形
jp2.addMouseListener(dl);
jp2.addMouseMotionListener(dl);
}
@Override
//重寫paint方法
public void paint(Graphics g) {
//調(diào)用父類的paint方法,繪制界面上的組件
super.paint(g);
//foreach遍歷集合
for (NetJavaShape l : shapesArray) {
l.draw();
}
}
}
這里使用集合添加圖形實(shí)現(xiàn)畫板的重繪時(shí),我是每實(shí)現(xiàn)一個(gè)圖形就會(huì)新建一個(gè)類來(lái)保存圖形的信息,這樣圖形類就會(huì)有很多。如果不想創(chuàng)建那么多的圖形類可以把它們都放到一個(gè)類里面,設(shè)置一個(gè)type的參數(shù),賦上按鈕的名稱。然后在draw方法中依據(jù)這個(gè)值判斷是什么圖形實(shí)現(xiàn)不同的畫圖方法。這樣畫板的所有功能基本就實(shí)現(xiàn)了,畫板的項(xiàng)目也就到這里。
總結(jié):
畫圖板的制作重要用到了Swing的組件,事件監(jiān)聽(tīng)機(jī)制,Graphics繪圖和畫板的重繪以及集合的使用,抽象類或者是接口作為規(guī)范圖形類的作用。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
java獲取文件擴(kuò)展名的方法小結(jié)【正則與字符串截取】
這篇文章主要介紹了java獲取文件擴(kuò)展名的方法,結(jié)合實(shí)例形式分析了使用正則與字符串截取兩種獲取擴(kuò)展名的操作技巧,需要的朋友可以參考下2017-01-01
Java使用Kaptcha實(shí)現(xiàn)簡(jiǎn)單的驗(yàn)證碼生成器
這篇文章主要為大家詳細(xì)介紹了Java如何使用Kaptcha實(shí)現(xiàn)簡(jiǎn)單的驗(yàn)證碼生成器,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考下2024-02-02
WPF實(shí)現(xiàn)自定義一個(gè)自刪除的多功能ListBox
這篇文章主要為大家詳細(xì)介紹了如何利用WPF實(shí)現(xiàn)自定義一個(gè)自刪除的多功能ListBox,文中示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-12-12
Java實(shí)現(xiàn)添加文字水印和圖片水印功能
為圖片添加水印是一種常用的圖片處理技術(shù),本文主要介紹了Java實(shí)現(xiàn)添加文字水印和圖片水印功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
SpringBoot之groups應(yīng)對(duì)不同的Validation規(guī)則自定義方式
這篇文章主要介紹了SpringBoot之groups應(yīng)對(duì)不同的Validation規(guī)則自定義方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
MyBatis中常見(jiàn)的SQL執(zhí)行方式及其使用方法
MyBatis可能很多人都一直在用,但是MyBatis的SQL執(zhí)行流程可能并不是所有人都清楚了,下面這篇文章主要給大家介紹了關(guān)于MyBatis中常見(jiàn)的SQL執(zhí)行方式及其使用的相關(guān)資料,需要的朋友可以參考下2023-09-09
使用Eclipse開(kāi)發(fā)工具如何解決Java Compiler中Annotation Processin不出現(xiàn)的問(wèn)題
這篇文章主要介紹了使用Eclipse開(kāi)發(fā)工具如何解決Java Compiler中Annotation Processin不出現(xiàn)的相關(guān)資料,需要的朋友可以參考下2015-11-11

