現在把地雷模塊先放一下,開始設計時間模塊。可以用JLabel來顯示數字,也可以用其來顯示錶示數字的圖片。我選擇了後者。其實最開始想做成時間翻頁的效果,其實也能實現,但是如果使用下面的方法真的過於麻煩了。
有一點要注意的是:
我們顯示圖片時應該等到 圖片被下載完成後才啓動裝載過程,然後顯示完整的圖像。但是getImage可以在沒有載入全部的圖像的情況下立即返回。如果創建一個顯示多幅圖片的動畫,可以使用getImage來將所有的圖片載入一個數組,以便JLabel有序的顯示,但是動畫的第一次運行不一定是有效的,因爲JLabel類要等到整個圖像被裝載後才顯示它。
爲了避免這個問題,Java提供了MedioTracker類。
MedioTracker能自動追蹤一個或多個圖片的裝載進度。我們可以使用它阻塞其他的操作直到一個或多個圖像(相關連的)被完全載入。
我把它實現的全過程寫到了loadPicture方法中:(這個是可用的)
public void loadPicture()
{
MediaTracker tracker = new MediaTracker(this);
for(int i=0;i<images.length ;i++)
{
images[i] = getToolkit().getImage("image/Time/"+i+"t.png");
tracker.addImage(images[i], i);
}
try
{
tracker.waitForAll();
}
catch(InterruptedException ie){}
}
代替了最初可能各種顯示有誤的(這個是有問題的):
public void loadPicture()
{
for(int i=0;i<images.length ;i++)
{
images[i] = getToolkit().getImage("image/Time/"+i+"t.png");
}
}
您可以在源代碼中註釋掉上面的正確的方法,把原來註釋掉的有問題的方法還原,看看效果如何。
當然,有問題的這個方法運行起來並不是每一次都有問題,多試幾次,或者增加圖片的個數效果就比較明顯了。
在這裏,我將兩個方法分別運行的效果圖傳上來了:
我們接下來說如何來實現時間爲動畫的。首先我們將0-9十張圖片加載到了images數組中,
然後啓動一個線程,添加一個計數器,每隔1秒自加1.(根據具體情況,也可以0.1s。。。)
我設定了分鐘和秒兩個大塊,而又細分爲四個動態改變的小塊。其改變的時間和範圍由左到右分別是:
0-5*600s
0-9*60s
0-5*10s
0-9*1s
其實僅僅通過時間刷新來判斷是否達到圖片的刷新條件就OK了。具體實現的代碼如下:
好像這段代碼有點太繁瑣了,大部分都是在修飾界面。關鍵的代碼就是上面的loadPicture,還有下面的那個重寫的paintComponent的圖片與時間的對應函數關係。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.border.SoftBevelBorder;
class TimePanel extends JPanel
{
private JPanel panel0 = new JPanel();
private JPanel panel1 = new JPanel();
private JPanel panel2 = new JPanel();
private MicPanel micpanel[] = new MicPanel[4];
/*********************************************/
private Image images[] = new Image[10];
private long current = 0;
/**初始化的時候默認不顯示跑*/
private boolean stop = true;
public static void main(String[] args)
{
JFrame frame = new JFrame();
TimePanel tpanel = new TimePanel();
frame.add(tpanel);
frame.pack();
frame.setVisible(true);
}
public TimePanel()
{
loadPicture();
initOther();
panel1.add(micpanel[2] = new MicPanel(10,6),BorderLayout.WEST);
panel1.add(micpanel[3] = new MicPanel(1,10),BorderLayout.EAST);
panel2.add(micpanel[0] = new MicPanel(600,6),BorderLayout.WEST);
panel2.add(micpanel[1] = new MicPanel(60,10),BorderLayout.EAST);
startTime();
reStarted();
}
public void loadPicture()
{
MediaTracker tracker = new MediaTracker(this);
for(int i=0;i<images.length ;i++)
{
images[i] = getToolkit().getImage(i+"t.png");
tracker.addImage(images[i], i);
}
try
{
tracker.waitForAll();
}
catch(InterruptedException ie){}
}
/*
public void loadPicture()
{
for(int i=0;i<images.length ;i++)
{
images[i] = getToolkit().getImage(+i+"t.png");
}
}
*/
public void startTime()
{
stop = true;
MyRunnable myrun = new MyRunnable();
Thread thread = new Thread(myrun);
thread.start();
}
public void initOther()
{
panel0.setLayout(new BorderLayout());
panel1.setLayout(new BorderLayout());
panel2.setLayout(new BorderLayout());
/*panel1放分鐘,panel2放秒*/
panel0.add(panel1,BorderLayout.EAST);
panel0.add(panel2,BorderLayout.WEST);
/*不透明的話就不美觀了*/
panel0.setOpaque(false);
panel1.setOpaque(false);
panel2.setOpaque(false);
this.setOpaque(false);
/*設置突出的邊框*/
panel1.setBorder(new SoftBevelBorder(BevelBorder.RAISED));
panel2.setBorder(new SoftBevelBorder(BevelBorder.RAISED));
panel0.setBorder(new SoftBevelBorder(BevelBorder.RAISED));//(BevelBorder.LOWERED));
add(panel0);
try
{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
SwingUtilities.updateComponentTreeUI(this);
}
catch(Exception e) { e.printStackTrace(); }
}
class MicPanel extends JPanel
{
private int cut_time;
private int limit_time;
public MicPanel(int copy_cut,int copy_limit)
{
//super();
cut_time = copy_cut;
limit_time = copy_limit;
repaint();
}
/*原來這是非常有用的,要重寫這個方法*/
public Dimension getPreferredSize()
{
return new Dimension(images[0].getWidth(this),images[0].getHeight(this));
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(images[(int)(current/cut_time)%limit_time],0,0,this);
}
}
public void reStarted()
{
current = 0;
stop = false;
}
public void stoped()
{
stop = true;
}
class MyRunnable implements Runnable
{
public void run()
{
while(true)
{
if(!stop)
{
try{
current++;
Thread.sleep(1000);
micpanel[0].repaint();
micpanel[1].repaint();
micpanel[2].repaint();
micpanel[3].repaint();
}catch(InterruptedException ie){}
}
}
}
}
}
圖片和源代碼已經上傳。(關於MediaTracker的部分,我是參考的《java程序設計進階教程》(清華大學出版社))。
看完了這個例子,我想您應該也能想到如何很麻煩的製作出時間在紙上翻頁的效果來,簡單的僞動畫也可以通過修改sleep的時間片段的長短來實現。