现在把地雷模块先放一下,开始设计时间模块。可以用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){} } } } } }
看完了这个例子,我想您应该也能想到如何很麻烦的制作出时间在纸上翻页的效果来,简单的伪动画也可以通过修改sleep的时间片段的长短来实现。