首頁  >  文章  >  Java  >  java圖形化Swing教學(二)

java圖形化Swing教學(二)

黄舟
黄舟原創
2017-03-01 11:24:351619瀏覽


與多執行緒、泛型等不同,Swing主要在於使用。  
以下主要放程式碼和註釋,少說話。

(一)共用程式碼

所有繼承JFrame的類別都要有一個開始的框架來包含他們,這裡直接給出框架,以下幾點中不會重複書寫。

package Event;import java.awt.*;import javax.swing.*;/**
 * 
 * @author QuinnNorris
 * 共用代码
 */public class BaseFrame {
    /**
     * @param args
     */
    public static void main(String[] args) {        
    // TODO Auto-generated method stub

        // 开启一个线程,所有的Swing组件必须由事件分派线程进行配置,线程将鼠标点击和按键控制转移到用户接口组件。
        EventQueue.invokeLater(new Runnable() {            
        // 匿名内部类,是一个Runnable接口的实例,实现了run方法
            public void run() {

                JFrame frame = new *********();                
                // 将*号的地方换成你实现的JFrame的子类,来实现你的代码

                frame.setExtendedState(Frame.MAXIMIZED_BOTH);                
                // 将窗口最大化

                frame.setTitle("Christmas");                
                // 设置窗口标题

                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                
                // 选择当用户关闭框架的时候进行的操作 ,在有些时候需要将窗口隐藏,不能直接退出需要用到这个方法

                frame.setVisible(true);                
                // 将窗口可见化,这样以便用户在第一次看见窗口之前我们能够向其中添加内容
            }

        });
    }

}

輸出結果:得到一個基本的公用框架,以後的內容可以在其他類別中書寫,放入這個框架。

(二)按鈕事件

package Event;import java.awt.*;import javax.swing.*;import java.awt.event.*;/**
 * 
 * @author QuinnNorris 按钮事件
 */public class ButtonFrame extends JFrame {

    private JPanel buttonPanel;    
    private static final int DEFAULT_WIDTH = 300;    
    private static final int DEFAULT_HEIGHT = 200;    
    public ButtonFrame() {
        setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);        // 设置默认宽度和高度

        buttonPanel = new JPanel();        // 将类的实例域中的JPanel面板对象实例化

        makeButton("yellow",Color.YELLOW);
        makeButton("blue",Color.BLUE);
        makeButton("red",Color.RED);        //调用makeButton方法来创建并添加按钮

        add(buttonPanel);        // 我们将这个添加好按钮的面板添加到原框架中


    }    /**
     * 通过方法来创建按钮,并且完成关联监视器和添加入面板的操作
     * @param name 创建按钮的标识
     * @param backgroundColor 点击按钮后改变的颜色,匿名内部类只能访问final修饰的变量,所以要用final
     */
    public void makeButton(String name,final Color backgroundColor){

        JButton colorButton = new JButton(name);        
        //通过不同的标识名,我们创建按钮

        buttonPanel.add(colorButton);        
        //我们将创建的按钮添加到面板中

        //匿名内部类,创建一个ActionListener的实例
        colorButton.addActionListener(new ActionListener(){            
        /**
             * 当按钮点击的时候,会自动的调用actionPerformed方法
             */
            public void actionPerformed(ActionEvent event) {

                buttonPanel.setBackground(backgroundColor);                
                // 调用setBackground方法,设置背景颜色
            }
        });
    }

}

輸出結果:在一個全螢幕視窗中,上方有三個不同顏色的按鈕,按下去後,背景顏色會跟著改變。

(三)更改主題

