今天做了一個關于Graphics 對象的小程序,主要是對java自定義控件的應用,即程序中的圓形,五角形以及月牙形按鈕,不過五角星和半圓形存在一些問題,在這里把代碼貼上來,希望喜歡java GUI的朋友一起來探討,也算是向大家請教吧。
程序中的不足:五角星按鈕點擊周圍時有的地方會觸發按鈕的點擊事件,還有月牙左邊的弧怎樣能夠成為一個真正的弧,而非像現在這樣感覺像是連接三個點的兩條線,再有月牙的標簽沒能實現居中,具體是坐標算法有問題還是有什么特殊的地方需要處理,還請大家指點。
運行效果如圖:


圓形按鈕
package MyControls;

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


/** *//*********************圓形按鈕控件******************************/

public class Sun extends JButton
{
private Shape shape;


public Sun(String lable)
{
super(lable);
Dimension size = this.getPreferredSize();//獲取按鈕的最佳大小
size.width = size.height = Math.max(size.width,size.height);//使按鈕變成一個正方形
this.setPreferredSize(size);
this.setContentAreaFilled(false);//使JButton不畫背景
}

//畫圓的背景和標簽

protected void paintComponent(Graphics g)
{

if(this.getModel().isArmed())
{
g.setColor(Color.BLUE);

}else
{
g.setColor(Color.red);
}
g.fillOval(0,0,getSize().width - 1,getSize().height - 1);
super.paintComponent(g);
}

//畫按鈕的邊框

protected void paintBorder(Graphics g)
{
g.setColor(this.getForeground());
g.drawOval(0,0,getSize().width - 1,getSize().height - 1);
}

//判斷鼠標點擊坐標是否在按鈕上

public boolean contains(int x,int y)
{

if(shape == null || (!shape.getBounds().equals(getBounds())))
{
shape = new Ellipse2D.Float(0,0,getWidth(),getHeight());
}
return shape.contains(x,y);
}
}


月牙按鈕代碼
package MyControls;

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


/** *//*********************月牙形按鈕控件******************************/

public class Moon extends JButton
{
private Shape shape;


public Moon(String lable)
{
super(lable);
Dimension size = this.getPreferredSize();//獲取按鈕的最佳大小
size.width = size.height = Math.max(size.width,size.height);//使按鈕變成一個正方形
this.setPreferredSize(size);
this.setContentAreaFilled(false);//使JButton不畫背景
}

//畫圓的背景和標簽

protected void paintComponent(Graphics g)
{

if(this.getModel().isArmed())
{
g.setColor(Color.BLUE);

}else
{
g.setColor(Color.yellow);
}
g.fillArc(0,0,getSize().width - 1,getSize().height - 1,-120,250);
super.paintComponent(g);
}

//畫按鈕的邊框

protected void paintBorder(Graphics g)
{
g.setColor(this.getForeground());
g.drawArc(0,0,getSize().width - 1,getSize().height - 1,-120,250);
}

//判斷鼠標點擊坐標是否在按鈕上

public boolean contains(int x,int y)
{

if(shape == null || (!shape.getBounds().equals(getBounds())))
{
shape = new Ellipse2D.Float(0,0,getWidth(),getHeight());
}
return shape.contains(x,y);
}
}


五星按鈕代碼
package MyControls;

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


/** *//*********************星形按鈕控件******************************/

