添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

GUI是由Component,LayoutManager以及Listener所組成的。Component是畫面的主要組成成分,本身並沒有可見的實體,其子類別才有顯現的效果。如果Component可以放入其他的Component,則這種Component就稱為是Container。Container裡面的Component的排放位置,可以用絕對座標,也可以透過LayoutManager加以調整。使用者以Mouse,Keyboard等操作GUI時,會產生相對應的Event,並由視窗系統將該Event傳遞給程式設計者所指定的Listener。例如使用者以Mouse的左鍵按下Button(一種Component)時,視窗系統會將ActionEvent傳給該Button的ActionListener(設計者實作的物件),由ActionListener決定採取的步驟。這種由使用者觸發的執行動作,和程序式語言由主程式開始呼叫其他程序的模式不同,我們稱之為事件驅動(Event Driven)模式。

AWT(Abstract Window Toolkit, java.awt.*)是JDK 1.0所提出來有關GUI的函式庫,在JDK 1.1時又修改了Event Handling的機制, 成為現在的樣子。當初為了快速開發出AWT, 以符合Java出版的時程, 因此在設計上, 是利用視窗系統已有的GUI元件為主。由於Java原始的設計理念具有跨平台的性質, 因此AWT只好取各家視窗系統(Windows,Open Look, Motif, Machintosh)上元件的交集, 因此AWT頗為陽春。

為了彌補AWT的不足, JDK自1.2以後提供新的JFC(Java Foundation Class)/Swing的程式庫(javax.swing)。Swing是以Java語言所寫出來的, 因此提供了更多樣化而複雜的元件, 如Image JButton, Image JLabel, JTree, JTable, JTabbedPane, JPopupMenu等等。而且由於Swing並不依靠底層的視窗系統畫出元件的外觀, 因此Swing可以讓使用者自行選定其所喜愛的look and feel。

為了讓原先使用AWT的應用程式能改用Swing的程式庫, AWT內所有的元件都有相對應以J開頭的Swing元件, 如Button對應JButton, TextField對應JTextField。原先AWT的程式只要把Source Code裡面的AWT元件前面加上J即可, 其餘Event Handling和LayoutManager均可沿用(除了JFrame, JDialog, JApplet, JWindow等最上層的Container不能直接加入元件, 必須透過getContentPane()取得放置的地方)。

在以下的範例中, 我們主要採用AWT, 並在最後面給一個Swing的範例, 以說明兩者間的相似性。

