Swing界面實現畫圖板
最近幾天在藍傑集訓,編寫了一個簡單的畫圖板。
實現畫圖板,首先需要創建一個繼承JFrame的類,用這個類中父類的方法創建一個窗體並添加按鍵,爲窗體和上面的按鍵添加監聽器(監聽器繼承了接口Mouselistener、MouseMotionListener和ActionListioner)。
因爲畫圖形需要在畫板上獲取座標,所以添加的面板監聽器是MouseListener(可以畫直線和形狀)和MouseMitionListener(可以畫曲線)。用不同的Graphics的方法形狀還可以多樣化。
因爲ActionListener中的方法中的getActionCommand可以用來獲得按鈕的信息,所以只爲按鍵添加ActionListener。
因爲每次改變窗體的顯示範圍或者最小化後重新打開窗體,窗體都會進行重繪,所以我們還需要創建一個數組隊列來存儲先相關的形狀屬性(另外新建一個形狀的類,並創建一個個對象,對象裏面存儲了形狀的信息的屬性,我們可以用形狀類的數組隊列來存儲一個個形狀對象),在重寫重繪方法的時候調用數組,重繪形狀。
其中圖形是畫在面板上的,所以獲取的Graphics是面板的Graphics,並且通過調用之前在監聽器類中寫好的獲取畫筆的方法傳入監聽器中(使用構造方法中的構造器傳參的話,必須在創建對象時進行參數傳遞,假另外編寫一個獲取參數的方法的,可以更自由地在需要傳入參數的時候進行參數傳遞),再對畫筆的形狀、粗細和顏色進行調整。
以下是我的窗體代碼
public class logListener extends JFrame implements MouseListener{
private loginUI ui;
Graphics g;
public Graphics2D gg;
Listener li;
public logListener(loginUI ui){
this.ui=ui;
}
public void mouseClicked(MouseEvent e) {
ui.dispose();
logListener boardUI = new logListener(null);
boardUI.showUI();
}
public void showUI(){
this.setTitle("畫圖板");
this.setSize(800,600);
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
this.setResizable(false);
//設置西邊北邊區域
//創建一個JPanel
JPanel jpw = new JPanel();
jpw.setPreferredSize(new Dimension(800,100));
jpw.setBackground(Color.LIGHT_GRAY);
//頂端空白
JPanel jpw2= new JPanel();
jpw2.setPreferredSize(new Dimension(800,20));
jpw2.setBackground(Color.LIGHT_GRAY);
jpw.add(jpw2);
//顏色文字提示
jpw.add(new JLabel("選擇顏色:"));
//創建監聽器
li = new Listener();
//設置顏色按鈕
for(int i=0;i<35;i++){
JButton jbu = new JButton();
jbu.setPreferredSize(new Dimension(15,15));
jbu.setBackground(new Color(150+3*i,i+1*8,255-i));
jbu.addActionListener(li);
jpw.add(jbu);
}
this.add(jpw,BorderLayout.NORTH);
//設置形狀按鈕
String[] array={"畫筆","直線","橢圓","矩形","橡皮","撤銷"};
for(int i=0;i<array.length;i++){
JButton jbu = new JButton(array[i]);
jbu.setPreferredSize(new Dimension(122,40));
jbu.addActionListener(li);
jpw.add(jbu);
}
this.addMouseListener(li);
this.addMouseMotionListener(li);
this.setVisible(true);
g = this.getGraphics();
li.setpen(g);
}
//重寫重繪方法
public void paint(Graphics g){
super.paint(g);
gg = (Graphics2D)g;
try{
for(int i=0;i<li.que.getSzie();i++){
shapes shape = new shapes();
shape.x=li.que.array[i].x;
shape.y=li.que.array[i].y;
shape.x1=li.que.array[i].x1;
shape.y1=li.que.array[i].y1;
shape.color=li.que.array[i].color;
shape.style=li.que.array[i].style;
if(shape.style=="畫筆"){
gg.setColor(shape.color);
gg.setStroke(new BasicStroke(3.0f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
gg.drawLine(shape.x, shape.y, shape.x1, shape.y1);
}
if(shape.style=="橡皮"){
gg.setColor(new Color(238,238,238));
gg.setStroke(new BasicStroke(20.0f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
gg.drawLine(shape.x, shape.y, shape.x1, shape.y1);
}
if(shape.style=="直線"){
gg.setColor(shape.color);
gg.setStroke(new BasicStroke(3.0f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
gg.drawLine(shape.x, shape.y, shape.x1, shape.y1);
}
if(shape.style=="橢圓"){
gg.setColor(shape.color);
gg.setStroke(new BasicStroke(3.0f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
gg.drawOval(shape.x, shape.y, shape.x1, shape.x1);
}
if(shape.style=="矩形"){
gg.setColor(shape.color);
gg.setStroke(new BasicStroke(3.0f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
gg.drawLine(shape.x, shape.y1, shape.x1, shape.y1);
gg.drawLine(shape.x, shape.y, shape.x1, shape.y);
gg.drawLine(shape.x1, shape.y, shape.x1, shape.y1);
gg.drawLine(shape.x, shape.y, shape.x, shape.y1);
}
}
}catch (Exception e) {
}
}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent arg0) {}
}
監聽器代碼
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
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 Listener implements MouseListener,ActionListener,MouseMotionListener{
public Graphics g;
public String str="畫筆";;
public int x,y,x1,y1;
public Graphics2D gg;
public Color color = Color.BLACK;
queue que = new queue();
public void setpen(Graphics g){
this.g=g;
gg = (Graphics2D)g;
}
數組隊列代碼
public class queue {
public shapes[] array = null;
//添加形狀
public void add(shapes ele){
if(array==null){
array=new shapes[]{ele};
}
else{
shapes[] newarray=new shapes[array.length+1];
for(int i=0;i<array.length;i++){
newarray[i]=array[i];
}
newarray[array.length] =ele ;
array = newarray;
}
}
//獲取數組隊列長度
public int getSzie(){
return array.length;
}
}
創建的形狀類的代碼
import java.awt.Color;
public class shapes {
public int x,y,x1,y1;
public String style;
public Color color;
}
因爲之前還寫了一個登陸界面,所以主函數在登陸界面那個類裏頭,沒有出現在上述代碼中。
雖然這個畫圖板寫得有些簡陋,但是學會了Swing界面中的不少方法,並且我還可以用於以上的方法對畫圖板進行完善。通過這次學習,我對Java編寫代碼的思想有了更深的體會,特別是每個類之間搭建聯繫需要用到傳遞參數,傳遞參數的值或者傳參的時候不對,都有可能導致空指針異常(指針爲空,沒有獲得相應的數據)。通過多次的空指針報錯,我以後更應該注意避免再次犯錯誤。