Java改進:驗證碼,流星雨,swing,線程,鍵盤事件,點擊事件,圖片移動【詩書畫唱】
題目:每間隔0.1秒就依次打印出”一起來看流星雨“中的一個字
以下是改進版的代碼,有個人的超級詳細(xì)易懂的理解內(nèi)容和注釋內(nèi)容!

package swing;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.util.Random;
import javax.swing.*;
public class starNew {
public static void main(String[] args) {
huaTu huaTu=new huaTu();
Thread Thread=new Thread(huaTu);
Thread.start();
}
}
//個人的理解:
//huaTu extends JFrame:這里必須用huaTu來繼承JFrame,而不是用
//starNew來繼承JFrame,因為要讓文字依次地被打印出來,
//那么就是每次打印一個字的時候,JFrame就要用repaint()同時刷新一次。
//用starNew來繼承JFrame時,就是會等寫的sleep方法和repaint()刷新,執(zhí)行完后,
//文字都被打印出來后,才會有新的JFrame自動
//“this.setVisible(true)”和主函數(shù)中new starNew()出來。
class huaTu extends JFrame implements Runnable{
public huaTu(){
//5個基本屬性:
this.setLayout(null);
this.setSize(600,600);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public void paint(Graphics g){
Random r=new Random();
//設(shè)置畫筆的顏色為黑色:
g.setColor(Color.black);
//畫個矩形(整個的黑色背景):
g.fillRect(0,0,600,600);
//繪制圖片人物:
Image img=Toolkit.getDefaultToolkit().getImage("人.png");
g.drawImage(img,100,250,100,250,this);
//繪制星星:
g.setColor(Color.white);
for(int i=0;i<100;i++){
g.drawString("*",r.nextInt(600),r.nextInt(200));
}
//繪制一個月亮:
g.fillOval(400,50,80,80);
g.setColor(Color.black);
g.fillOval(389,50,80,80);
//一起去看流星雨思路:將文字轉(zhuǎn)為字符數(shù)組,用for循環(huán)每打印一個文字,
//就文字休眠0.1秒。
char[] charArray="一起去看流星雨".toCharArray();
g.setColor(Color.white);
g.setFont(new Font("微軟雅黑",Font.BOLD,30));
for(int i=0;i<charArray.length;i++){
g.drawString(charArray[i]+"",450,200+(i*30));
try {
Thread.sleep(100);
//這里的休眠同時控制文字和星星的每改變一次的時間間隔為0.1秒
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void run() {
while(true){
try {
Thread.sleep(10);
repaint();
// 這里的重繪repaint()方法是為了刷新
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}



每點擊一次后就讓用paint方法等畫的矩形的x軸和y軸方向的位移發(fā)生改變,就是讓矩形動

package swing;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class jvXing extends JFrame{
public static JButton anNiu=null;
public static void main(String[] args) {
new jvXing();
}
public jvXing(){
this.setLayout(null);
this.setSize(500,500);
this.setLocationRelativeTo(null);
huaTuClass huaTuClass=new huaTuClass();
huaTuClass.setBounds(0,0,400,400);
anNiu=new JButton("刷新");
anNiu.setBounds(410, 100, 70, 30);
anNiu.addActionListener(huaTuClass);
this.add(anNiu);
this.add(huaTuClass);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
//graphics 英[?ɡr?f?ks]
//美[?ɡr?f?ks]
//n. 圖樣; 圖案; 繪圖; 圖像;
//
//huaTuClass:畫圖類,繼承面板類,用Graphics和paint等,來畫圖
class huaTuClass extends JPanel implements ActionListener{
int x,y=0;//設(shè)置初始的x軸或y軸的距離的變量為0
public void paint(Graphics g){
//用clearRect方法刷新頁面的時候清空頁面上的所有內(nèi)容
// rect
// [詞典] 矩形(Rectangular); 矩形結(jié)構(gòu); 矩形區(qū)域;
g.clearRect(0, 0, this.getWidth(), this.getHeight());
// 個人總結(jié)的語法:
// this.getWidth()和this.getHeight()表示整個面板的寬和高
// g.clearRect(要清空區(qū)域的X軸方向位移,?
// 要清空區(qū)域的y軸方向位移,?
// 要清空區(qū)域的寬, 要清空區(qū)域的高)
//for循環(huán):
g.fillRect(x, y, 100, 100);//實心的矩形
}
// anNiuDengWenzi:按鈕等上的文字,就是點擊綁定點擊事件的按鈕等后,
// 會獲取上面的文字,傳值到actionPerformed里面
@Override
public void actionPerformed(ActionEvent anNiuDengWenzi) {
if(anNiuDengWenzi.getActionCommand().equals("刷新")){
this.x+=10;this.y+=10;
// 每次點擊按鈕后就會改變這里的矩形的X軸方向位移和y軸方向位移,
// 都會加10
repaint();//用于刷新頁面
// 調(diào)用該方法的三個情況:
// 1.頁面初始化
// 2.顯示調(diào)用repaint()方法
// 3.頁面大小進行改變的時候
}
}
}



做出驗證碼效果:

package swing;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.*;
public class yanZhengMa extends JFrame{
public static JButton anNiu=null;
public static void main(String[] args) {
//思路:先畫一個背景矩形
//畫4個數(shù)字
//畫干擾線
//畫干擾點
new yanZhengMa();
}
public yanZhengMa(){
// ————
//5個基本屬性其中的三個:
this.setLayout(null);
this.setSize(500,500);
this.setLocationRelativeTo(null);
// ————
//設(shè)置最大的總頁面的大小位置等:
huaTuCLASS huaTuCLASS=new huaTuCLASS();
huaTuCLASS.setBounds(0,0,500,500);
this.add(huaTuCLASS);
// ————
// 設(shè)置按鈕:
anNiu=new JButton("沒看清,換一張驗證碼");
anNiu.setBounds(165,210,170,20);
anNiu.addActionListener(huaTuCLASS);
this.add(anNiu);
// ————
//5個基本屬性其中的二個:
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
class huaTuCLASS extends JPanel implements ActionListener{
public void paint(Graphics g){
// g.clearRect(195,140,110,50);
g.clearRect(0, 0, this.getWidth(), this.getHeight());
// 一般都頁面刷新后清除原先的整個頁面內(nèi)容,不然,
// 不是左上角按鈕等會到最左上角等,會有“重影”等,
// 原先的某些頁面內(nèi)容等。
// :clearRect方法用于頁面刷新后清除原先的內(nèi)容
// erWeiMa.anNiu.setBounds(0, 0, 70, 30);
// ————
//畫一個矩形:
g.setColor(Color.black);
g.fillRect(195,140,110,50);
// ————
Random Random=new Random();
String String="0123456789abcdefghijklmnopqrstuvwxyzfjosdj"
+ "fiosmiosnfioudsjfiosdjfiodsjfosdjfiosdjfkodsfl";
//用toCharArray()將一個字符串轉(zhuǎn)為字符數(shù)組:
char[] charArray=String.toCharArray();//toCharArray()將字符串轉(zhuǎn)為字符數(shù)組
//設(shè)置字體的顏色隨機:
Color[] colorArray={Color.red,Color.yellow,
Color.blue,Color.black,Color.green};
for(int i=0;i<4;i++){//用for循環(huán)4次
g.setFont(new Font("微軟雅黑",Font.BOLD,
Random.nextInt(10)+20));
g.setColor(colorArray[Random.nextInt(colorArray.length)]);
String randomChar=charArray[Random.nextInt(String.length())+1]+"";
g.drawString(randomChar,i*20+10+200,Random.nextInt(10)+165);
}
// [Random.nextInt(String.length())+1]為charArray數(shù)組的下標(biāo)
// ,這里的Random.nextInt范圍含頭不含尾
// 比如:Random Random=new Random();
// Random.nextInt(4)將產(chǎn)生0,1,2,3這4個數(shù)字中的任何隨機一個數(shù)字
// ————
//干擾線部分:
for(int i=0;i<8;i++){
//繪制5條干擾線:
g.setColor(colorArray[Random.nextInt(colorArray.length)]);
g.drawLine(Random.nextInt(100)+200,Random.nextInt(30)+150,
Random.nextInt(100)+200,Random.nextInt(30)+150);
}
// ————
//干擾點部分:
for(int i=0;i<20;i++){
//繪制5條干擾線
g.setColor(colorArray[Random.nextInt(colorArray.length)]);
int x=Random.nextInt(100)+200;
int y= Random.nextInt(30)+150;
g.drawLine(x,y,x+1,y+1);
}
}
@Override
public void actionPerformed(ActionEvent anNiuDengWenzi) {
// TODO Auto-generated method stub
if(anNiuDengWenzi.getActionCommand().
equals("沒看清,換一張驗證碼")){
// this.x+=10;this.y+=10;
// 每次點擊按鈕后就會改變這里的矩形的X軸方向位移和y軸方向位移,
// 都會加10
repaint();//用于刷新頁面
// 調(diào)用該方法的三個情況:
// 1.頁面初始化
// 2.顯示調(diào)用repaint()方法
// 3.頁面大小進行改變的時候
}
}
}



用鍵盤控制圖片的上下左右的移動:

package swing;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class jianPanYiDong extends JFrame{
// jianPanYiDong:鍵盤移動
// public static JLabel tiShiWenZi;
// public static JButton anNiu;
public static void main(String[] args) {
new jianPanYiDong();
JOptionPane.showMessageDialog(null,"點擊鍵盤上的W,圖片向前\n"
+ "點擊鍵盤上的S,圖片向后\n"
+ "點擊鍵盤上的A,圖片向左\n"
+ "點擊鍵盤上的D,圖片向右");
}
public jianPanYiDong(){
this.setLayout(null);
this.setSize(500,500);
this.setLocationRelativeTo(null);
jianPanYiDonghuaTuCLass huaTuCLass=new jianPanYiDonghuaTuCLass();
huaTuCLass.setBounds(0,0,500,500);
this.add(huaTuCLass);
this.addKeyListener(huaTuCLass);
// __
// 設(shè)置提示文字(這里文字等控件的顯示都沒效果,
// 可能是因為設(shè)置了clearRect(清除矩形的范圍)):
// tiShiWenZi=new JLabel("點擊鍵盤上的W,圖片向前\n"
// + "點擊鍵盤上的S,圖片向后\n"
// + "點擊鍵盤上的A,圖片向左\n"
// + "點擊鍵盤上的D,圖片向右");
// tiShiWenZi.setBounds(0,0,170,50);
// this.add(tiShiWenZi);
// anNiu = new JButton("沒看清,換一張驗證碼");
// anNiu.setBounds(165,210,170,20);
//
// this.add(anNiu);
// __
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
//————
//用implements實現(xiàn)鍵盤點擊的KeyListener接口:
class jianPanYiDonghuaTuCLass extends JPanel implements KeyListener{
// :jianPanYiDonghuaTuCLass:調(diào)用的這個類不可重名或只是大小寫區(qū)別的命名等
// 不然會報錯等
// ————
int x,y;
Image Image;
//在構(gòu)造方法里初始化x軸,y軸方向的位置和圖片:
public jianPanYiDonghuaTuCLass(){
x=100;
y=100;
Image=Toolkit.getDefaultToolkit().getImage("人.png");
}
//用paint繪制的方法繪制圖片:?
public void paint(Graphics g){
g.clearRect(0,0,this.getWidth(),this.getHeight());
g.drawImage(Image,x,y,100,100,this);
}
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
//點擊鍵盤的方法:
if(e.getKeyCode()==KeyEvent.VK_W){
//點擊一個鍵盤按鈕后讓圖片移動 :
this.y-=10;
// JOptionPane.showMessageDialog(null,"點擊了W");
}
if(e.getKeyCode()==KeyEvent.VK_S){
this.y+=10;
// JOptionPane.showMessageDialog(null,"點擊了S");
}
if(e.getKeyCode()==KeyEvent.VK_A){
this.x-=10;
// JOptionPane.showMessageDialog(null,"點擊了A");
}
if(e.getKeyCode()==KeyEvent.VK_D){
this.x+=10;
// JOptionPane.showMessageDialog(null,"點擊了D");
}
this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}