public class Star extends JButton
{
private Shape shape;
private int r1=50; //外接大圓半徑
private int r0=(int)(r1*Math.cos(72*Math.PI/180)); //內圓半徑
// 五角星10個點的橫坐標

private int[] xrr =
{
(int) 0, (int) (r0 * Math.cos(54 * Math.PI / 180)),
(int) (r1 * Math.sin(72 * Math.PI / 180)),
(int) (r0 * Math.cos(18 * Math.PI / 180)),
(int) (r1 * Math.cos(54 * Math.PI / 180)), (int) 0,
(int) ( ( -r1) * Math.cos(54 * Math.PI / 180)),
(int) ( ( -r0) * Math.cos(18 * Math.PI / 180)),
(int) ( ( -r1) * Math.sin(72 * Math.PI / 180)),
(int) ( ( -r0) * Math.cos(54 * Math.PI / 180))
};
//五角星10個點的縱坐標

private int[] yrr =
{
(int) - r1, (int) ( -r0 * Math.sin(54 * Math.PI / 180)),
(int) ( -r1 * Math.cos(72 * Math.PI / 180)),
(int) ( (r0) * Math.sin(18 * Math.PI / 180)),
(int) ( (r1) * (Math.sin(54 * Math.PI / 180))), (int) (r0),
(int) ( (r1) * (Math.sin(54 * Math.PI / 180))),
(int) ( (r0) * Math.sin(18 * Math.PI / 180)),
(int) ( -r1 * Math.cos(72 * Math.PI / 180)),
(int) ( -r0 * Math.sin(54 * Math.PI / 180)),
};


public Star(String lable)
{
super(lable);
Dimension size = this.getPreferredSize(); //獲取按鈕的最佳大小
size.width = size.height = Math.max(size.width, size.height); //使按鈕變成一個正方形
this.setPreferredSize(size);
this.setContentAreaFilled(false); //使JButton不畫背景
this.drawStar();
}


private void drawStar()
{

for (int i = 0; i < xrr.length; i++)
{ //計算大五角星坐標平移
xrr[i] += 50;
yrr[i] += 60;
}
}

//畫圓的背景和標簽

protected void paintComponent(Graphics g)
{

if(this.getModel().isArmed())
{
g.setColor(Color.BLUE);

}else
{
g.setColor(Color.yellow);
}
g.fillPolygon(xrr,yrr,10);
super.paintComponent(g);
}

//畫按鈕的邊框

protected void paintBorder(Graphics g)
{
g.setColor(this.getForeground());
g.drawPolygon(xrr,yrr,10);
}

//判斷鼠標點擊坐標是否在按鈕上

public boolean contains(int x,int y)
{

if(shape == null || (!shape.getBounds().equals(getBounds())))
{
shape = new Ellipse2D.Float(0,0,getWidth(),getHeight());
}
return shape.contains(x,y);
}

}


窗體代碼
package MyControls;

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


public class SkyOfNight extends JFrame implements ActionListener
{
private JButton btnSun,btnMoon,btnStar;


public SkyOfNight()
{

try
{
jbInit();
//設置窗體的背景顏色
//this.getContentPane().setBackground(Color.BLACK);
//創建圓形按鈕實例并畫到窗體中
btnSun = new Sun("Sun");
btnSun.setBackground(Color.RED);
btnSun.setBounds(new Rectangle(50,50,70,70));
btnSun.addActionListener(this);
this.getContentPane().add(btnSun);
//創建月牙形按鈕實例并畫到窗體中
btnMoon = new Moon("Moon");
btnMoon.setBackground(Color.RED);
btnMoon.setBounds(new Rectangle(250,200,80,80));
btnMoon.addActionListener(this);
this.getContentPane().add(btnMoon);
//創建星形按鈕實例并畫到窗體中
btnStar = new Star("Star");
btnStar.setBackground(Color.RED);
btnStar.setBounds(new Rectangle(50,200,105,120));
btnStar.addActionListener(this);
this.getContentPane().add(btnStar);
}

catch (Exception exception)
{
exception.printStackTrace();
}
}


private void jbInit() throws Exception
{
getContentPane().setLayout(null);
this.setResizable(false);
this.setTitle("SkyOfNight");
}


public void actionPerformed(ActionEvent e)
{

if(e.getSource() == btnSun)
{
JOptionPane.showMessageDialog(this,"I am Sun!","Prompt",JOptionPane.INFORMATION_MESSAGE);
return;

}else if(e.getSource() == btnMoon)
{
JOptionPane.showMessageDialog(this,"I am Moon!","Prompt",JOptionPane.INFORMATION_MESSAGE);
return;

}else if(e.getSource() == btnStar)
{
JOptionPane.showMessageDialog(this,"I am Star!","Prompt",JOptionPane.INFORMATION_MESSAGE);
return;
}
}


public static void main(String[] args)
{
SkyOfNight skyofnight = new SkyOfNight();
skyofnight.setSize(400,400);
skyofnight.setLocation(300,200);
skyofnight.setVisible(true);
skyofnight.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

點擊下載源代碼:/Files/daizhenghenry/skyOfNight.rar