1. 程式人生 > >Java基礎——GUI編程(四)

Java基礎——GUI編程(四)

perf on() paint 禁用 layout 文件 .cn 窗體 .text

繼前面的,這篇主要記錄菜單和文件對話框的兩個小練習,來熟悉一下方法的應用,一些簡單的邏輯和Swing的相關簡介,以及關於GUI基礎的記錄。

一、創建一個菜單

import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import javax.swing.JOptionPane; public class Test29 { public static void main(String[] args) { new MenuDeom(); } } class MenuDeom { MenuDeom() { init(); } private Frame f; private MenuBar mBar; private Menu menu;
private Menu subMenu; // 這是要當作二級菜單的,放在 menu 下 private MenuItem mItem1; private MenuItem mItem2; private void init() { f = new Frame("窗口標題"); f.setBounds(20, 20, 400, 500); f.setLayout(new FlowLayout()); mBar = new MenuBar(); // 創建一個菜單欄 menu = new Menu("文件"); //
創建一個菜單 mItem1 = new MenuItem("打開"); mItem2 = new MenuItem("退出"); menu.add(mItem1); menu.add(mItem2); subMenu = new Menu(); subMenu.add(new MenuItem("退出")); menu.add(subMenu); mBar.add(menu); f.setMenuBar(mBar); f.setVisible(true); initEvent(); } private void initEvent() { f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); mItem1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("第一個響應了"); JOptionPane.showMessageDialog(null, "這是第一個菜單的響應"); } }); mItem2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("第二個響應了"); JOptionPane.showMessageDialog(null, "這是第二個菜單的響應"); } }); } }

技術分享

二、創建文件對話框

import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

class FileDlgDemo {
    FileDlgDemo() {
        init();
    }

    private Frame f;
    private MenuBar mBar;
    private Menu fileMenu;
    private MenuItem openItem, saveItem, closeItem;
    private TextArea txtArea;

    private FileDialog openFileDlg; // 文件打開對話框
    private FileDialog saveFileDlg; // 文件保存對話框
    private File file;

    private void init() {
        f = new Frame("記事本");
        f.setBounds(50, 50, 400, 200);

        mBar = new MenuBar();
        fileMenu = new Menu("文件");
        openItem = new MenuItem("打開");
        saveItem = new MenuItem("保存");
        closeItem = new MenuItem("退出");

        fileMenu.add(openItem);
        fileMenu.add(saveItem);
        fileMenu.add(closeItem);

        mBar.add(fileMenu);

        f.setMenuBar(mBar);

        f.setVisible(true);

        openFileDlg = new FileDialog(f, "文件打開對話框", FileDialog.LOAD);
        saveFileDlg = new FileDialog(f, "文件保存對話框", FileDialog.SAVE);
        txtArea = new TextArea();
        f.add(txtArea);

        initEvent();
    }

    private void initEvent() {
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        // 打開
        openItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    openFileDlg.setVisible(true);

                    String driStr = openFileDlg.getDirectory();
                    String fileName = openFileDlg.getFile();

                    // System.out.println(driStr+":"+fileName);
                    BufferedReader br = new BufferedReader(new FileReader(
                            driStr + fileName));

                    String str = null;
                    while ((str = br.readLine()) != null) {
                        txtArea.append(str + "\r\n");
                    }

                    br.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }

            }
        });

        // 文件保存
        saveItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    saveFileDlg.setVisible(true);

                    String dirStr = saveFileDlg.getDirectory();
                    String fileName = saveFileDlg.getFile();
                    if (fileName != null && dirStr != null) {
                        file = new File(dirStr, fileName);

                        BufferedWriter bw = new BufferedWriter(new FileWriter(file));
                        String content = txtArea.getText();
                        bw.write(content);

                        bw.close();
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }

            }
        });

    }

}

public class Test30 {

    public static void main(String[] args) {
        new FileDlgDemo();

    }

}

技術分享

三、Swing 簡介和Swing 窗體

AWT組件最大的缺陷是它依賴於操作系統,Swing組件是在AWT組件基礎上發展而來,是純Java組件。

在Swing編程中,有一些經常要使用到的組件,其中包括:

