目录
(一)共用代码
(二)按钮事件
(三)更改主题
(四)按钮与击键动作
(五)鼠标操作
首页 Java java教程 java图形化Swing教程(二)

java图形化Swing教程(二)

Mar 01, 2017 am 11:24 AM


与多线程、泛型等不同,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

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
威尔R.E.P.O.有交叉游戏吗?
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Java 中的完美数 Java 中的完美数 Aug 30, 2024 pm 04:28 PM

Java 完美数指南。这里我们讨论定义,如何在 Java 中检查完美数?,示例和代码实现。

Java中的Weka Java中的Weka Aug 30, 2024 pm 04:28 PM

Java 版 Weka 指南。这里我们通过示例讨论简介、如何使用weka java、平台类型和优点。

Java 中的史密斯数 Java 中的史密斯数 Aug 30, 2024 pm 04:28 PM

Java 史密斯数指南。这里我们讨论定义,如何在Java中检查史密斯号?带有代码实现的示例。

Java Spring 面试题 Java Spring 面试题 Aug 30, 2024 pm 04:29 PM

在本文中,我们保留了最常被问到的 Java Spring 面试问题及其详细答案。这样你就可以顺利通过面试。

突破或从Java 8流返回? 突破或从Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一种强大且表达力丰富的处理数据集合的方式。然而,使用Stream时,一个常见问题是:如何从forEach操作中中断或返回? 传统循环允许提前中断或返回,但Stream的forEach方法并不直接支持这种方式。本文将解释原因,并探讨在Stream处理系统中实现提前终止的替代方法。 延伸阅读: Java Stream API改进 理解Stream forEach forEach方法是一个终端操作,它对Stream中的每个元素执行一个操作。它的设计意图是处

Java 中的时间戳至今 Java 中的时间戳至今 Aug 30, 2024 pm 04:28 PM

Java 中的时间戳到日期指南。这里我们还结合示例讨论了介绍以及如何在java中将时间戳转换为日期。

Java程序查找胶囊的体积 Java程序查找胶囊的体积 Feb 07, 2025 am 11:37 AM

胶囊是一种三维几何图形,由一个圆柱体和两端各一个半球体组成。胶囊的体积可以通过将圆柱体的体积和两端半球体的体积相加来计算。本教程将讨论如何使用不同的方法在Java中计算给定胶囊的体积。 胶囊体积公式 胶囊体积的公式如下: 胶囊体积 = 圆柱体体积 两个半球体体积 其中, r: 半球体的半径。 h: 圆柱体的高度(不包括半球体)。 例子 1 输入 半径 = 5 单位 高度 = 10 单位 输出 体积 = 1570.8 立方单位 解释 使用公式计算体积: 体积 = π × r2 × h (4

如何在Spring Tool Suite中运行第一个春季启动应用程序? 如何在Spring Tool Suite中运行第一个春季启动应用程序? Feb 07, 2025 pm 12:11 PM

Spring Boot简化了可靠,可扩展和生产就绪的Java应用的创建,从而彻底改变了Java开发。 它的“惯例惯例”方法(春季生态系统固有的惯例),最小化手动设置

See all articles