package Event;import java.awt.*;import javax.swing.*;import java.awt.event.*;/**
 * 
 * @author QuinnNorris 更换主题
 */public class MetalFrame extends JFrame {

    private JPanel buttonPanel;    
    private static final int DEFAULT_WIDTH = 300;    
    private static final int DEFAULT_HEIGHT = 200;    
    public MetalFrame() {

    
        setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);        // 设置默认宽度和高度

        buttonPanel = new JPanel();        // 将类的实例域中的JPanel面板对象实例化

        UIManager.LookAndFeelInfo[] infos = UIManager
                .getInstalledLookAndFeels();        // 调用这个静态方法,我们获得所有主题

        makeButton(infos);        // 调用makeButton方法来将主题实现

        add(buttonPanel);        // 我们将这个添加好按钮的面板添加到原框架中
    }    /**
     * 通过方法来创建所有的主题按钮,并且将他们关联监视器
     * 
     * @param infos
     *            包含有所有类型主题的数组
     */
    private void makeButton(final UIManager.LookAndFeelInfo[] infos) {        
    for (UIManager.LookAndFeelInfo info : infos) {
            JButton button = new JButton(info.getName());            
            // 用for-each循环来遍历所有的主题

            final UIManager.LookAndFeelInfo innerInfo = info;            
            // 将info复制并且定义位final类型,便于内部类的使用

            buttonPanel.add(button);            
            // 我们将创建的按钮添加到面板中

            // 匿名内部类,创建一个ActionListener的实例
            button.addActionListener(new ActionListener() {                
            /**
                 * 当按钮点击的时候,会自动的调用actionPerformed方法
                 */
                public void actionPerformed(ActionEvent ae) {                    
                try {

                        UIManager.setLookAndFeel(innerInfo.getClassName());                       
                        // 调用setLookAndFeel方法,更改主题

                        SwingUtilities.updateComponentTreeUI(buttonPanel);                        
                        // 通过这个静态方法,将更改的主题立即应用

                    } catch (Exception e) {                        
                    // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            });
        }

    }

}

輸出結果:視窗上方有五個主題按鈕,分別寫著他們各自主題的名字,點擊後會立即更改所屬主題。

(四)按鈕與擊鍵動作

package Event;import javax.swing.*;import java.awt.*;import java.awt.event.*;/**
 * 
 * @author QuinnNorris 按钮与击键动作
 */public class ActionFrame extends JFrame {

    private JPanel buttonPanel;    
    private static final int DEFAULT_WIDTH = 300;    
    private static final int DEFAULT_HEIGHT = 200;    
    public ActionFrame() {

        setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);        
        // 设置默认宽度和高度

        buttonPanel = new JPanel();        
        // 将类的实例域中的JPanel面板对象实例化

        Action yellowAction = new ColorAction("Yellow", Color.YELLOW);        
        // 创建一个自己定义的ColorAction对象yellowAction

        buttonPanel.add(new JButton(yellowAction));        
        // 创建一个按钮,其属性从所提供的 Action中获取

        add(buttonPanel);        
        // 我们将这个添加好按钮的面板添加到原框架中

        InputMap imap = buttonPanel
                .getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);        
                // 我们将JPanel对象的InputMap设置为第二种输入映射,并创建该对象

        imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");        
        // 在imap中通过调用击键类KeyStroke的静态方法设置击键输入ctrl+Y的组合
        // 第二个参数是一个标志参数,将这对参数用键值对的形式存入imap

        ActionMap amap = buttonPanel.getActionMap();        
        // 我们不能将InputMap直接和Action做映射,我们需要用ActionMap做过渡
        // 用JPanel中的getACtionMap方法获得amap对象

        amap.put("panel.yellow", yellowAction);        
        // 将imap中标记参数对应的击键组合和相应的Action组合起来
    }    public class ColorAction extends AbstractAction {

        /**
         * ColorAction的构造器,存放键值对
         * @param name 按钮的名称
         * @param c 按钮对应点击后显示的颜色
         */
        public ColorAction(String name, Color c) {
            putValue(Action.NAME, name);
            putValue(Action.SHORT_DESCRIPTION,                    
            "Set panel color to " + name.toLowerCase());
            putValue("color", c);            
            //在构造器中设置一些键值对映射,这些设置的属性将会被JPanel读取
        }        
        /**
         * 当按钮点击或击键的时候,会自动的调用actionPerformed方法
         */
        public void actionPerformed(ActionEvent event) {
            Color c = (Color) getValue("color");
            buttonPanel.setBackground(c);            
            // 调用setBackground方法,设置背景颜色
        }
    }
}

輸出結果:視窗上方有yellow按鈕,透過點擊或者ctrl+Y都可以使背景變黃,滑鼠懸停在上面一段時間會顯示說明文字。

(五)滑鼠操作

package Event;import javax.swing.*;/**
 * 
 * @author QuinnNorris
 * 继承JFrame的子类,将Component对象内容打包
 */public class MouseFrame extends JFrame{

    public MouseFrame(){
        add(new MouseComponent());        
        //向框架中添加一个JComponent的实例
        pack();
    }
}
package Event;import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;/**
 * 
 * @author QuinnNorris 鼠标点击
 */public class MouseComponent extends JComponent {

    private static final int SIDELENGTH = 100;    
    // 定义创造的正方形的边长

    private ArrayList<Rectangle2D> squares;    
    // 声明一个正方形集合

    private Rectangle2D current;    
    // java类库中用来描述矩形的类,它的对象可以看作是一个矩形

    /**
     * 构造器方法,做初始化工作
     */
    public MouseComponent() {

        squares = new ArrayList<>();
        current = null;

        addMouseListener(new MouseHandler());        
        // 添加一个我们实现的类,这个类继承了监测鼠标点击情况的MouseListener

        addMouseMotionListener(new MouseMotionHandler());        
        // 添加另一个实现类,这个类继承了监测鼠标移动情况的MouseMotionListener
    }    /**
     * 我们覆盖了这个以用来打印图形,将会被自动调用
     * 
     * @param g
     *            Graphics是我们要使用的2D的一个父类
     */
    public void paintComponent(Graphics g) {

        Graphics2D g2 = (Graphics2D) g;        
        // 转换为我们需要使用的类型

        for (Rectangle2D r : squares)
            g2.draw(r);        
            // 对数组中的每个正方形,都进行绘制
    }    /**
     * 判断在这个坐标上是否有图形
     * 
     * @param p
     *            一对当前的x,y的坐标值
     * @return 返回存在的图形或者null
     */
    public Rectangle2D find(Point2D p) {        
    for (Rectangle2D r : squares) {            
    if (r.contains(p))                
    //contains方法测定坐标是否在图形的边界内

                return r;
        }        
        // 如果在squares这个数组中有这个位置的坐标,表明这个位置上非空
        // 返回这个位置上的对象

        return null;        
        // 否则如果什么都没有,返回null
    }    
    /**
     * 在这个坐标位置增加一个图形
     * @param p 坐标位置
     */
    public void add(Point2D p) {        
    double x = p.getX();        
    double y = p.getY();        
    //获取x和y的坐标

        current = new Rectangle2D.Double(x - SIDELENGTH / 2,
                y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH);        
                //用获得的坐标和既定的边长构建一个新的正方形,并将其赋值给current

        squares.add(current);        
        //将current添加到squares队列中

        repaint();        
        //重绘图像

    }    /**
     * 将这个位置的图形移除
     * @param s 代表所要移除的矩形对象
     */
    public void remove(Rectangle2D s) {        
    if (s == null)            
    return;        
    //如果要移除的内容为空,直接返回

        if (s == current)
            current = null;        
            //如果要移除的内容和current正指向的内容相同,则将current清空
        //避免发生不必要的错误

        squares.remove(s);        
        //将s从squares的列表中直接删去

        repaint();        
        //重绘图像
    }    
    /**
     * 
     * @author QuinnNorris 继承了MouseAdapter类的鼠标点击控制类
     */
    private class MouseHandler extends MouseAdapter {

        /**
         * 单击鼠标操作
         */
        public void mousePressed(MouseEvent event) {

            current = find(event.getPoint());            
            // 将鼠标单击的这个点的坐标的对象赋给current

            if (current == null)                
            //如果这个点没有对象,当前指向空的位置

                add(event.getPoint());                
                //在这个点绘制正方形
        }        
        /**
         * 鼠标双击操作
         */
        public void mouseClicked(MouseEvent event) {

            current = find(event.getPoint());            
            // 将鼠标单击的这个点的坐标的对象赋给current

            if (current != null && event.getClickCount() >= 2)                
            //如果这个点有对象,而且点击鼠标的次数大于2

                remove(current);                
                //移除current

        }
    }    
    /**
     * 
     * @author QuinnNorris
     * 鼠标移动拖动类
     */
    private class MouseMotionHandler implements MouseMotionListener {

        /**
         * 鼠标光标移动到组件上,但未按下时调用
         */
        public void mouseMoved(MouseEvent event) {            
        if (find(event.getPoint()) == null)                
        //如果鼠标所在位置不是空

                setCursor(Cursor.getDefaultCursor());                
                //则将光标的图像设置为默认的图像
            else
                setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));                
                //如果当前位置有图像,则将光标样式设置为手型
        }        /**
         * 鼠标光标在组件上按下,并拖动时调用
         */
        public void mouseDragged(MouseEvent event) {            
        if (current != null) {                
        //因为在调用这个方法之前肯定会调用点击鼠标的方法
                //所以我们直接判断:如果现在current不为空

                int x = event.getX();                
                int y = event.getY();                
                //获取到坐标

                current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2,
                        SIDELENGTH, SIDELENGTH);                
                        //最后在鼠标放下时进行图形绘制

                repaint();                
                //重绘图像
            }
        }
    }

}

輸出結果:在這個窗體中,按一下滑鼠會建立一個100像素為邊長的小正方形。在正方形內,雙擊或更多次點擊會刪除這個正方形。可以點住正方形並進行拖曳,並且在指示正方形區域內時,滑鼠指標會變成手型指標。

與多執行緒、泛型等不同,Swing主要在於使用。  
以下主要放程式碼和註釋,少說話。

 以上就是java圖形化Swing教學(二)的內容,更多相關內容請關注PHP中文網(www.php.cn)!


#
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn