Java学习备忘 (一)之二

        我在网上找到一个比较好的例子,具体网址为http://blog.csdn.net/yidinghe/article/details/6468407(感谢博主-捏造的信仰提供的这个例子,我在此引用此例,只为学习之用,别无他想。)我花了两三天中的业余时间,把它大概弄个明白,自己再重新敲一遍。因为我信奉:代码自己敲过一遍,才有可能真正弄明白。
package shc.stopwatch;

import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import javax.swing.SwingConstants;
import java.awt.event.ActionEvent;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionListener;

public class StopWatch extends JFrame {

	private static String LABEL_CONTENT_INIT = "00:00:00 0";
	private static final long serialVersionUID = 1;
	
	private JButton startButton = new JButton("Start");
	private JButton resetButton = new JButton("Reset");
	
	private long startupTime = System.currentTimeMillis();
	private long pauseTime = startupTime;
	private long pauseCount = 0;
	
	private CountingThread cThread = new CountingThread();
	
	private JLabel content = new JLabel(LABEL_CONTENT_INIT);
	private ActionListener startButtonListener = new ActionListener() {
		public void actionPerformed(ActionEvent e){
			//The Button is pressed initially,and cThread start 
			//updating the label.
			if(cThread.isStoped){
				pauseCount += (System.currentTimeMillis() - pauseTime);
				cThread.isStoped = false;
				startButton.setText("Pause");
			}else{//Pressed again and Stop counting.
				cThread.isStoped = true;
				pauseTime = System.currentTimeMillis();
				startButton.setText("Continue");
			}
				
		}
	}; 
	private ActionListener resetButtonListener = new ActionListener() {
		public void actionPerformed(ActionEvent e){
			cThread.isStoped = true;
			pauseTime = startupTime;
			content.setText(LABEL_CONTENT_INIT);
			startButton.setText("Start");
			pauseCount = 0;
		}
	}; 
	public StopWatch(String title) {
		super(title);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLocation(200,200);
		setResizable(false);
		setupBorder();
		
		setupButtonsPanel();
		setupLabel();
		startButton.addActionListener(startButtonListener);
		resetButton.addActionListener(resetButtonListener);
		
		cThread.start();
		//content.setText(formatTime(345678));
	}
	private void setupBorder() {
		JPanel contentPane = new JPanel(new BorderLayout());
		contentPane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
		this.setContentPane(contentPane);
	}
	private void setupButtonsPanel() {
		JPanel buttonPane = new JPanel(new FlowLayout());
		buttonPane.add(startButton);
		buttonPane.add(resetButton);
		add(buttonPane,BorderLayout.SOUTH);
	}
	private void setupLabel() {
		content.setHorizontalAlignment(SwingConstants.CENTER);
		content.setFont(new Font(content.getFont().getName(),
				content.getFont().getStyle(),40));
		add(content,BorderLayout.CENTER);
	}
	public static void main(String[] args) {
		try{
			UIManager.setLookAndFeel(UIManager.
					getSystemLookAndFeelClassName());
		}catch(Exception e){
			e.printStackTrace();
		}
		StopWatch stopWatch = new StopWatch("Stop Watch");
		stopWatch.pack();
		stopWatch.setVisible(true);
	}
	private String formatTime(long elapse) {
		int millis, sec, min, hour;
		/*
		millis = (int)(eclapse - eclapse / 1000 * 1000);
		millis /= 100;
		eclapse -= millis;
		eclapse /= 1000;
		sec = (int)(eclapse - eclapse / 60 * 60);
		eclapse -= sec;
		eclapse /= 60;
		min =(int)(eclapse - eclapse / 60 * 60);
		eclapse -= min;
		hour = (int)(eclapse / 60);
		*/
		millis = (int)(elapse % 1000);
		millis /=  100;
		elapse /= 1000;
		
		sec = (int)(elapse % 60);
		elapse /= 60;
		
		min = (int)(elapse % 60);
		elapse /= 60;
		
		hour = (int)(elapse % 60);
		
		return String.format("%02d:%02d:%02d:%01d", hour,min,sec,millis);
		
	}
	private class CountingThread extends Thread {
		public boolean isStoped = true;
		private CountingThread(){
			this.setDaemon(true);
		}
		public void run(){
			while(true){
				if(!isStoped){
					long elapseTime = System.currentTimeMillis() - startupTime
							- pauseCount;
					content.setText(formatTime(elapseTime));
				}
				try{
					sleep(10);
				}catch(InterruptedException e){
					e.printStackTrace();
				}
			}
		}
	}
}

      在这里,我主要从两个方面理解。

       首先是程序界面。要显示一个“窗口”,选择JFrame类,因为它是Java图形中的顶层容器,其显示效果就是个“窗口”;所以自然要从JFrame类扩展一个子类,如代码第16行。下来要往“窗口”,也就是我们所扩展的StopWatch子类,里面添加一些元素。加一个文本标签来显示时间的变化,加两个按钮来控制时间的变化行为。代码第21、22、30创建两个按钮和一个标签的实例,我们不希望别人再扩展这个StopWatch类,就把这几个成员指定为私有的。

       怎么把它们加入到JFrame里?在这里,创建一个面板(JPanel)实例(代码第72行),再把它设置为JFrame的内容窗格(代码第74行)。正如《Java核心技术 卷I》中所讲,JFrame类有几个窗格(pane)成员,我们经常与之打交道的是内容窗格,上面的元素最终是加到这个窗格的。代码第74行中的方法setContentPane就是把传入的容器类实例作为内容窗格(JPanel是Container的子类哦)。再添加其他东西,调用add方法即可。就像代码第80、86行那样,它们把装有按钮和标签的两个面板放在内容窗格的适当位置上,位置是由传给add方法的第二个参数决定的。

      另外,创建面板时,我们两次(代码第72、77行)都指定了布局:布局用来决定组件在容器中放置的位置及大小,比如代码第77-79行,把两个按钮以流布局方式放在面板中,这样它们就依次横向排列。

        以上这些都是在构造JFrame子类的时候做的动作,这样程序界面就做好了。代码第90行是确定程序运行时呈现出来的外观的(也就是《Java核心技术 卷I》中所用的术语“观感”),不加这行代码,在任何平台上,程序界面外观都一样;加上后,Windows下程序呈现的是Windows的界面风格,Ubuntu下呈现的是就是Ubuntu的风格。

        代码58-60分别指定:点击窗口关闭按钮时的默认动作,窗口在屏幕上的位置,窗口是否可改变大小。代码第96行是把窗口的大小调整到较优的状态同时适应它包含的组件的布局,97行把这些都显示出来,这个不能忘,否则运行后什么都没有哦。

       Java文档说Swing组件不是线程安全的,就这样建议:把89-97行放到一个Runnable的run方法里,再把它作为一个参数传给EventQueue.invokeLater或SwingUtilities.invokeLater,它们其中之一再放在main方法中。我试了一下前者,在这个例子里没有感觉到什么不同。但最好按文档做。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值