1.JFrame(窗體,框架)

2.JButton(按鈕)

3.JLabel(標簽)

4.JTextField(文本框)

...

JFrame組件用於在Swing程序中創建窗體;

== JFrame 類的構造函數

JFrame() 創建新窗體,該窗體初始為不可見

JFrame(String title) 創建新窗體,使用參數title指定標題,該窗體初始為不可見

== JFrame 類的常用方法

void setTitle(String title) 設置窗體標題,標題內容由參數title指定

void setSize(int width, int height) 設置窗體的大小,參數width指定寬度,參數height指定高度,單位為像素

void setResizable(boolean resizable) 設置窗體能否調整大小,由參數resizable決定

void setVisible(boolean b) 設置窗體是否為可見,由參數b決定,true為可見,false為不可見

Container getContentPane() 獲得當前窗體的內容面板

不能把組件直接添加到Swing窗體中,其含有內容面板容器,應把組件添加到內容面板中;

不能為swing窗體設置布局,而應當為swing窗體中的內容面板設置布局

void setDefaultCloseOperation(int operation) 設置窗體在關閉時默認執行的操作

void dispose() 釋放當前窗體及其所有子組件所占用的資源,即卸載窗體

void repaint() 重新繪制當前窗體

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 退出時結束程序 //重要

代碼應用例子:

import javax.swing.JFrame;

//一個簡單的窗體示例
class MyFrame extends JFrame {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public MyFrame() {
        this.setTitle("這是個JFrame窗體");
        this.setSize(300, 200);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 正確的關閉窗體
    }

}

class Test31 {
    public static void main(String[] args) {
        new MyFrame();
    }
}

四、內容面板

一個完整的窗體是由外部框架和內容面板兩部分組成的;外部框架是指由標題欄和四邊所組成空心邊框,它主要用來控制窗體的大小和外觀;我們實際操作的是內容面板,如設置窗體的背景色,設置窗體的布局,往窗體中添加其它組件等等;我們不能直接在 JFrame 上增加子部件和部局管理器,使用getContentPane方法獲得當前窗體的內容面板,該方法的返回值是Container(容器)類對象(實際上應該是JRootPane類對象,可以強轉),如:

Container contentPane = getContentPane();

Container類在java.awt包中。

Container類通常用於操作JFrame的內容面板,其常用的方法有:

void setBackground(Color bg) 設置容器的背景色,由參數bg指定顏色

void setLayout(LayoutManager mgr) 設置容器的布局,參數是布局管理器

Component add(Component comp) 往容器中添加一個組件

Component add(Component comp, int index) 將指定組件添加到容器中的指定位置上

void remove(Component comp) 從容器中移除指定的組件

void removeAll() 從容器中移除所有組件

void repaint() 重新繪制當前容器

代碼應用示例:

import java.awt.Color;
import java.awt.Container;

import javax.swing.JFrame;

//例子
class ContentPaneDemo extends JFrame {
    public ContentPaneDemo() {
        super("內容面板示例"); // 設置標題
        Container c = this.getContentPane(); // 得到內容面板
        c.setBackground(Color.CYAN); // 背影設成青綠色
        this.setSize(300, 400);
        this.setResizable(false); // 窗體固定大小
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }

}

class Test32 {
    public static void main(String[] args) {
        new ContentPaneDemo();
    }
}

附: Color類

Color類用於創建顏色對象,其構造方法共有7種重載方式,以下是常用的幾種:

Color(int r, int b, int g)

Color類中還提供一系列靜態的顏色常量 例如 :Color.BLACK

五、常用控件

1.JButton類

JButton() 創建一個空按鈕

JButton(String text) 創建一個帶文本的按鈕

JButton(Icon icon) 創建一個帶圖標的按鈕

JButton(String text, Icon icon) 創建一個帶文本和圖標的按鈕

super("內容面板示例");   //設置標題    
    Container c=this.getContentPane(); //得到內容面板
    c.setBackground(Color.CYAN);  //背影設成青綠色
                        
    c.setLayout(new FlowLayout());
    Icon icon=new ImageIcon("src/8.gif");
    JButton btn=new JButton("按紐名稱",icon);
        c.add(btn);
                        
        this.setSize(300,400);
        this.setResizable(false); //窗體固定大小
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

附加:常用方法

void setText(String text) 設置按鈕上的文本

String getText() 獲得按鈕上的文本

void setBackground(Color bg) 設置按鈕的背景色

Color getBackground() 獲得按鈕的背景色

void setEnabled(boolean b) 設置啟用(或禁用)按鈕,由參數b決定

void setVisible(boolean b) 設置按鈕是否為可見,由參數b決定

void setToolTipText(String text) 設置按鈕的懸停提示信息

void setMnemonic(int mnemonic) 設置按鈕的快捷鍵

2.JLabel

既可以顯示文本,也可以顯示圖像;

JLabel() 創建一個空的標簽

JLabel(String text) 創建一個帶文本的標簽

JLabel(String text, int ha) 創建一個帶文本的標簽,並指定其對齊方式,可以是JLabel.LEFT、JLabel.CENTER和JLabel.RIGHT

JLabel(Icon image) 創建一個帶圖像的標簽

JLabel(Icon image, int ha) 創建一個帶圖像的標簽,並指定其對齊方式

JLabel(String text, Icon image, int ha) 創建一個帶文本和圖像的標簽,並指定其對齊方式

void setText(String text) 設置標簽上的文本

String getText() 獲得標簽上的文本

void setIcon(Icon icon) 設置標簽中的圖像

Icon getIcon() 獲得標簽中的圖像

void setHorizontalAlignment(int alignment) 設置標簽中文本的對齊方式

void setVisible(boolean b) 設置標簽是否為可見

3.JTextFiel

JTextField() 創建一個空的文本框

JTextField(String text) 創建一個帶文本的文本框

JTextField(int columns) 創建一個指定列數的空文本框

JTextField(String text, int columns) 創建一個帶文本,並指定列數的文本框

void setText(String text) 設置文本框中的文本

String getText() 獲得文本框中的文本

void setHorizontalAlignment(int alignment) 設置文本框中文本的對齊方式,可以是JTextField.LEFT、JTextField.CENTER和JTextField.RIGHT

void setEditable(boolean b) 設置文本框是否可以編輯,由參數b決定

void setEnabled(boolean enabled) 設置啟用(或禁用)文本框

void setVisible(boolean b) 設置文本框是否為可見

4.JPanel

JPanel提供面板組件,它是輕量級的容器組件;

面板中可以添加其它組件,也可以設置布局,我們一般使用面板來實現布局嵌套;

JPanel類的構造方法有4種重載方式,以下是常用的幾種:

JPanel() 創建一個空面板

JPanel(LayoutManaer layout) 創建帶有指定布局的面板

JPanel(面板)的操作方式與Container(內容面板)很相似,以下是一些常用方法

void setBackground(Color bg) 設置面板的背景色,由參數bg指定顏色

void setLayout(LayoutManager mgr) 設置面板的布局,參數是布局管理器

Component add(Component comp) 往面板中添加一個組件

Component add(Component comp, int index) 將指定組件添加到面板中的指定位置上

void remove(Component comp) 從面板中移除指定的組件

void removeAll() 從面板中移除所有組件

void repaint() 重新繪制當前面板

相關應用的代碼示例:

例一:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

class EventDemo extends JFrame {
    private JLabel lblMsg;
    private JButton btn;

    EventDemo() {
        lblMsg = new JLabel("請點擊下面的按鈕..");
        btn = new JButton("請點擊");

        Container c = this.getContentPane();
        c.setLayout(new BorderLayout());

        c.add(btn, BorderLayout.CENTER);
        c.add(lblMsg, BorderLayout.NORTH);

        this.setTitle("這是窗體標題");

        btn.addActionListener(new MyActionListener());

        this.setSize(300, 400);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }

    class MyActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            lblMsg.setText("按鈕被點擊了,我的內容變了");
        }
    }

}

class Test33 {
    public static void main(String[] args) {
        new EventDemo();
    }
}