AWT中直接繼承 Component 的子類別有

  • Button The following context describes the graphic
  • Canvas :空白的方形區域
  • Checkbox :勾選
  • Choice :拉下式表單
  • Container :裡面還可以放入其他Component
  • Label :可以顯示文字
  • List :捲軸表單
  • Scrollbar :捲軸
  • TextComponent :可用以編輯文字,其子類別有
  • Container的子類別有

  • Window :最上層的視窗,又有 Frame (可以設定 MenuBar 的獨立視窗), Dialog (必須依附在Frame下的視窗), FileDialog 等子類別。
  • Panel :沒有顯示的容器
  • ScrollPane : 具有ScrollBar的容器
  • AWT提供的 LayoutManager

  • BorderLayout :
  • CardLayout
  • FlowLayout :
  • GridBagLayout :
  • GridLayout :
  • AWT定義的Event主要是 java.awt.AWTEvent , 其下又有許多子類別(java.awt.event.*)

  • ActionEvent : component-defined action occured
  • AdjustmentEvent : ScrollBar被拉動
  • ComponentEvent :一般不直接使用, 其子類別有
    • ContainerEvent : Container加入或移除Component, 也很少用
    • FocusEvent : Gain or Lose Focus
    • InputEvent : 有兩個子類別
    • PaintEvent : 供AWT內部使用, 不用管他
    • WindowEvent : 視窗狀態改變
    • HierarchyEvent : AWT自動處理, 不用管他
    • InputMethodEvent
    • InvocationEvent : 由AWT event dispatcher thread呼叫Runnable物件裡的run()
    • ItemEvent : an item was selected or deselected
    • TextEvent : an object's text changed
    • 以上的Event都有相對應的Listener Interface來處理, 如ActionEvent相對應的是 ActionListener import java.awt.*; import java.awt.event.*; public class OXMain extends Frame implements ActionListener { private OX oxBoard; private OXMain() { super ("井字遊戲"); Menu m; MenuBar mb; oxBoard = new OX(this); this .add(oxBoard); CloseWindow close = new CloseWindow( this , true); this .setMenuBar(mb = new MenuBar ()); mb.add(m = new Menu ("遊戲")).add( new MenuItem ("新遊戲")).addActionListener( this ); m.add( new MenuItem ("結束")).addActionListener(close); mb.add( new Menu ("說明")).add( new MenuItem ("關於本遊戲")).addActionListener( this ); this .addWindowListener(close); pack(); setVisible(true); public static void main( String argv[]) { new OXMain(); // implements the ActionListener interface public void actionPerformed( ActionEvent e) { String command = e.getActionCommand(); if (command.equals("關於本遊戲")) { new ErrorDialog( this ,"俞旭昇寫好玩的"); } else if (command.equals("新遊戲")) { oxBoard.newGame(); class OX extends Component implements MouseListener { public static final byte EMPTY = 0; public static final byte CIRCLE = 1; public static final byte CROSS = 2; private byte [] board = new byte[9]; private byte playing = CIRCLE; private Dimension mySize = new Dimension (300,300); private Frame parent; private byte [][] directions = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}}; public OX( Frame p) { this .addMouseListener( this ); parent = p; // The following 5 functions implement the MouseListener interface public void mouseClicked( MouseEvent e) {} public void mouseEntered( MouseEvent e) {} public void mouseExited( MouseEven t e) {} public void mouseReleased( MouseEvent e) {} public void mousePressed( MouseEvent e) { int row = e.getY()/100; int col = e.getX()/100; if (row >= 3 || col >= 3) return ; // 超過邊界 if (board[row*3+col] == EMPTY) { // 此位置可以下 board[row*3+col] = playing; repaint(); // notify Window Manager // Anyone Win? for ( int i=0; i < directions.length; i++) { int j; for (j = 0; j < 3 && board[directions[i][j]]==playing; j++) ; if (j==3) { if (playing == CIRCLE) { new ErrorDialog(parent,"圓圈贏了"); } else if (playing == CROSS) { new ErrorDialog(parent,"叉叉贏了"); this .newGame(); return ; playing ^= 0x03; // override paint() defined in Component public void paint( Graphics g) { g.drawLine(0,100,300,100); g.drawLine(0,200,300,200); g.drawLine(100,0,100,300); g.drawLine(200,0,200,300); for ( int i = 0; i < 3; i++) { for ( int j = 0; j < 3; j++) { if (board[i*3+j] == CIRCLE) { g.drawOval(50+j*100-25,50+i*100-25,50,50); } else if (board[i*3+j] == CROSS) { g.drawLine(25+j*100,25+i*100,75+j*100,75+i*100); g.drawLine(75+j*100,25+i*100,25+j*100,75+i*100); public void newGame() { for ( int i = 0; i < 3; i++) { for ( int j = 0; j < 3; j++) { board[i*3+j] = EMPTY; playing = CIRCLE; repaint(); // override getPreferredSize defined in Component, // so that the Component has proper size on screen public Dimension getPreferredSize() { return mySize; // WindowAdapter implements the WindowLister interface // We extends WindowAdapter to reduce the line numer of code class CloseWindow extends WindowAdapter implements ActionListener { private Window target; private boolean exit; public CloseWindow( Window target, boolean exit) { this .target = target; this .exit = exit; public CloseWindow( Window target) { this .target = target; public void windowClosing( WindowEvent e) { target.dispose(); if (exit) System .exit(0); public void actionPerformed( ActionEvent e) { target.dispose(); if (exit) System .exit(0); class AddConstraint { public static void addConstraint( Container container, Component component, int grid_x, int grid_y, int grid_width, int grid_height, int fill, int anchor, double weight_x, double weight_y, int top, int left, int bottom, int right) { GridBagConstraints c = new GridBagConstraints (); c.gridx = grid_x; c.gridy = grid_y; c.gridwidth = grid_width; c.gridheight = grid_height; c.fill = fill; c.anchor = anchor; c.weightx = weight_x; c.weighty = weight_y; c.insets = new Insets(top,left,bottom,right); (( GridBagLayout )container.getLayout()).setConstraints(component,c); container.add(component); class ErrorDialog extends Dialog { public ErrorDialog( Frame parent, String all[]) { this (parent, all, null); public ErrorDialog( Frame parent, String all[], String msg) { super (parent,"",true); StringBuffer sb = new StringBuffer (); for ( int i=0; i < all.length; i++) { sb.append(all[i]); sb.append('\n'); if (msg!=null) { sb.append(msg); setup(parent, sb.toString()); public ErrorDialog( Frame parent, String message) { super (parent,"",true); setup(parent, message); private void setup( Frame parent, String message) { this .setLayout( new GridBagLayout()); int row=0, col=0, i, width=0; Font font = new Font ("Serif", Font.PLAIN, 16); char c=' '; for (i = 0; i < message.length(); i++) { c = message.charAt(i); if (c=='\n') { row++; if (width > col) { col = width; width=0; } else if (c == '\t') { width += 7-width%7; } else { if (c > 0x00FF) { width+=2; } else { width++; if (c!='\n') { row++; if (width > col) { col = width; col++; // 希望視窗出來不要太大或太小 row = (row > 24) ? 24 : row; if (row < 5) { row=5; if (col < 20) { col = 20; TextArea tx = new TextArea (message,row,col); tx.setEditable(false); tx.setFont(font); AddConstraint.addConstraint( this , tx, 0, 0, 1, 1, GridBagConstraints .BOTH, GridBagConstraints .NORTHWEST, 1,1,0,0,0,0); Button b = new Button ("確定"); b.setFont(font); AddConstraint.addConstraint( this , b, 0, 1, 1, 1, GridBagConstraints .HORIZONTAL, GridBagConstraints .CENTER, 1,0,0,0,0,0); CloseWindow cw = new CloseWindow( this ); this .addWindowListener(cw); b.addActionListener(cw); pack(); setVisible(true);

      井字遊戲的Swing版本

      GUI簡介 GUI是由Component,LayoutManager以及Listener所組成的。Component是畫面的主要組成成分,本身並沒有可見的實體,其子類別才有顯現的效果。如果Component可以放入其他的Component,則這種Component就稱為是Container。Container裡面的Component的排放位置,可以用絕對座標,也可以透過LayoutManager加以調整。使用者以Mouse,Keyboard等操作GUI時,會產生相對應的Event,並由視窗系統將該Event傳遞給程式設計者所指定的Listener。例如使用者以Mouse的左鍵按下Button(一種Component)時,視窗系統會將ActionEvent傳給該Button的ActionListener(設計者實作的物件),由ActionListener決定採取的步驟。這種由使用者觸發的執行動作,和程序式語言由主程式開始呼叫其他程序的模式不同,我們稱之為事件驅動(Event Driven)模式。 AWT(Abstract Window Toolkit, java.awt.*)是JDK 1.0所提出來有關GUI的函式庫,在JDK 1.1時又修改了Event Handling的機制, 成為現在的樣子。當初為了快速開發出AWT, 以符合Java出版的時程, 因此在設計上, 是利用視窗系統已有的GUI元件為主。由於Java原始的設計理念具有跨平台的性質, 因此AWT只好取各家視窗系統(Windows,Open Look, Motif, Machintosh)上元件的交集, 因此AWT頗為陽春。 為了彌補AWT的不足, JDK自1.2以後提供新的JFC(Java Foundation Class)/Swing的程式庫(javax.swing)。Swing是以Java語言所寫出來的, 因此提供了更多樣化而複雜的元件, 如Image JButton, Image JLabel, JTree, JTable, JTabbedPane, JPopupMenu等等。而且由於Swing並不依靠底層的視窗系統畫出元件的外觀, 因此Swing可以讓使用者自行選定其所喜愛的look and feel。 為了讓原先使用AWT的應用程式能改用Swing的程式庫, AWT內所有的元件都有相對應以J開頭的Swing元件, 如Button對應JButton, TextField對應JTextField。原先AWT的程式只要把Source Code裡面的AWT元件前面加上J即可, 其餘Event Handling和LayoutManager均可沿用(除了JFrame, JDialog, JApplet, JWindow等最上層的Container不能直接加入元件, 必須透過getContentPane()取得放置的地方)。 在以下的範例中, 我們主要採用AWT, 並在最後面給一個Swing的範例, 以說明兩者間的相似性。 AWT中直接繼承Component的子類別有 Button Canvas:空白的方形區域 Checkbox:勾選 Choice:拉下式表單 Container:裡面還可以放入其他Component Label:可以顯示文字 List:捲軸表單 Scrollbar:捲軸 TextComponent:可用以編輯文字,其子類別有 TextField(單行) TextArea(多行) Container的子類別有 Window:最上層的視窗,又有Frame(可以設定MenuBar的獨立視窗), Dialog(必須依附在Frame下的視窗), FileDialog等子類別。 Panel:沒有顯示的容器 ScrollPane: 具有ScrollBar的容器 AWT提供的LayoutManager有 BorderLayout: CardLayout FlowLayout: GridBagLayout: GridLayout: AWT定義的Event主要是java.awt.AWTEvent, 其下又有許多子類別(java.awt.event.*) ActionEvent: component-defined action occured AdjustmentEvent: ScrollBar被拉動 ComponentEvent:一般不直接使用, 其子類別有 ContainerEvent: Container加入或移除Component, 也很少用 FocusEvent: Gain or Lose Focus InputEvent: 有兩個子類別 KeyEvent MouseEvent PaintEvent: 供AWT內部使用, 不用管他 WindowEvent: 視窗狀態改變 HierarchyEvent: AWT自動處理, 不用管他 InputMethodEvent InvocationEvent: 由AWT event dispatcher thread呼叫Runnable物件裡的run() ItemEvent: an item was selected or deselected TextEvent: an object's text changed 以上的Event都有相對應的Listener Interface來處理, 如ActionEvent相對應的是ActionListener import java.awt.*; import java.awt.event.*; public class OXMain extends Frame implements ActionListener { private OX oxBoard; private OXMain() { super("井字遊戲"); Menu m; MenuBar mb; oxBoard = new OX(this); this.add(oxBoard); CloseWindow close = new CloseWindow(this, true); this.setMenuBar(mb = new MenuBar()); mb.add(m = new Menu("遊戲")).add(new MenuItem("新遊戲")).addActionListener(this); m.add(new MenuItem("結束")).addActionListener(close); mb.add(new Menu("說明")).add(new MenuItem("關於本遊戲")).addActionListener(this); this.addWindowListener(close); pack(); setVisible(true); public static void main(String argv[]) { new OXMain(); // implements the ActionListener interface public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if (command.equals("關於本遊戲")) { new ErrorDialog(this,"俞旭昇寫好玩的"); } else if (command.equals("新遊戲")) { oxBoard.newGame(); class OX extends Component implements MouseListener { public static final byte EMPTY = 0; public static final byte CIRCLE = 1; public static final byte CROSS = 2; private byte[] board = new byte[9]; private byte playing = CIRCLE; private Dimension mySize = new Dimension(300,300); private Frame parent; private byte[][] directions = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}}; public OX(Frame p) { this.addMouseListener(this); parent = p; // The following 5 functions implement the MouseListener interface public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mousePressed(MouseEvent e) { int row = e.getY()/100; int col = e.getX()/100; if (row >= 3 || col >= 3) return; // 超過邊界 if (board[row*3+col] == EMPTY) { // 此位置可以下 board[row*3+col] = playing; repaint(); // notify Window Manager // Anyone Win? for (int i=0; i < directions.length; i++) { int j; for (j = 0; j < 3 && board[directions[i][j]]==playing; j++) ; if (j==3) { if (playing == CIRCLE) { new ErrorDialog(parent,"圓圈贏了"); } else if (playing == CROSS) { new ErrorDialog(parent,"叉叉贏了"); this.newGame(); return; playing ^= 0x03; // override paint() defined in Component public void paint(Graphics g) { g.drawLine(0,100,300,100); g.drawLine(0,200,300,200); g.drawLine(100,0,100,300); g.drawLine(200,0,200,300); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i*3+j] == CIRCLE) { g.drawOval(50+j*100-25,50+i*100-25,50,50); } else if (board[i*3+j] == CROSS) { g.drawLine(25+j*100,25+i*100,75+j*100,75+i*100); g.drawLine(75+j*100,25+i*100,25+j*100,75+i*100); public void newGame() { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { board[i*3+j] = EMPTY; playing = CIRCLE; repaint(); // override getPreferredSize defined in Component, // so that the Component has proper size on screen public Dimension getPreferredSize() { return mySize; // WindowAdapter implements the WindowLister interface // We extends WindowAdapter to reduce the line numer of code class CloseWindow extends WindowAdapter implements ActionListener { private Window target; private boolean exit; public CloseWindow(Window target, boolean exit) { this.target = target; this.exit = exit; public CloseWindow(Window target) { this.target = target; public void windowClosing(WindowEvent e) { target.dispose(); if (exit) System.exit(0); public void actionPerformed(ActionEvent e) { target.dispose(); if (exit) System.exit(0); class AddConstraint { public static void addConstraint(Container container, Component component, int grid_x, int grid_y, int grid_width, int grid_height, int fill, int anchor, double weight_x, double weight_y, int top, int left, int bottom, int right) { GridBagConstraints c = new GridBagConstraints(); c.gridx = grid_x; c.gridy = grid_y; c.gridwidth = grid_width; c.gridheight = grid_height; c.fill = fill; c.anchor = anchor; c.weightx = weight_x; c.weighty = weight_y; c.insets = new Insets(top,left,bottom,right); ((GridBagLayout)container.getLayout()).setConstraints(component,c); container.add(component); class ErrorDialog extends Dialog { public ErrorDialog(Frame parent, String all[]) { this(parent, all, null); public ErrorDialog(Frame parent, String all[], String msg) { super(parent,"",true); StringBuffer sb = new StringBuffer(); for (int i=0; i < all.length; i++) { sb.append(all[i]); sb.append('\n'); if (msg!=null) { sb.append(msg); setup(parent, sb.toString()); public ErrorDialog(Frame parent, String message) { super(parent,"",true); setup(parent, message); private void setup(Frame parent, String message) { this.setLayout(new GridBagLayout()); int row=0, col=0, i, width=0; Font font = new Font("Serif", Font.PLAIN, 16); char c=' '; for (i = 0; i < message.length(); i++) { c = message.charAt(i); if (c=='\n') { row++; if (width > col) { col = width; width=0; } else if (c == '\t') { width += 7-width%7; } else { if (c > 0x00FF) { width+=2; } else { width++; if (c!='\n') { row++; if (width > col) { col = width; col++; // 希望視窗出來不要太大或太小 row = (row > 24) ? 24 : row; if (row < 5) { row=5; if (col < 20) { col = 20; TextArea tx = new TextArea(message,row,col); tx.setEditable(false); tx.setFont(font); AddConstraint.addConstraint(this, tx, 0, 0, 1, 1, GridBagConstraints.BOTH, GridBagConstraints.NORTHWEST, 1,1,0,0,0,0); Button b = new Button("確定"); b.setFont(font); AddConstraint.addConstraint(this, b, 0, 1, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, 1,0,0,0,0,0); CloseWindow cw = new CloseWindow(this); this.addWindowListener(cw); b.addActionListener(cw); pack(); setVisible(true); 井字遊戲的Swing版本 * Program Name: SwingOXMain.java * Purpose: Showing how to Swing to write 井字遊戲 * Modify Date: 2005/03/29 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SwingOXMain extends JFrame implements ActionListener { private OX oxBoard; private SwingOXMain() { super("井字遊戲"); JMenu m; JMenuBar mb; oxBoard = new OX(this); this.getContentPane().add(oxBoard); CloseWindow close = new CloseWindow(this, true); this.setJMenuBar(mb = new JMenuBar()); mb.add(m = new JMenu("遊戲")).add(new JMenuItem("新遊戲")).addActionListener(this); m.add(new JMenuItem("結束")).addActionListener(close); mb.add(new JMenu("說明")).add(new JMenuItem("關於本遊戲")).addActionListener(this); this.addWindowListener(close); pack(); setVisible(true); public static void main(String argv[]) { new SwingOXMain(); // implements the ActionListener interface public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if (command.equals("關於本遊戲")) { new ErrorDialog(this,"俞旭昇寫好玩的"); } else if (command.equals("新遊戲")) { oxBoard.newGame(); class OX extends Component implements MouseListener { public static final byte EMPTY = 0; public static final byte CIRCLE = 1; public static final byte CROSS = 2; private byte[] board = new byte[9]; private byte playing = CIRCLE; private Dimension mySize = new Dimension(300,300); private JFrame parent; private byte[][] directions = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}}; public OX(JFrame p) { this.addMouseListener(this); parent = p; // The following 5 functions implement the MouseListener interface public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mousePressed(MouseEvent e) { int row = e.getY()/100; int col = e.getX()/100; if (row >= 3 || col >= 3) return; // 超過邊界 if (board[row*3+col] == EMPTY) { // 此位置可以下 board[row*3+col] = playing; repaint(); // notify Window Manager // Anyone Win? for (int i=0; i < directions.length; i++) { int j; for (j=0; j &tl; 3 && board[directions[i][j]]==playing; j++) ; if (j==3) { if (playing == CIRCLE) { new ErrorDialog(parent,"圓圈贏了"); } else if(playing == CROSS) { new ErrorDialog(parent,"叉叉贏了"); this.newGame(); return; playing ^= 0x03; // override paint() defined in Component public void paint(Graphics g) { g.drawLine(0,100,300,100); g.drawLine(0,200,300,200); g.drawLine(100,0,100,300); g.drawLine(200,0,200,300); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i*3+j] == CIRCLE) { g.drawOval(50+j*100-25,50+i*100-25,50,50); } else if (board[i*3+j] == CROSS) { g.drawLine(25+j*100,25+i*100,75+j*100,75+i*100); g.drawLine(75+j*100,25+i*100,25+j*100,75+i*100); public void newGame() { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { board[i*3+j] = EMPTY; playing = CIRCLE; repaint(); // override getPreferredSize defined in Component, // so that the Component has proper size on screen public Dimension getPreferredSize() { return mySize; // WindowAdapter implements the WindowLister interface // We extends WindowAdapter to reduce the line numer of code class CloseWindow extends WindowAdapter implements ActionListener { private Window target; private boolean exit; public CloseWindow(Window target, boolean exit) { this.target = target; this.exit = exit; public CloseWindow(Window target) { this.target = target; public void windowClosing(WindowEvent e) { target.dispose(); if (exit) System.exit(0); public void actionPerformed(ActionEvent e) { target.dispose(); if (exit) System.exit(0); class AddConstraint { public static void addConstraint(Container container, Component component, int grid_x, int grid_y, int grid_width, int grid_height, int fill, int anchor, double weight_x, double weight_y, int top, int left, int bottom, int right) { GridBagConstraints c = new GridBagConstraints(); c.gridx = grid_x; c.gridy = grid_y; c.gridwidth = grid_width; c.gridheight = grid_height; c.fill = fill; c.anchor = anchor; c.weightx = weight_x; c.weighty = weight_y; c.insets = new Insets(top,left,bottom,right); ((GridBagLayout)container.getLayout()).setConstraints(component,c); container.add(component); 文字編輯器 import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import java.io.*; public class Editor extends WindowAdapter implements ActionListener { JFrame topWindow; JTextArea jta; public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if (command.equals("Open")) { JFileChooser fd = new JFileChooser("."); fd.setDialogType(JFileChooser.OPEN_DIALOG); int returnVal = fd.showOpenDialog(topWindow); if (returnVal == JFileChooser.APPROVE_OPTION) { try { File file = fd.getSelectedFile(); BufferedReader fin = new BufferedReader(new FileReader(file)); StringBuffer sb = new StringBuffer(); String x; while ((x=fin.readLine()) != null) { sb.append(x); sb.append("\n"); jta.setText(sb.toString()); } catch(Exception epp) {} jta.setCaretPosition(0); } else if (command.equals("Save")) { JFileChooser fd = new JFileChooser("."); fd.setDialogType(JFileChooser.SAVE_DIALOG); int returnVal = fd.showSaveDialog(topWindow); if (returnVal == JFileChooser.APPROVE_OPTION) { try { File file = fd.getSelectedFile(); FileWriter fout = new FileWriter(file); fout.write(jta.getText()); fout.close(); } catch(Exception epp) {} } else if (command.equals("Find")) { String x = jta.getText(); int at = x.indexOf("int", jta.getCaretPosition()); if (at >= 0) { jta.setCaretPosition(at); jta.setSelectionStart(at); jta.setSelectionEnd(at+3); } else { System.out.println("Unknown "+command); public void windowClosing(WindowEvent e) { topWindow.dispose(); System.exit(0); public Editor() { Font myFont = new Font("細明體", Font.PLAIN, 20); topWindow = new JFrame("My IDE"); // get the root container of JFrame Container c = topWindow.getContentPane(); c.setLayout(new GridLayout(1,1)); JMenuBar jmb = new JMenuBar(); JMenu m = new JMenu("File"); m.setFont(myFont); JMenuItem mi = new JMenuItem("Open"); mi.setFont(myFont); mi.addActionListener(this); m.add(mi); mi = new JMenuItem("Save"); mi.setFont(myFont); mi.addActionListener(this); m.add(mi); mi = new JMenuItem("Find"); mi.setFont(myFont); mi.addActionListener(this); m.add(mi); jmb.add(m); topWindow.setJMenuBar(jmb); jta = new JTextArea(24,80); jta.setFont(myFont); jta.setCursor(new Cursor(Cursor.HAND_CURSOR)); JScrollPane jsp = new JScrollPane(jta); c.add(jsp); topWindow.addWindowListener(this); topWindow.pack(); // 壓縮到最適當的大小 topWindow.show(); // 顯示JFrame public static void main(String[] argv) { new Editor(); 鍵盤事件處理範例 /* Program Name: Field.java Subject: 單一欄位輸入 Author: 俞旭昇 Shiuh-Sheng Yu National ChiNan University Department of Information Management Since 1997/08/17 Last Update Date: 08/23/1998 2003/12/17, fix delete, tab 2004/04/26, 支援jdk1.2以後版本使用Ctrl-C,Ctrl-V複製貼上功能 ToolKit: JDK1.1.6 package ncnu.gui; import java.awt.*; import java.awt.event.*; import java.sql.Types; import java.awt.datatransfer.*; import java.io.IOException; public class Field implements ActionListener, KeyListener, Transferable, ClipboardOwner { static { try { if (System.getProperty("java.version").startsWith("1.1")) { checkCopy = false; } else { checkCopy = true; } catch(Exception ex) { public DataFlavor[] getTransferDataFlavors() { DataFlavor[] myFlavors = new DataFlavor[1]; myFlavors[0] = DataFlavor.stringFlavor; return myFlavors; public boolean isDataFlavorSupported(DataFlavor flavor) { return flavor.equals(DataFlavor.stringFlavor); public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { return myData; public void lostOwnership(Clipboard clipboard, Transferable contents) { static String myData; static boolean checkCopy; public static final int OVR=0; public static final int INS=1; TextField t; int limit; int type; int decimalDigits; int mode=0; KeyJump parent; public Field(KeyJump parent, TextField t, int limit, int type, int decimalDigits) { this.t = t; this.limit = limit; this.type = type; this.decimalDigits = decimalDigits; this.parent = parent; this.mode = OVR; t.addActionListener((ActionListener)this); t.addKeyListener((KeyListener)this); public void keyPressed(KeyEvent e) { String s; int pos,sstart,send; StringBuffer sb; switch(e.getKeyCode()) { case KeyEvent.VK_PASTE: case KeyEvent.VK_COPY: case KeyEvent.VK_UNDO: case KeyEvent.VK_CUT: case KeyEvent.VK_FIND: return; case KeyEvent.VK_INSERT: if (mode==OVR) { mode = INS; } else { mode = OVR; e.consume(); break; case KeyEvent.VK_TAB: case KeyEvent.VK_ENTER: case KeyEvent.VK_DOWN: parent.next(t); e.consume(); break; case KeyEvent.VK_UP: parent.previous(t); e.consume(); break; case KeyEvent.VK_LEFT: case KeyEvent.VK_RIGHT: case KeyEvent.VK_HOME: case KeyEvent.VK_END: return; case KeyEvent.VK_PAGE_UP: parent.pageUp(t); e.consume(); break; case KeyEvent.VK_PAGE_DOWN: parent.pageDown(t); e.consume(); break; case KeyEvent.VK_DELETE: e.consume(); if (!t.isEditable()) { return; s = t.getText(); pos = t.getCaretPosition(); sstart=t.getSelectionStart(); send=t.getSelectionEnd(); if (send>sstart) { sb = new StringBuffer(s.substring(0,sstart)); if (send!=s.length()) { sb.append(s.substring(send)); if ((type==Types.NUMERIC||type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; t.setText(sb.toString()); t.setCaretPosition(sstart); } else { if (pos==s.length()) { return; sb = new StringBuffer(s.substring(0,pos)); sb.append(s.substring(pos+1)); if ((type==Types.NUMERIC || type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; t.setText(sb.toString()); t.setCaretPosition(pos); return; case KeyEvent.VK_BACK_SPACE: e.consume(); if (!t.isEditable()) { return; s = t.getText(); pos = t.getCaretPosition(); sstart=t.getSelectionStart(); send=t.getSelectionEnd(); if (send>sstart) { sb = new StringBuffer(s.substring(0,sstart)); if (send!=s.length()) { sb.append(s.substring(send)); if ((type==Types.NUMERIC||type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; t.setText(sb.toString()); t.setCaretPosition(sstart); } else { if (pos==0) { return; if (pos<=1) { sb = new StringBuffer(); } else { sb = new StringBuffer(s.substring(0,pos-1)); sb.append(s.substring(pos)); if ((type==Types.NUMERIC||type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; t.setText(sb.toString()); t.setCaretPosition(pos-1); return; public void keyTyped(KeyEvent e) { String s; int pos,sstart,send; StringBuffer sb; if (!t.isEditable()) { e.consume(); return; char ch = e.getKeyChar(); // 3copy, 22 paste,127 delete,8 backspace if (checkCopy) { if (ch==3) { e.consume(); s = t.getText(); pos = t.getCaretPosition(); sstart=t.getSelectionStart(); send=t.getSelectionEnd(); if (send>sstart) { myData = s.substring(sstart,send); } else { myData = ""; Toolkit.getDefaultToolkit().getSystemClipboard().setContents(this,this); if (ch==22) { e.consume(); Transferable tt = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this); if (tt != null) { String data; try { data = (String)tt.getTransferData(DataFlavor.stringFlavor); } catch(Exception eppp) { System.out.println(eppp); return; s = t.getText(); pos = t.getCaretPosition(); sstart=t.getSelectionStart(); send=t.getSelectionEnd(); if (send>sstart) { // 有選起來 sb = new StringBuffer(s.substring(0,sstart)); sb.append(data); if (send!=s.length()) { sb.append(s.substring(send)); if ((type==Types.NUMERIC||type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; t.setText(sb.toString()); t.setCaretPosition(sstart); } else { sb = new StringBuffer(s.substring(0,pos)); sb.append(data); if (pos < s.length()) { sb.append(s.substring(pos)); if ((type==Types.NUMERIC || type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; t.setText(sb.toString()); t.setCaretPosition(pos); if (ch==3 || ch==22 || ch==8 || ch==127 || ch=='\t' || ch=='\n') { e.consume(); return; if (ch!=KeyEvent.CHAR_UNDEFINED) { s = t.getText(); sstart=t.getSelectionStart(); send=t.getSelectionEnd(); if (send > sstart) { sb = new StringBuffer(s.substring(0,sstart)); sb.append(ch); if (send!=s.length()) { sb.append(s.substring(send)); } else { pos = t.getCaretPosition(); sb = new StringBuffer(s.substring(0,pos)); sb.append(ch); if (pos!=s.length()) { if (mode==INS) { sb.append(s.substring(pos)); } else { sb.append(s.substring(pos+1)); if ((type==Types.NUMERIC||type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; pos = t.getCaretPosition(); t.setText(inputTruncate(sb.toString())); t.setCaretPosition(pos+1); e.consume(); public void keyReleased(KeyEvent e) { return; public void actionPerformed(ActionEvent e) { int currentIndex, i; TextComponent next; switch(e.getID()) { case ActionEvent.ACTION_PERFORMED: parent.next(t); break; default: break; protected String inputTruncate(String s) { int i,j=limit; if (type==Types.NUMERIC||type==Types.DECIMAL) { int k=0, leading; if (decimalDigits==0) { leading = limit; } else { leading = limit-decimalDigits; if (s.charAt(0)=='-') { for (; k < leading && k < s.length(); k++) { if (!(s.charAt(k) >='0' && s.charAt(k) <='9')) { break; if (decimalDigits!=0) { k += decimalDigits+1; j = k; if (s.getBytes().length>j) { for (i=s.length()-1; i > 0 ;i--) { if (s.substring(0,i).getBytes().length<=j) { break; return (s.substring(0,i)); return s; protected boolean legalNumber(String s) { int leading; int i=0,j=0; if (s.length()==0) { return true; if (decimalDigits == 0) { leading = limit; } else { leading = limit - decimalDigits; if (s.charAt(i)=='-') { for (;(j < s.length()) && (j < leading); j++) { if (!(s.charAt(j) >='0' && s.charAt(j) <='9')) { break; if (j==s.length()) { return true; if (decimalDigits==0) { return false; } else { if (s.charAt(j)=='.') { for (i=j; i!=s.length() && i-j < decimalDigits; i++) { if (!(s.charAt(i) >='0' && s.charAt(i) <='9')) { break; if (i==s.length()) { return true; return false;

      文字編輯器

      import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import java.io.*; public class Editor extends WindowAdapter implements ActionListener { JFrame topWindow; JTextArea jta; public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if (command.equals("Open")) { JFileChooser fd = new JFileChooser("."); fd.setDialogType(JFileChooser.OPEN_DIALOG); int returnVal = fd.showOpenDialog(topWindow); if (returnVal == JFileChooser.APPROVE_OPTION) { try { File file = fd.getSelectedFile(); BufferedReader fin = new BufferedReader(new FileReader(file)); StringBuffer sb = new StringBuffer(); String x; while ((x=fin.readLine()) != null) { sb.append(x); sb.append("\n"); jta.setText(sb.toString()); } catch(Exception epp) {} jta.setCaretPosition(0); } else if (command.equals("Save")) { JFileChooser fd = new JFileChooser("."); fd.setDialogType(JFileChooser.SAVE_DIALOG); int returnVal = fd.showSaveDialog(topWindow); if (returnVal == JFileChooser.APPROVE_OPTION) { try { File file = fd.getSelectedFile(); FileWriter fout = new FileWriter(file); fout.write(jta.getText()); fout.close(); } catch(Exception epp) {} } else if (command.equals("Find")) { String x = jta.getText(); int at = x.indexOf("int", jta.getCaretPosition()); if (at >= 0) { jta.setCaretPosition(at); jta.setSelectionStart(at); jta.setSelectionEnd(at+3); } else { System.out.println("Unknown "+command); public void windowClosing(WindowEvent e) { topWindow.dispose(); System.exit(0); public Editor() { Font myFont = new Font("細明體", Font.PLAIN, 20); topWindow = new JFrame("My IDE"); // get the root container of JFrame Container c = topWindow.getContentPane(); c.setLayout(new GridLayout(1,1)); JMenuBar jmb = new JMenuBar(); JMenu m = new JMenu("File"); m.setFont(myFont); JMenuItem mi = new JMenuItem("Open"); mi.setFont(myFont); mi.addActionListener(this); m.add(mi); mi = new JMenuItem("Save"); mi.setFont(myFont); mi.addActionListener(this); m.add(mi); mi = new JMenuItem("Find"); mi.setFont(myFont); mi.addActionListener(this); m.add(mi); jmb.add(m); topWindow.setJMenuBar(jmb); jta = new JTextArea(24,80); jta.setFont(myFont); jta.setCursor(new Cursor(Cursor.HAND_CURSOR)); JScrollPane jsp = new JScrollPane(jta); c.add(jsp); topWindow.addWindowListener(this); topWindow.pack(); // 壓縮到最適當的大小 topWindow.show(); // 顯示JFrame public static void main(String[] argv) { new Editor();

      鍵盤事件處理範例

      /* Program Name: Field.java Subject: 單一欄位輸入 Author: 俞旭昇 Shiuh-Sheng Yu National ChiNan University Department of Information Management Since 1997/08/17 Last Update Date: 08/23/1998 2003/12/17, fix delete, tab 2004/04/26, 支援jdk1.2以後版本使用Ctrl-C,Ctrl-V複製貼上功能 ToolKit: JDK1.1.6 package ncnu.gui; import java.awt.*; import java.awt.event.*; import java.sql.Types; import java.awt.datatransfer.*; import java.io.IOException; public class Field implements ActionListener, KeyListener, Transferable, ClipboardOwner { static { try { if (System.getProperty("java.version").startsWith("1.1")) { checkCopy = false; } else { checkCopy = true; } catch(Exception ex) { public DataFlavor[] getTransferDataFlavors() { DataFlavor[] myFlavors = new DataFlavor[1]; myFlavors[0] = DataFlavor.stringFlavor; return myFlavors; public boolean isDataFlavorSupported(DataFlavor flavor) { return flavor.equals(DataFlavor.stringFlavor); public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { return myData; public void lostOwnership(Clipboard clipboard, Transferable contents) { static String myData; static boolean checkCopy; public static final int OVR=0; public static final int INS=1; TextField t; int limit; int type; int decimalDigits; int mode=0; KeyJump parent; public Field(KeyJump parent, TextField t, int limit, int type, int decimalDigits) { this.t = t; this.limit = limit; this.type = type; this.decimalDigits = decimalDigits; this.parent = parent; this.mode = OVR; t.addActionListener((ActionListener)this); t.addKeyListener((KeyListener)this); public void keyPressed(KeyEvent e) { String s; int pos,sstart,send; StringBuffer sb; switch(e.getKeyCode()) { case KeyEvent.VK_PASTE: case KeyEvent.VK_COPY: case KeyEvent.VK_UNDO: case KeyEvent.VK_CUT: case KeyEvent.VK_FIND: return; case KeyEvent.VK_INSERT: if (mode==OVR) { mode = INS; } else { mode = OVR; e.consume(); break; case KeyEvent.VK_TAB: case KeyEvent.VK_ENTER: case KeyEvent.VK_DOWN: parent.next(t); e.consume(); break; case KeyEvent.VK_UP: parent.previous(t); e.consume(); break; case KeyEvent.VK_LEFT: case KeyEvent.VK_RIGHT: case KeyEvent.VK_HOME: case KeyEvent.VK_END: return; case KeyEvent.VK_PAGE_UP: parent.pageUp(t); e.consume(); break; case KeyEvent.VK_PAGE_DOWN: parent.pageDown(t); e.consume(); break; case KeyEvent.VK_DELETE: e.consume(); if (!t.isEditable()) { return; s = t.getText(); pos = t.getCaretPosition(); sstart=t.getSelectionStart(); send=t.getSelectionEnd(); if (send>sstart) { sb = new StringBuffer(s.substring(0,sstart)); if (send!=s.length()) { sb.append(s.substring(send)); if ((type==Types.NUMERIC||type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; t.setText(sb.toString()); t.setCaretPosition(sstart); } else { if (pos==s.length()) { return; sb = new StringBuffer(s.substring(0,pos)); sb.append(s.substring(pos+1)); if ((type==Types.NUMERIC || type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; t.setText(sb.toString()); t.setCaretPosition(pos); return; case KeyEvent.VK_BACK_SPACE: e.consume(); if (!t.isEditable()) { return; s = t.getText(); pos = t.getCaretPosition(); sstart=t.getSelectionStart(); send=t.getSelectionEnd(); if (send>sstart) { sb = new StringBuffer(s.substring(0,sstart)); if (send!=s.length()) { sb.append(s.substring(send)); if ((type==Types.NUMERIC||type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; t.setText(sb.toString()); t.setCaretPosition(sstart); } else { if (pos==0) { return; if (pos<=1) { sb = new StringBuffer(); } else { sb = new StringBuffer(s.substring(0,pos-1)); sb.append(s.substring(pos)); if ((type==Types.NUMERIC||type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; t.setText(sb.toString()); t.setCaretPosition(pos-1); return; public void keyTyped(KeyEvent e) { String s; int pos,sstart,send; StringBuffer sb; if (!t.isEditable()) { e.consume(); return; char ch = e.getKeyChar(); // 3copy, 22 paste,127 delete,8 backspace if (checkCopy) { if (ch==3) { e.consume(); s = t.getText(); pos = t.getCaretPosition(); sstart=t.getSelectionStart(); send=t.getSelectionEnd(); if (send>sstart) { myData = s.substring(sstart,send); } else { myData = ""; Toolkit.getDefaultToolkit().getSystemClipboard().setContents(this,this); if (ch==22) { e.consume(); Transferable tt = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this); if (tt != null) { String data; try { data = (String)tt.getTransferData(DataFlavor.stringFlavor); } catch(Exception eppp) { System.out.println(eppp); return; s = t.getText(); pos = t.getCaretPosition(); sstart=t.getSelectionStart(); send=t.getSelectionEnd(); if (send>sstart) { // 有選起來 sb = new StringBuffer(s.substring(0,sstart)); sb.append(data); if (send!=s.length()) { sb.append(s.substring(send)); if ((type==Types.NUMERIC||type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; t.setText(sb.toString()); t.setCaretPosition(sstart); } else { sb = new StringBuffer(s.substring(0,pos)); sb.append(data); if (pos < s.length()) { sb.append(s.substring(pos)); if ((type==Types.NUMERIC || type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; t.setText(sb.toString()); t.setCaretPosition(pos); if (ch==3 || ch==22 || ch==8 || ch==127 || ch=='\t' || ch=='\n') { e.consume(); return; if (ch!=KeyEvent.CHAR_UNDEFINED) { s = t.getText(); sstart=t.getSelectionStart(); send=t.getSelectionEnd(); if (send>sstart) { sb = new StringBuffer(s.substring(0,sstart)); sb.append(ch); if (send!=s.length()) { sb.append(s.substring(send)); } else { pos = t.getCaretPosition(); sb = new StringBuffer(s.substring(0,pos)); sb.append(ch); if (pos!=s.length()) { if (mode==INS) { sb.append(s.substring(pos)); } else { sb.append(s.substring(pos+1)); if ((type==Types.NUMERIC||type==Types.DECIMAL) && !legalNumber(sb.toString())) { return; pos = t.getCaretPosition(); t.setText(inputTruncate(sb.toString())); t.setCaretPosition(pos+1); e.consume(); public void keyReleased(KeyEvent e) { return; public void actionPerformed(ActionEvent e) { int currentIndex, i; TextComponent next; switch(e.getID()) { case ActionEvent.ACTION_PERFORMED: parent.next(t); break; default: break; protected String inputTruncate(String s) { int i,j=limit; if (type==Types.NUMERIC||type==Types.DECIMAL) { int k=0, leading; if (decimalDigits==0) { leading = limit; } else { leading = limit-decimalDigits; if (s.charAt(0)=='-') { for (; k < leading && k < s.length(); k++) { if (!(s.charAt(k) >='0' && s.charAt(k) <='9')) { break; if (decimalDigits!=0) { k += decimalDigits+1; j = k; if (s.getBytes().length>j) { for (i=s.length()-1; i > 0 ;i--) { if (s.substring(0,i).getBytes().length<=j) { break; return (s.substring(0,i)); return s; protected boolean legalNumber(String s) { int leading; int i=0,j=0; if (s.length()==0) { return true; if (decimalDigits == 0) { leading = limit; } else { leading = limit - decimalDigits; if (s.charAt(i)=='-') { for (;(j < s.length()) && (j < leading); j++) { if (!(s.charAt(j) >='0' && s.charAt(j) <='9')) { break; if (j==s.length()) { return true; if (decimalDigits==0) { return false; } else { if (s.charAt(j)=='.') { for (i=j; i!=s.length() && i-j < decimalDigits; i++) { if (!(s.charAt(i) >='0' && s.charAt(i) <='9')) { break; if (i==s.length()) { return true; return false;
  •