Archive for the 'Java' Category

部落格搬家

WordPress是個非常好用的部落格,實在是很不想跳槽。

以下是針對免費空間的評論。

優點:

  1. 後台管理界面越來越友善
  2. 文章編輯很容易

缺點:

  1. 不能使用JavaScript,很多外掛都不能裝,畫面會顯得單調。
  2. 版面不能自己設計,或使用從網路上找到的好的佈景。

所以只好跳到Blogger去了,但是它的編輯功能實在是不太好用。

總之,不想付費就要有所限制囉~~

新家:http://tonycube.blogspot.com/

因為TonyBox已經被申請了,所以盒子就轉換成立方體(TonyCube)啦~

SystemTray – 常駐程式

systemtray.gif

(圖片來源:http://java.sun.com/docs/books/tutorial/uiswing/misc/systemtray.html)

我們常看到的在工作列右邊的常駐程式,可以用java.awt.SystemTray來寫,搭配java.awt.TrayIcon來顯示圖示。這個功能必須使用Java SE 6或更新版本,這兩個class都在java.awt這個package之下。

由於SystemTray實作成單體(即一個Java程式只能有唯一一個SystemTray的實體或稱物件),所以要取得SystemTray的實體必須呼叫它的static getSystemTray method如下:

SystemTray.getSystemTray();

但在使用之前,可以先檢查該作業系統是否有支援:

SystemTray.isSupported();

支援傳回true,不支援則傳回false

一個SystemTray可以包含一個或多個TrayIcon,使用add() method來增加至SystemTray中:

tray.add(trayIcon);

註:tray表示SystemTray的實體,trayIcon表示TrayIcon的實體。

TrayIcon可以顯示一個tooltip,如上圖的"Sun TrayIcon"黃色小框框:

trayIcon.displayMessage(String caption, String text, TrayIcon.MessageType messageType)

messageType 共有4個參數,如下:

  • TrayIcon.MessageType.ERROR – 錯誤訊息error.png
  • TrayIcon.MessageType.INFO – 資訊訊息info.png
  • TrayIcon.MessageType.NONE – 簡單訊息(無圖示)
  • TrayIcon.MessageType.WARNING – 警告訊息warning.png

註:trayIcon表示TrayIcon的實體。

TrayIcon可監聽的滑鼠事件:

MouseEvents (pressed, released, and clicked)

  • pressed:按住不放
  • released:放開
  • clicked:按一下

程式碼如下:

/* SysTray.java
* Created on 2008/10/11
* Author Tony
*
*/

import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JOptionPane;

public class SysTray {
//icon object
private TrayIcon trayIcon;
//SystemTray object
private SystemTray tray = null;
//取得圖示,如果找不到圖,在系統列上會是空白的
private final Image image = Toolkit.getDefaultToolkit().getImage(“image/tray.gif");

//跳出式選單
private PopupMenu popup = new PopupMenu();
private MenuItem openItem = null;
private MenuItem optionItem = null;
private MenuItem aboutItem = null;
private MenuItem exitItem = null;

public SysTray(){
//檢查OS是否支援SystemTray
if(SystemTray.isSupported()){

//每個Java程式只能有一個SystemTray實體
tray = SystemTray.getSystemTray();

//設定選單
setMenu();

//設定trayIcon(圖片,滑鼠指上去的Tip訊息,選單)
trayIcon = new TrayIcon(image, “我的系統常駐程式", popup);

//設定圖示自動變更尺寸
trayIcon.setImageAutoSize(true);

try {
//把trayIcon加入tray中
tray.add(trayIcon);
} catch (AWTException e) {
System.err.println(“TrayIcon could not be added.");
}

//設定事件
setEvent();
}else{
JOptionPane.showMessageDialog(null, “SystemTray not support!");
}
}

private void setMenu(){
//加入選單
openItem = new MenuItem(“開啟系統主界面");
optionItem = new MenuItem(“選項");
aboutItem = new MenuItem(“關於本程式");
exitItem = new MenuItem(“離開");

popup.add(openItem);
popup.add(optionItem);
popup.add(aboutItem);
//加入分隔線
popup.addSeparator();
popup.add(exitItem);
}

private void setEvent(){
//設定滑鼠事件監聽器
MouseListener mouseListener = new MouseListener() {
//Click
public void mouseClicked(MouseEvent e) {
//按左鍵才顯示Tip訊息
if (e.getButton() == MouseEvent.BUTTON1){
trayIcon.displayMessage(“^____^ :",
“使用displayMessage()可以用來通知使用者訊息喔~~~ \n滑鼠右鍵則可以顯示選單。",
TrayIcon.MessageType.INFO);
}
System.out.println(“Tray Icon – 按一下!");
}
//Enter
public void mouseEntered(MouseEvent e) {
System.out.println(“Tray Icon – 滑鼠進入!無效");
}
//Exit
public void mouseExited(MouseEvent e) {
System.out.println(“Tray Icon – 滑鼠離開!無效");
}

public void mousePressed(MouseEvent e) {
System.out.println(“Tray Icon – 滑鼠按下!");
}

public void mouseReleased(MouseEvent e) {
System.out.println(“Tray Icon – 滑鼠放開!");
}
};

//openItem按鈕事件
ActionListener openListener = new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(null, “開啟系統主界面");
}
};

//optionItem按鈕事件
ActionListener optionListener = new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(null, “開啟選項");
}
};

//aboutItem按鈕事件
ActionListener aboutListener = new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(null, “SystemTray 系統匣\n\nTonyBox\n\nhttps://tonybox.wordpress.com");
}
};

//aboutItem按鈕事件
ActionListener exitListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, “離開");
System.out.println(“離開");
System.exit(0);
}
};

//加入事件
openItem.addActionListener(openListener);
optionItem.addActionListener(optionListener);
aboutItem.addActionListener(aboutListener);
exitItem.addActionListener(exitListener);
trayIcon.addMouseListener(mouseListener);
}

public static void main(String[] args) {
//Test
new SysTray();
}

}

Properity – 屬性檔

※問題

要將系統設定的屬性儲存到磁碟上,當下次開啟系統時可以得到相同的屬性設定。

※解決方法

使用 java.util.Properties ,它繼承自 Hashtable 。使用的方式是它會以一組 key-value 來儲存資料,指定某個key它就會回傳相對應的value,也可把它當成簡易的資料庫來使用。程式碼如下:

/* properity.java
* Created on 2008/10/11
* Author Tony
*
*/

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;

public class properity {

public static void main(String[] args) throws Exception {
//建立Properties物件
Properties prop = new Properties();

//1.儲存屬性檔
//(1)建立FileOutputStream
FileOutputStream fout = new FileOutputStream(“myProperty.dat");
//(2)推入資料(key,value):可用key去找value
prop.put(“Author","Tony");
//(3)將資料儲存進屬性檔,可設定該屬性檔的名稱
prop.store(fout, “My Property");
//(4)關閉資料流
fout.close();

//執行完上面後,會在磁碟上存入一個檔案 myProperty.dat
//內容如下:
/*
#My Property
#Sat Oct 11 01:44:19 CST 2008
Author=Tony

*/

//2.讀取屬性檔
//(1)建立FileInputStream
FileInputStream fin = new FileInputStream(“myProperty.dat");
//(2)載入屬性檔案
prop.load(fin);
//(3)以key去取得value
String value = prop.getProperty(“Author");
//(4)關閉資料流
fin.close();
//(5)顯示資料
System.out.println(“Author: " + value);

}

}

JDBC – 日期時間欄位

※問題

如何 insert 一個日期時間欄位。

※解決方法

  • 存入目前日期時間

Calendar cal = Calendar.getInstance();
stam.setTimestamp(1, new java.sql.Timestamp(cal.getTimeInMillis()));

  • 存入設定的日期

Calendar cal = Calendar.getInstance();
cal.set(2008, 10 – 1, 1);//2008年10月1日
stam.setDate(1, new java.sql.Date(cal.getTimeInMillis()));

另外要注意的是,MySQL的日期時間欄位要選擇

  • date:只顯示日期
  • datetime:顯示日期時間
  • timestamp:顯示日期時間(有選項可勾選自動取得目前時間)

JDBC – 中文亂碼問題

※問題:

使用Java SDK 1.6 + Apach + MySQL

在 insert 中文字的時候會出現 ??

※解決方法:

  1. 確定phpMyAdmin管理界面首頁的文字編碼連線校對是否為 utf8_unicode_ci

    mysql-unicode.png

    在建立新資料庫的時候也要記得選 utf8_unicode_ci

    ps. 簡單測試:在phpMyAdmin中輸入帶有中文字的SQL語法(insert),如果新增進去的中文字沒有出現??,那MySQL這邊的設定就OK了。

  2. Java程式碼這邊要利用 PreparedStatement ,然後用它的 setNString(parameterIndex, value) 方法,如此中文字即可正常寫入MySQL。我看Java 的API沒有看到多一個N帶表什麼,以前用MS-SQL時它是代表unicode,所以我大膽的給它試下去,就解決了。大概的程式碼如下:

String sql = “INSERT INTO user (user_name, user_gender, user_addr) VALUES(?,?,?)";
PreparedStatement stam = conn.prepareStatement(sql);
stam.setNString(1, “張三");
stam.setInt(2,1);
stam.setNString(3, “台中市");
stam.executeUpdate();

簡單動畫 – 碰壁反彈的小方塊

Animation.JPG

簡單的動畫,小方塊在碰到邊框時會反彈。

/* animation.java
* Created on 2008/10/1
* Author Tony
* Blog tonybox
*/
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;

import javax.swing.*;

public class animation extends JComponent implements Runnable {

//執行緒
Thread t;
//是否移動
boolean go = true;
//方塊座標
int x = 0, y = 0;
//正向反向
int wx = 1, wy = 1;
//移動速度
int speed = 10;
//方塊大小
int boxSize = 20;

public static void main(String[] args){
JFrame window = new JFrame(“Animation");
Container cp = window.getContentPane();
animation a = new animation();
cp.add(a);

window.setSize(200,200);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}

animation(){
t = new Thread(this);
t.start();
}

@Override
public void run() {
while(go){
x += speed * wx;
y += speed * wy;
repaint();

try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public void paint(Graphics g){
if (x > this.getSize().width – boxSize){
wx = -1;
}
if (x <= 0){
wx = 1;
}

if (y > this.getSize().height – boxSize){
wy = -1;
}
if (y <= 0){
wy = 1;
}
g.setColor(Color.BLUE);
g.fillRoundRect(x, y, boxSize, boxSize, 1, 1);
}
}

Java 2D(4) – 幾合圖形(Geometric Primitives)

Java 2D API 提供幾標準圖形,例如:點(points)、線(lines)、矩形(rectangles)、弧形(arcs)、橢圓形(ellipses)和曲線(curves)。

Shape interface提供一組通用的方法來描述或檢查2D幾合圖形,並且支援曲線線段和多重子圖形(multiple sub-shapes),而 Graphics class 只支援直線(straight line)線段 。

要畫出幾合形狀要知道這個 package:java.awt.geom

Points

java.awt.geom.Point2D:定義一個點在位置上的表示方式,使用座標(x,y)。在Java 2D API中點"point"不等於像素(pixel)。Points 被用來建立其他的形狀(shapes),在 Point2D class中有提供2點間距離的method。

Lines

java.awt.geom.Line2D:這個是抽象類別(abstract class),看名字就知道是用來畫線的啦。另外也可以使用GeneralPath class 來畫直線線段。

Rectangular Shapes

Rectangle2DRoundRectangle2DArc2DEllipse2D都是繼承自java.awt.geom.RectangularShape class,都是用來畫矩形的。

2D-13.gif

(圖片來源:http://java.sun.com/docs/books/tutorial/figures/2d/2D-13.gif)

Quadratic and Cubic Curves

java.awt.geom.QuadCurve2D:畫二次曲線線段。二次曲線的定義是「2 個端點和 1 個控制點」,看下面的圖比較清楚。

2D-14.gif

(圖片來源:http://java.sun.com/docs/books/tutorial/figures/2d/2D-14.gif)

java.awt.geom.CubicCurve2D:畫三次曲線線段。三次曲線的定義是「2個端點和2個控制點」,請看下面的圖。

2D-15.gif

(圖片來來:http://java.sun.com/docs/books/tutorial/figures/2d/2D-15.gif)

Arbitrary Shapes

GeneralPath class :畫出任意形狀。它會利用一連串的點來設定形狀的邊界,並用直線或曲線來連結。類似小朋友用連連看來畫圖一樣。

PolyShape.gif

(圖片來源:http://java.sun.com/docs/books/tutorial/figures/2d/PolyShape.gif)

Area

java.awt.geom.Area:用來執行 boolean 運算,例如:聯集(union)、交集(intersection)和差集(subtraction)。

參考資料:http://java.sun.com/docs/books/tutorial/2d/overview/primitives.html

Java 2D(3) – 描圖(Rendering)

Java 2D API 包含 java.awt.Graphics2D class,它繼承自 Graphics class,提供增強型的圖像(graphics)和描圖(rendering)等特色,包括有:

  • draw methos :使用 stroke 和 paint 屬性來描繪任何圖形的外框(outline)。
  • fill method :可依指定的 paint 屬性填滿顏色(color)或圖案(pattern)。
  • drawString method :可畫出文字,其中的 font 屬性會被轉換成圖形,並可填滿由 paint 屬性所指定的顏色或圖案。
  • drawImage method :可畫出指定的圖像(image)。

以上提到的 method 都離不開以下兩個群組:

  1. 畫出形狀的方法(Methods to draw a shape)。
  2. 影響描圖的方法(Methods that affect rendering)。

第2個群組使用由 Graphics2D 而來的 state 屬性,有以下幾個目的:

  • 改變筆劃的寬度(stroke width)
  • 改變筆劃的組合
  • 設定剪裁路徑去限制描圖範圍
  • 定義顏色和圖案去填滿形狀
  • 指定如何組合多重圖像

Java 2D API 可透過型別轉換(cast)將由 Graphics object 產生的元件(component)轉型成 Graphics2D object,如下範例:

public void paint (Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    ...
}

以下列出幾個 Graphics2D class 描圖所包含的幾個屬性:

2D-4.gif pen 屬性:圖形的外框(outline)。這個筆劃(stroke)屬性允許你畫出任何尺寸的實線和虛線(dashing),並且可以在線端(end-cap)加上裝飾。
2D-5.gif fill 屬性:用在圖形的內部。這個顏料(paint)屬性可以讓你填滿單色(solid colors)、斜度(gradients)和圖案(patterns)。
2D-6.gif compositing 屬性:用在圖形物件的重疊上(overlap)
2D-7.gif

transform 屬性:可以將座標空間從 user space 轉成 device-space 。選項有:變形(translation)、旋轉(rotation)、縮放(scaling)和裁切(shearing)。

2D-8.gif clip 屬性:使用任何 Shape Object 的外框去定義剪裁路徑(clipping path)。
2D-9.gif font 屬性:轉換文字字串(text strings)為圖形。
2D-10.gif Rendering hits:調整速度(speed)和品質(quality)兩者間的偏好設定。

(以上圖片來源:http://java.sun.com/docs/books/tutorial/2d/overview/rendering.html)

參考資料:http://java.sun.com/docs/books/tutorial/2d/overview/rendering.html

Java 2D(2) – 座標(Coordinates)

Java 2D API 使用2種座標空間

  • User space – 指圖像原本的座標空間。
  • Device space – 輸出到像是螢幕(screen)、視窗(window)、印表機(printer)等裝置的座標系統。

User space是裝置獨立(device-independent)的邏輯座標系統,我們所寫的程式就是使用這個座標空間。所有在Java 2D中的描圖(rendering)都被指定為 user-space 座標。

當預設的轉換從user space轉成device space被使用,圖像的原點就是在左上角,如下圖。

2D-11.gif

(圖片來源:http://java.sun.com/docs/books/tutorial/figures/2d/2D-11.gif)

左上角座標值為(0,0),X軸座標往右為正,Y軸座標往下為正。和我們數學上學到的直角座標有點不同,如下圖。

350px-Cartesian-coordinate-system.svg.png

(圖片來源:http://upload.wikimedia.org/wikipedia/commons/thumb/0/0e/Cartesian-coordinate-system.svg/350px-Cartesian-coordinate-system.svg.png)

所有的座標值都是用整數,但也可在需要的時候使用浮點數。

Device space是裝罝相依(device-dependent)的座標系統。雖然視窗或螢幕使用的座標系統和印表機使用的座標系統有些微差異,但是不會太明顯(invisible)。(這是Sun說的喔~我們就相信他吧。)

user space和device space的轉換會在描圖需要的時候自動的執行,我們不用太去注意。

靠!都不知道自己在寫什麼,反正你只要知道座標是由左上角那個地方當原點,往右往下延伸就好了。(頭好痛~~~)

參考資料:http://java.sun.com/docs/books/tutorial/2d/overview/coordinate.html

Java 2D(1) – 概念

Java 2D API:

Java 2D API 提供的功能:

  • 對顯示裝罝(display devices,例如螢幕)及印表機(printers)使用同一描圖模型(rendering model)。
  • 豐富的原始幾合圖形,例如:曲線(curves)、矩形(rectangles)、橢圓形(ellipses)。
  • 可處理形狀(shapes)、文字(text)、圖像(images)
  • 提供重疊物件的混合模型(compositing model),像是photoshop中的混合模式。
  • 增強的顏色管理(color management)
  • 支援列印複雜的文件
  • 可控制的描圖品質

ps.以上是使用我的爛英文從sun的網站上翻出來,並用自己明白後的意思寫下來的,如果看不懂,那只是你不瞭解我的明白XD,跳過去吧,反正 Java 2D就是用來畫圖的就是了。

參考資料:http://java.sun.com/docs/books/tutorial/2d/overview/index.html