臨近聖誕節,複習不下去了就突然想畫一棵聖誕樹,正好蘋果那麼貴買不起就用這個表達一下心意吧
思路:
計劃用Java的Graphics畫筆畫一個聖誕樹,用若干個20*20像素的正方形表示。
-
首先用C寫了個大概的樣子出來確定了主要的寫法和邏輯
聖誕樹1.0
運行出來感覺這樣的太醜了,就決定下面兩個三角形都不要尖的部分了 -
確定了寫法後就用Java來寫,還是要用到圖形化界面,在一個面板裏直接用fillRect()方法畫正方形
聖誕樹2.0
畫完只有一個樹有點沒意思,就用fillRoundRect()在樹尖上加上了小球 -
畫到這裏還是沒那味兒,就打算弄個開關讓小球會變色模擬發光。加一個按鈕添加事件,用來觸發一個時間事件,通過時間事件每隔2秒就改變一下小球的顏色,最後還加上了一個背景音樂
聖誕樹3.0
[video(video-uhEZX1XW-1577196014760)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=80522682)(image-https://ss.csdn.net/p?http://i0.hdslb.com/bfs/archive/6130b4b6d0a038f8c317ba6e5a0cbe8d684a3a34.jpg)(title-用Java畫了一顆聖誕樹)]
現在就有那味兒了
細節:
- 畫圖形的時候要填充顏色,默認填充的Graphics畫筆設置的顏色,可以用setColor()方法修改填充顏色,可以直接用Color類自帶的幾種顏色,但是實在是太醜了,所以可以選擇先創建一個Color類的對象,然後打開PS選出喜歡的顏色查看這個顏色的RGB,然後設置該對象的RGB就可以得到這個顏色,最後將這個對象作爲setColor()方法的參數即可。
Color red = new Color(255, 0, 0) ;
g.setColor(red) ;
- 按鈕設置爲一個圖片要用setIcon()方法,但是可能會有存在邊框、背景顏色的問題,對於邊框使用setBorder()方法,參數設置爲null;對於背景顏色使用setContentAreaFilled()方法,參數設置爲false
onOff.setBorder(null) ; //去除邊框
onOff.setContentAreaFilled(false) ; //去除默認背景顏色
- 按鈕圖片大小不合適,首先要壓縮圖片,將圖片放在ImageIcon類的一個對象中,然後使用setImage()方法,參數爲icon.getImage().getScaledInstance(x,y, 0)
ImageIcon icon = new ImageIcon("OFF.png");
icon.setImage(icon.getImage().getScaledInstance(50,50, 0)) ; //壓縮圖片大小
onOff = new JButton() ;
onOff.setIcon(icon) ; //添加按鈕圖片
完整代碼如下:
Start.java
package christmasTree;
public class Start {
public static void main(String[] args) {
new MyFrame() ;
}
}
MyFrame.java
package christmasTree;
import javax.swing.JFrame;
public class MyFrame extends JFrame{
MyPanel p ;
MyFrame() {
p = new MyPanel() ;
add(p) ;
setBounds(400, 200, 800, 800) ;
setVisible(true) ;
validate() ;
setDefaultCloseOperation(MyFrame.EXIT_ON_CLOSE) ;
}
}
MyPanel.java
package christmasTree;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import javax.swing.*;
public class MyPanel extends JPanel implements ActionListener{
int x, y ; //座標
JButton onOff ; //開關按鈕
Timer time ; //觸發時間事件
boolean flag ; //判斷是開還是關
boolean color ; //控制動畫
File file = new File("music.wav") ;
URL url = null;
URI uri = null ;
AudioClip clip = null;
MyPanel() {
setLayout(null);
ImageIcon icon = new ImageIcon("OFF.png");
icon.setImage(icon.getImage().getScaledInstance(50,50, 0)) ; //壓縮圖片大小
onOff = new JButton() ;
onOff.addActionListener(this) ;
onOff.setIcon(icon) ; //添加按鈕圖片
onOff.setBorder(null) ; //去除邊框
onOff.setContentAreaFilled(false) ; //去除默認背景顏色
onOff.setBounds(0, 0, 50, 50) ;
add(onOff) ;
flag = true ;
color = true ;
time = new Timer(300,this) ;
time.stop() ;
try {
uri=file.toURI();
url = uri.toURL() ;
}
catch (MalformedURLException e1) {}
clip=Applet.newAudioClip(url);
}
public void paintComponent(Graphics g) {
x = 380 ;
y = 100 ;
if(color) {
ImageIcon image1 = new ImageIcon("2.png") ;
g.drawImage(image1.getImage(), x-3, y-25, 28, 26, null) ;
}
else {
ImageIcon image1 = new ImageIcon("1.png") ;
g.drawImage(image1.getImage(), x-3, y-25, 25, 25, null) ;
}
Color red = new Color(255, 0, 0) ;
Color yellow = new Color(255, 241, 0) ;
drawTree(1, 4, g) ; //畫第一個三角形
if(color) {
drawDecoration(x+22, y-44, 6, yellow, g); //畫第一個三角形的黃色裝飾
drawDecoration(x, y-22, 8, red, g); //畫第一個三角形的紅色裝飾
}
else {
drawDecoration(x+22, y-44, 6, red, g); //畫第一個三角形的黃色裝飾
drawDecoration(x, y-22, 8, yellow, g); //畫第一個三角形的紅色裝飾
}
x = 380-2*22;
drawTree(3, 6, g) ; //畫第二個三角形
if(color) {
drawDecoration(x+22, y-44, 10, yellow, g); //畫第二個三角形的黃色裝飾
drawDecoration(x, y-22, 12, red, g); //畫第二個三角形的紅色裝飾
}
else {
drawDecoration(x+22, y-44, 10, red, g); //畫第二個三角形的黃色裝飾
drawDecoration(x, y-22, 12, yellow, g); //畫第二個三角形的紅色裝飾
}
x = 380-4*22;
drawTree(5, 8, g) ; //畫第三個三角形
if(color) {
drawDecoration(x+22, y-44, 14, yellow, g); //畫第三個三角形的黃色裝飾
drawDecoration(x, y-22, 16, red, g); //畫第三個三角形的紅色裝飾
}
else {
drawDecoration(x+22, y-44, 14, red, g); //畫第三個三角形的黃色裝飾
drawDecoration(x, y-22, 16, yellow, g); //畫第三個三角形的紅色裝飾
}
x = 380-1*22 ;
drwaRoot(g) ; //畫樹根
}
void drawTree(int from, int to, Graphics g) { //畫三角形
Color c = new Color(9, 124, 37) ;
g.setColor(c) ;
for(int i=from; i<=to; i++) {
for(int j=0; j<(i*2-1); j++) {
g.fillRect(x, y, 20, 20);
x += 22 ;
}
x = 380-i*22 ;
y += 22 ;
}
}
void drawDecoration(int tx, int ty, int num, Color c, Graphics g) { //畫裝飾
g.setColor(c) ;
g.fillRoundRect(tx, ty, 18, 18, 18, 18) ; //畫圓
g.fillRoundRect(tx+num*22, ty, 18, 18, 18, 18) ;
}
void drwaRoot(Graphics g) { //畫樹根
Color c = new Color(131, 78, 0) ;
g.setColor(c);;
for(int i=0; i<4; i++) {
for(int j=0; j<3; j++) {
g.fillRect(x, y, 20, 20);
x += 22 ;
}
x = 380-1*22 ;
y += 22 ;
}
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == onOff) { //按鈕事件
if(flag) { //開
ImageIcon icon = new ImageIcon("ON.png");
icon.setImage(icon.getImage().getScaledInstance(50,50, 0)) ;
onOff.setIcon(icon) ;
flag = false ;
clip.loop();
time.restart() ;
}
else { //關
ImageIcon icon = new ImageIcon("OFF.png");
icon.setImage(icon.getImage().getScaledInstance(50,50, 0)) ;
onOff.setIcon(icon) ;
flag = true ;
time.stop() ;
clip.stop() ;
}
}
else if(e.getSource() == time) { //時間事件
repaint() ;
color = !color ;
}
}
}
總結: