2004年05月07日

—————————-
注意你的思想,思想产生语言;
注意你的语言,语言会变成行动;
注意你的行动,行动将形成性格;
注意你的性格,性格将决定你的命运。

—————————-
I Love You means:


I — Inject — 投入


L — Loyal — 忠诚
O — Obligation — 责任
V — Valiant — 勇敢
E — Enjoyment — 喜悦


Y — Yes — 愿意
O — Observant — 用心
U — Unison — 和谐
—————————-

2004年05月05日

月之轮回·时间表

  2:48初亏


  月亮进入地球黑影,发生圆亏变化


  3:52食既


  月亮全部进入地球黑影,红月浮现


  4:30食甚


  月亮进入离地球黑影中心最近处


  5:08生光


  月亮开始离开地球的黑影


  6:12复圆


  月全食结束,一轮满月重现天空


  月之轮回·月全食


  月食是地球运行到太阳和月球中间、地球的影子遮掩月球时产生的一种奇特天象。月全食是地影遮掩了整个月球,月偏食只是月球的一部分在地影之内。发生月全食时,月亮并不是完全看不见,而是变成一个隐约可见的古铜色圆盘。这是因为地球挡住了太阳光对月亮的照射,而产生的阴影,而地球的大气层在此时仍然会折射一部分太阳光,因此会出现红月亮的情况。

2004年05月01日

开始使用Eclipse + VE进行JAVA的GUI设计。VE1.0是用于Eclipse3.0的,VE0.5是用于Eclipse2.1.2的。


要使用VE,必须先安装相应的EMF和GEF。VE1.0目前支持SWING和AWT,看来SWT还未被支持。利用VE可以很方便的制作JAVA的GUI界面,免去了很多写代码的工作,但是添加bean时反应还是比较慢的,远慢于MFC设计界面,但毕竟实现机制是不一样的。


Eclipse 3.0的界面要比2.1.2版本漂亮,或者说花哨一点,启动速度和2.1.2差不多。并且中文语言包最多只有2.1.2版本的。由于界面上组件太多,分辨率1024×768明显不够啊。

import javax.swing.*;
import java.awt.*;
/*
JWindow 是一个能够在用户桌面的任何地方显示的容器。
所以能够使用它构成程序刚运行时的splash画面。
*/
public class ESplash extends JWindow implements Runnable {
   
    private Thread thread = null;
    private Image logo = null;
    private Color bg_color = new Color(255, 255, 255);
    private Toolkit toolkit =getToolkit();
    private int image_width;
    private int image_height;

    public ESplash() {
      logo = new ECreateIcon().getSplashImage();
      loadImage(logo, 0);
      image_width = logo.getWidth(this);
      image_height = logo.getHeight(this);
      setBackground(bg_color);
      setCursor(new Cursor(3));
      setSize(image_width + 10, image_height + 10);
      //设置JWindow的显示位置
      int Xpos = (toolkit.getScreenSize().width – getSize().width) / 2;
      int Ypos = (toolkit.getScreenSize().height – getSize().height) / 2;
      setBounds(Xpos, Ypos, getSize().width, getSize().height);
      setVisible(true);
    }
    /*
     通过使用MediaTracker加载图像,确保图像被正确的加载。
     图像被加载后,将进行绘图。
    */
    private void loadImage(Image image, int ID) {
        if(image != null) {
            MediaTracker tracker = new MediaTracker(this);
            tracker.addImage(image, ID);
            try {
                tracker.waitForID(ID);
            }
            catch(InterruptedException _ex) { }
        }
    }

    /*
     在JWindow部件上绘制图像。
    */
    
    public void paint(Graphics g) {
        g.drawImage(logo, 5, 5, image_width, image_height, this);
        
        //设置字体的色彩
        g.setColor(new Color(102, 102, 150));
        g.drawString(“正在初始化系统……”, 7, getSize().height – 72);
        //设置矩形框的背景色彩。
        g.setColor(new Color(255, 255, 255));
        
        //绘制矩形框
        g.fillRect(5, getSize().height – 70, 317, 7);
        g.drawRect(5, getSize().height – 70, 317, 7);
        
        //重新设置将要填涂在矩形框中的颜色
        g.setColor(new Color(102, 102, 150));
        for(int n = 0; n < 317; n += 5)
            try {
             //线程休眠50毫秒
             Thread.sleep(50L);
             //填涂矩形框
             g.fillRect(5, getSize().height – 70, n, 5);
            }
            catch(Exception _ex) { }
        }

    public void run() {
        //设置鼠标为等待状态
        setCursor(new Cursor(3));
        repaint();
    }

    public void stop() {
        //结束线程
        thread = null;
        logo = null;
    }

//更新图形区,防止绘图时产生闪烁现象。

    public void update(Graphics g) {
        paint(g);
    }
  }

/////////////////////////////////////////////////////

import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;

public class ECreateIcon{

private static Image splashimage;

public ECreateIcon(){
splashimage = getImageFromResource(“resources/images/Esplash.gif”);
   }
//获得图像
private Image getImageFromResource(String image_path) {
         return Toolkit.getDefaultToolkit().getImage(image_path);
   }

public ImageIcon createImageIcon(String filename) {
  String path = “/resources/images/” + filename;
  return new ImageIcon(getClass().getResource(path));
   }
   
   public Image getSplashImage() {
       return splashimage;
   }
}

Java语言从其诞生到现在不过短短五年时间,却已经成为全球最热门的语言,Java程序员正成为IT业其它程序员中薪金最高的职员。这一切都应归功于Java良好的特性:简单、面向对象、分布式、平台无关性、可移植性、支持多线程等等。本文将用Java的多线程特性来实现线程等待提示框。

1、问题的提出

在Java应用程序编程中,有时需要在GUI(图形化用户界面)中处理一些占用系统资源较多,耗费时间较长的事务,例如:与数据库进行大批量数据交换、大数据量的复杂运算、远程连接服务器等等。系统在处理这些事务时,如果还是使用GUI所在的线程,会导致界面冻结,无法刷新,看起来好象系统已经崩溃,这是一个良好的软件系统不允许出现的局面。

2、解决问题的途径

解决上述问题的方法就是采用Java的多线程特性,为这些耗时又耗资源的事务再开一个线程单独运行,并在GUI处出现提示框“正在执行,请等待”,在线程结束时自动关闭该提示框。这样即避免了上面出现的界面冻结情况,又保证了线程的安全性,是软件开发者上佳的选择。

3、具体实现

(1)例子

这里举一个简单的例子来介绍如何用JAVA实现线程等待提示框。

此例实现一个很简单的GUI,根窗体testFrame是一个JFrame(框架)类,在testFrame中放置一个JPanel(面板):testPanel ,最后将一个JButton(按钮):testButton添加到testPanel中。

按下testButton,系统开始运行一个模拟的耗时又耗资源的事务:在标准输出设备上显示从1到100000,同时出现“线程正在运行”提示框,一旦事务完成(即线程结束),系统自动关闭该提示框。

(2)实现方法

为了达到上述功能,可以这样来实现:

当按下按钮后,启动一个新的线程来完成事务,即在标准输出设备上显示从1到100000(在代码中通过TestThread类来实现),紧接着再启动一个线程来显示“线程正在运行”提示框(在代码中通过ThreadDiag类来实现)。

为了使提示框在TestThread结束后,自行关闭,在TestThread启动后,还启动了一个DisposeDiag线程,这个线程专门用来等待TestThread线程结束后,关闭“线程正在运行”提示框。

(3)程序代码及注释

① TestFrame类

TestFrame是Java运行主程序,用来显示用户界面。 

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TestFrame extends JFrame
{
   //GUI所需组件
   public JPanel testPanel = null;
   public JButton testButton = null;
   public JFrame testFrame = null;
   public TestFrame()
   {
    //设置GUI为windows风格
    try
    {
     UIManager.setLookAndFeel(
     ”com.sun.java.swing.plaf.windows.WindowsLookAndFeel”);
    }
    catch (Exception ex)  
    {
     System.out.println(“Exception: ” + ex);
    }
    testFrame = this;
    // 初始化GUI
    Dimension dimensions = Toolkit.getDefaultToolkit().getScreenSize();
    setSize(dimensions.width /2, dimensions.height /2);
      setLocation(dimensions.width/2-dimensions.width/4,  
      dimensions.height/2-dimensions.height/4);
    testPanel = new JPanel();
    testButton = new JButton(“开始线程”);
    testPanel.add(testButton);
    getContentPane().add(testPanel);
    //增加按钮testButton事件监听器
    testButton.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(ActionEvent e) {
    TestThread testThread = new TestThread();//新生成一个处理事务线程
    testThread.start();//启动事务线程
    (new ThreadDiag(testFrame, testThread ,  
     ”正在执行,请等待……”)).start();//启动等待提示框线程
    }
   });
     //增加testFrame事件监听器
   addWindowListener(new WindowAdapter()
   {
    public void windowClosing(WindowEvent e) {
    System.exit(0);
     }
   });
  }
  public static void main(String[] args)  
  {
    //主程序
    TestFrame testFrame2 = new TestFrame();
    testFrame2.setTitle(“线程等待测试”);
    testFrame2.show();
  }
}
 


② TestThread类

TestThread类是处理事务线程,即在标准输出设备上显示从1到100000。 

public class TestThread extends Thread
{
  public void run()
  {
   for (int i = 1; i < 100000 ; i++ )
   {
    System.out.println(i);
   }  
  }
}




③ ThreadDiag类

ThreadDiag类用来显示“线程正在运行”提示框。

import java.awt.*;
import javax.swing.*;
public class ThreadDiag extends Thread
{
   private Thread currentThread = null;//实际调用时就是TestThread事务处理线程
   private String messages = “”;//提示框的提示信息
   private JFrame parentFrame = null;//提示框的父窗体
   private JDialog clueDiag = null;// “线程正在运行”提示框
   private Dimension dimensions = Toolkit.getDefaultToolkit().getScreenSize();
   private int width = dimensions.width / 4, height = 60;
   private int left = 0, top = 0;
   public ThreadDiag(JFrame parentFrame, Thread currentThread, String messages)
   {
    this.parentFrame = parentFrame;
    this.currentThread = currentThread;
    this.messages = messages;
    initDiag();//初始化提示框
   }
   protected void initDiag()
    {
    clueDiag = new JDialog(parentFrame,”正在执行,请等待…”,true);
    clueDiag.setCursor(new Cursor(Cursor.WAIT_CURSOR));
    JPanel testPanel = new JPanel();
    JLabel testLabel = new JLabel(messages);
    clueDiag.getContentPane().add(testPanel);
    testPanel.add(testLabel);
    (new DisposeDiag()).start();//启动关闭提示框线程
   }
  public void run()
  {
    //显示提示框
    int left = (dimensions.width – width)/2;
    int top = (dimensions.height – height)/2;
    clueDiag.setSize(new Dimension(width,height));
    clueDiag.setLocation(left, top);
    clueDiag.show();
  }
}




④ DisposeDiag类

DisposeDiag类用来关闭提示框


class DisposeDiag extends Thread
{
 public void run()
 {
   try
   {
    currentThread.join();//等待事务处理线程结束
   }
   catch(InterruptedException e)
   {
    System.out.println(“Exception:” + e);
   }
   clueDiag.dispose();//关闭提示框
  }
}



注:为了共用变量clueDiag,上述ThreadDiag类和DisposeDiag类放在同一个Java文件内,如果分开存放,只需传递一下参数即可。

上述程序在jdk1.3下运行通过。

2004年04月30日

Java Abstract Window Toolkit (AWT,抽象窗口工具包) 允许开发者通过setSize方法按照点来精确改变窗口大小。不过有时候用百分比或比例来指定窗口大小更容易。


下面的这个基本方法可以实现以上功能。窗口大小是一个“int”值,所以先将double值转换为int,改变值就可以改变窗口大小了。


/**
* Resizes the given window to the givenratio of the screen size
*
* @param w Window to resize.
* @param ratioX double value to changethe window horizontal size to.
* @param ratioY double value to changethe window vertical size to.
*/

static public void sizeWindowOnScreen(Window w double ratioX double ratioY)
{

// java.awt.Toolkit

Toolkit tk = w.getToolkit();

// java.awt.Dimension

Dimension scrn = tk.getScreenSize();

w.setSize( new Dimension((int)(scrn.width * ratioX)

(int)(scrn.height * ratioY)

) );

}

static public void sizeWindowOnScreen(Window w double ratio) {

sizeWindowOnScreen(w ratio ratio);

}



不少开发者还是喜欢用百分比而不是比例(ratios)。比例和百分比之间只是一个数学上的转换,并不影响API 对方法的调用。


应该确保经常用到方法,这样,每个逻辑大小会被存放在不同区域,通过使用sizeWindowOnScreen (Window, double, double) 方法,百分比与比例的转换会在一个区域里进行,实际的大小不是被拷贝而是被重用了。例如:

static publicvoid resizeWindowToScreenPercentage(Window w double perc) {

resizeWindowToScreenPercentage(wperc perc);

}

static public void resizeWindowToScreenPercentage(Window w double percX double percY)

{

sizeWindowOnScreen(w percX/100percY/100);

}



最后,也许有人希望把窗口大小设定为屏幕大小,MaxWindowOnScreen 这个方法可以实现上述功能。如下所示:

static publicvoid maxWindowOnScreen(Window w) {

sizeWindowOnScreen(w 1.0 1.0);

}

2004年04月29日

2004.04.28, Wednesday :: MPlayer 1.0pre4 released


We fixed a remotely exploitable security vulnerability in the Real RTSP code.

2004年04月19日

千辛万苦才从网下载了Eclipse和一些插件。5K的下载速度让我无法从Eclipse官方网站下载最新3.0,只好在校园网里面下了2.1.1。


唉,免费的国外代理速度慢,收费的费用高,没办法啊。


一直以来都很喜欢扩展性强的软件,这次还下了UML2和C/C++的插件,回去试用试用。


Eclipse的意思是日食之类的意思,IBM的Open Source软件,想想SUN吧,呵呵,这个名字起的。。。

1.记住该记住的,忘记该忘记的。改变能改变的,接受不能改变的

2.能冲刷一切的除了眼泪,就是时间,以时间来推移感情,时间越长,冲突越淡,仿佛不断稀释的茶。


3.怨言是上天得至人类最大的供物,也是人类祷告中最真诚的部分


4.智慧的代价是矛盾。这是人生对人生观开的玩笑。


5.世上的姑娘总以为自己是骄傲的公主(除了少数极丑和少数极聪明的姑娘例外)


6.如果敌人让你生气,那说明你还没有胜他的把握


7.如果朋友让你生气,那说明你仍然在意他的友情


8.令狐冲说“有些事情本身我们无法控制,只好控制自己。”


9.我不知道我现在做的哪些是对的,那些是错的,而当我终于老死的时候我才知道这些。所以我现在所能做的就是尽力做好每一件事,然后等待着老死。


10.也许有些人很可恶,有些人很卑鄙。而当我设身为他想象的时候,我才知道:他比我还可怜。所以请原谅所有你见过的人,好人或者坏人


11.鱼对水说你看不到我的眼泪,因为我在水里.水说我能感觉到你的眼泪,因为你在我心里。


12.快乐要有悲伤作陪,雨过应该就有天晴。如果雨后还是雨,如果忧伤之后还是忧伤.请让我们从容面对这离别之后的离别。 微笑地去寻找一个不可能出现的你!


13.死亡教会人一切,如同考试之后公布的结果??虽然恍然大悟,但为时晚矣!


14.你出生的时候,你哭着,周围的人笑着;你逝去的时候,你笑着,而周围的人在哭!


15.男人在结婚前觉得适合自己的女人很少,结婚后觉得适合自己的女人很多


16.于千万人之中,遇见你所遇见的人;于千万年之中,时间的无涯荒野里,没有早一步,也没有晚一步,刚巧赶上了


17.每个人都有潜在的能量,只是很容易:被习惯所掩盖,被时间所迷离,被惰性所消磨.


18.人生短短几十年,不要给自己留下了什么遗憾,想笑就笑,想哭就哭,该爱的时候就去爱,无谓压抑自己


19.《和平年代》里的话:当幻想和现实面对时,总是很痛苦的。要么你被痛苦击倒,要么你把痛苦踩在脚下


20.真正的爱情是不讲究热闹不讲究排场不讲究繁华更不讲究嚎头的


21.生命中,不断地有人离开或进入。于是,看见的,看不见的;记住的,遗忘了。生命中,不断地有得到和失落。于是,看不见的,看见了;遗忘的,记住了。 然而,看不见的,是不是就等于不存在?记住的,是不是永远不会消失?


22.我们确实活得艰难,一要承受种种外部的压力,更要面对自己内心的困惑。在苦苦挣扎中,如果有人向你投以理解的目光,你会感到一种生命的暖意,或许仅有短暂的一瞥,就足以使我感奋不已。


23.我不去想是否能够成功,既然选择了远方,便只顾风雨兼程;我不去想,身后会不会袭来寒风冷雨,既然目标是地平线,留给世界的只能是背影.


24.后悔是一种耗费精神的情绪.后悔是比损失更大的损失,比错误更大的错误.所以不要后悔

2004年02月13日

多亏POPOEVER提醒,日志的PR已经到4了,留个纪念:P
还要多谢Plod的链接,嘻嘻