例二:

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class EventDemo extends JFrame {
    private JLabel lblMsg;
    private JButton btnClick1;
    private JButton btnClick2;

    public EventDemo() {
        lblMsg = new JLabel("請點擊下面的按鈕...");
        btnClick1 = new JButton("確定");
        btnClick2 = new JButton("取消");
        Container cpMe = getContentPane();
        cpMe.setLayout(new FlowLayout());
        cpMe.add(lblMsg);
        cpMe.add(btnClick1);
        cpMe.add(btnClick2);
        setTitle("ActionListener Demo");
        btnClick1.addActionListener(new MyListener());
        btnClick2.addActionListener(new MyListener());

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(300, 200);
        setResizable(false); // 設置不允許用戶自行調整窗口大小
        setVisible(true);
    }

    class MyListener implements ActionListener {
        public void actionPerformed(ActionEvent ae) { // 實現事件處理函數
            ((JButton) e.getSource()).setEnabled(false); // 禁用被點擊的按鈕
            if (ae.getSource() == btnClick1) {
                lblMsg.setText("確定!");
            }
            if (ae.getSource() == btnClick2) {
                lblMsg.setText("取消!");
            }
        }
    }

    public static void main(String[] args) {
        new EventDemo();
    }

}

六、java 圖形坐標系統和圖形上下文

java中,對大部分圖形,文本,圖像的操作方法都定義在 Graphics 類中,它是java.awt程序包的一部分

1)屏幕坐標系統 略

2)圖形上下文,也稱為圖形環境

允許用戶在屏幕上繪制圖形的信息,它由 Graphics 類封裝,表示一個繪制圖層,它提供了繪制3種圖形對象(形狀,文本,圖象)

Graphics 類的對象可以通過 Component 類的 getGraphics() 方法獲得。

在遊戲程序中,常在 paint()方法內獲得 Graphics類對象,paint() 方法是Component提供的一個方法,當系統需要重繪組件時,會調用該方法,該方法只有一個參數,就是 Graphics 類的實例。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;

class MyFrameAA extends JFrame {
    MyFrameAA() {
        this.setTitle("一個遊戲程序");
        this.setSize(300, 200);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.addWindowListener(new WindowAdapter() {
            public void windowActivated(WindowEvent e) {
                repaint();
            }

        });
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        System.out.println("paint 方法被調用了");
        Color c = new Color(127, 200, 250);
        g.setColor(c);
        g.drawString("這是帶顏色的字體", 100, 50);
        g.drawRect(60, 70, 80, 80);
        g.drawLine(0, 0, 90, 90);
    }
}

class Test34 {
    public static void main(String[] args) {
        new MyFrameAA();
    }
}

七、繪制動畫

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

class GamePanel extends JPanel implements Runnable {
    GamePanel() {
        Thread t = new Thread(this);
        t.start();
    }

    private int yPos = -80;

    @Override
    public void paint(Graphics g) {
        g.clearRect(0, 0, this.getWidth(), this.getHeight());
        g.setColor(Color.green);
        g.fillOval(90, yPos, 80, 80);
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            yPos += 5;
            if (yPos > this.getHeight()) {
                yPos = -80;
            }
            repaint();
        }
    }
}

class MyWindow extends JFrame {
    MyWindow() {
        this.setTitle("遊戲");
        Container c = this.getContentPane();
        c.add(new GamePanel());
        this.setBounds(150, 150, 300, 300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }
}

class Test35 {
    public static void main(String[] args) {
        new MyWindow();
    }
}

八、定時器

Timer 組件可以定時執行任務

Timer(int delay,ActionListener l)

--start()

--stop()

--restart();

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Date;
import java.text.SimpleDateFormat;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;

class TimerDemo extends JFrame implements ActionListener {
    private JLabel lblMsg = new JLabel("這是原始值");
    private Timer timer;

    TimerDemo() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(400, 400);
        this.add(lblMsg); // 直接添到窗體上

        timer = new Timer(1000, this);
        timer.start();

        this.setVisible(true);

    }

    public void actionPerformed(ActionEvent e) {
        String str = new SimpleDateFormat("hh-mm-ss").format(new Date(eventMask));
        lblMsg.setText(str);
    }

}

class Test35 {
    public static void main(String[] args) {
        new TimerDemo();
    }
}

Java基礎——GUI編程(四)