GUI-图形化的用户界面

发布于:2024-05-10 ⋅ 阅读:(31) ⋅ 点赞:(0)

一、概述 

所谓GUI,即图形化的用户界面/接口(Graphical User Interface),实现了采用图形方式显示的计算机操作用户界面。比如下面的QQ登录界面:

为了不被落下,Java依旧稳定发挥,它也提供了一套可以轻松构建GUI的工具,将GUI界面封装为类,其中若干类放在了java.awt包和javax.swing包内:

java.awt

(抽象窗口工具包)

依赖于本地操作系统的GUI,缺乏平台独立性,属重量级控件

包中主要包括界面组件、布局管理器、事件处理模型及图形和图像工具...

java.swing

完全由java实现,增强了可移植性,属轻量级控件;

在AWT的基础上建立的一套图形化界面系统,提供了更多的组件;

Swing中的类是从AWT继承的,有些Swing类直接扩展AWT中对应的类(JFrame、JPanel、JButton)

   

还去查了下swing是啥的缩写啥意思,来源...查到一个比较可信比较满意的结果,没啥意思..:

Swing和AWT之间的最明显的区别是界面组件的外观:一个基于Swing的应用程序可能在任何平台上都一样;而AWT依赖于本地操作系统在不同平台上运行相同的程序,界面的外观和风格可能会有一些差异

二、编程步骤

1、创建容器

Java容器(Container)实际上是Component的子类,因此容器类对象本身也是一个组件,具有组件的所有性质,另外还具有容纳其他组件和容器的功能

分类

顶层容器:

  • JFrame(框架窗口)
  • JDialog(对话框)
  • JApplet(嵌入在网页中的Java小程序)

中间容器:

  • JPanel:最常用灵活
  • JScrollPane:可在大的组件或可扩展组件周围提供滚动条
  • JTabbedPane:包含多个组件,但一次只显示一个组件,用户可在组件之间方便的切换
  • JToolBar:换行或排列一组组件(通常是按钮)

下面我们都以顶层容器为JFrame(框架窗口)为例来讲解GUI的应用

框架窗口JFrame

Swing组件的顶层容器,继承了AWT的Frame类,支持Swing体系结构的高级GUI属性

常用构造方法:JFrame()、JFrame(String title)

常用方法:

setLocation(int x,int y) 位置

setLocationRelativeTo(null)

居中
setSize(int x,int y) 大小

setResizable(true)

可调整大小

setVisible(true)

可视化窗口(必须要有)
setContentPane(Container contentPane)、getContentPane() 设置/返回此窗体的 contentPane 对象
setLayout(LayoutManager manager) 设置LayoutManager属性 
setDefaultCloseOperation(int operation)、getDefaultCloseOperation() 设置/返回用户在此窗体上单击“关闭”按钮时默认执行的操作
setIconImage(Image image) 窗口图标显示的图
setMenuBar(JMenuBar menubar) 设置窗口的菜单栏

创建一个简单的空窗口:

 在早期的java版本中,对JFrame添加组件有两种方式:

  •  用getContentPane()方法获得JFrame的内容面板rootpanel,再对其加入组件:
    f.getContentPane().add(childComponent)
  • 建立一个中间容器p,把该容器置为JFrame的内容面板,再对其加入组件:
    JPanel p=new JPanel();//创建中间面板
    .....//把其它组件添加到中间容器中
    f.setContentPane(p);//把中间容器p对象设置成为frame的内容面板

这时候还是不可以直接往JFrame内直接添加组件的,否则会抛出异常,因为JFrame 不是一个容器,它只是一个框架!

ContentPane是一个Swing容器类,它是Frame、JDialog和JApplet的默认容器,用于承载和管理其他GUI组件,以构建窗口界面。在创建JFrame就会自动创建了ContentPane,getContentPane()获取其默认对象对象。

但是大人现在时代不同了!已经简化为可以直接向JFrame添加组件了,实际上还是向内容面板进行了添加,只是代码上简洁了

frame.add(child);

可以通过阅读java源代码得知:

但是我们在对JFrame设置背景颜色后界面仍是白色的,原因很简单,创建JFrame时自动生成的rootpanel覆盖在JFrame之上,即便对JFrame设置背景色,白色的rootpanel覆盖上去又是白的了,l所以要么对rootpanel设置背景色,要么添加个you'yan

中间容器JPane

常用构造方法:JPanel(),JPanel(LayoutManager layout)

常用方法:

void add(Component comp) 在容器中添加指定的组件
void remove(Component comp) 从容器中移除指定的组件
void setFont(Font f) 设置容器的字体
void setBackground(Color c) 设置组件的背景色

JFrame与JPanel的区别
  • JFrame可以独立存在、可被移动、可被最大化和最小化;有标题栏、边框,可添加菜单栏;默认布局BorderLayout(边界布局)
  • JPanel不能独立运行,必须包含在另一个容器中;没有标题、边框,不可添加菜单栏;默认布局FlowLayout(流式布局)

2、添加组件

添加组件用于和用户交互 (Java图形用户界面的最基本组成部分)

基本组件
组件 构造方法(举例参数最全的一个) 常用方法

标签组件 JLabel()

显示单行文本信息的组件,一般用来显示固定的提示信息

JLabel(String text,Icon image,int honrizontalAlignment)

水平对齐方式取值:JLabelLEFT、JLabelRIGHT、JLabelCENTER

setText(String text)

getText()

setIcon(Icon image)

getIcon()

按钮组件 JButton

最简单的按钮组件,只在按下和释放两个状态之间进行切换

JButton(String text、Icon image)

setText(String text)

setMargin(Insets m)

setEnable(boolean flag) setHorizontalAlignment(int align) setVerticalAlignment(int alig)

文本框JTextFiled

JTextFiled(String text,int columns) setColumns(int columns) setFront(Font f) setHorizontalAlignment(int alignment)
JTextArea文本区域 JTextArea(String text,int rows,int columns)

append(String str)

setColuns(int columns)

getColumns()获取行数

getRows()

setLineWrap(boolean wrap)

另外还有JCeckBox复选框、JToggleButton开关按钮、JPassword密码框、JComboBox下拉列表框、JList列表、JProgressBar进度条、JSilder滑块,菜单组件(菜单栏JMenuBar、下拉菜单JMenu、菜单项JMenuIte)

3、安排组件

为了更好的实现跨平台,可以通过相对量衡量、布局管理器Layout Manager、相关属性进行设置

绝对定位

在Java中可以通过绝对定位的方式进行布局,运用绝对定位时需要注意以下几点:

JFrame的布局方式要设置为null  例如:

jframe.setLayout(null)

需要设置x坐标、y坐标,width组件宽度,height组件高度 例如

组件.setBounds(x,y,w,h) 

布局管理器Layout Manager

在使用Swing向容器添加组件时,需要考虑组件的位置和大小。如果不使用布局管理器,则需要先在纸上画好各个组件的位置并计算组件间的距离,再向容器中添加,这样虽然能够灵活控制组件的位置,实现却非常麻烦。

为了加快开发速度,Java提供了一些布局管理器,他们可以将组件进行统一管理,这样开发人员就不需要考虑组件是否会重叠等问题。有以下6种:

边框布局BorderLayout、流式布局FlowLayout、网格布局GirdLayout、卡片布局CardLayout、盒布局BoxLayout、空布局null(绝对定位时设置)

接下来把这几种布局管理器都演示一遍:

 

 

 

4、处理事件

相关概念

案例1:点击不同的按钮,面板改变响应背景颜色

  • 事件:点击(用户所执行的动作)
  • 事件源:按钮(动作发生的对象)
  • 事件处理:变色(当用户在某组件上执行某事件,则进行相应处理)
  • 监听器:时刻监听事件源上所有发生的事件类型,一旦该事件类型与自己所负责处理的事件                  类型一致,就马上进行处理
常用事件对应的监听器接口

事件类型( java.awt.event )

监听器接口 监听器接口抽象方法
动作事件 ActionEvent ActionListener actionPerfermed()
鼠标事件 MouseEvent MouseListener

mouseClicked(MouseEvent e)

mousePressed(MouseEvent e)

mouseReleased(MouseEvent e)

mouseEntered(MouseEvent e)

mouseExited(MouseEvent e)

鼠标移动事件 MouseMotionEvent MouseMotionListener

mouseDragged(MouseEvent e)
mouseMoved(MouseEvent e)

键盘事件 KeyEvent KeyListener

keyTyped(KeyEvent e)

keyPressed(KeyEvent e)

keyReleased(KeyEvent e)

 下面来写一下上述案例代码:

使用内部类
public class demo1 extends JFrame{
    JPanel p;
    JButton jRed,jGreen,jYellow;
    public demo1(){
        super("事件测试-改变颜色");
        p=new JPanel();
        jRed=new JButton("红色");
        jGreen=new JButton("绿色");
        jYellow=new JButton("黄色");

        //2、创建一个监听器组件
        ButtonListener buttonListener=new ButtonListener();
        //3、注册监听
        jRed.addActionListener(buttonListener);
        jGreen.addActionListener(buttonListener);
        jYellow.addActionListener(buttonListener);

        p.add(jRed);
        p.add(jGreen);
        p.add(jYellow);
        this.add(p);

        this.setBounds(400,500,700,650);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    //1、创建扩展ActionListener的监听类
        /*该监听器类是一个内部类,外部类 可以直接对外部类中的资源进行访问*/
    class ButtonListener implements ActionListener{
        //重写事件处理方法
        @Override
        public void actionPerformed(ActionEvent e) {
            //获取事件源并判断
            Object souce=e.getSource();
            if(souce==jRed){
                p.setBackground(Color.red);
            }else if(souce==jGreen){
                p.setBackground(Color.green);
            }else{
                p.setBackground(Color.yellow);
            }
        }
    }

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

}
直接使用匿名内部类 
public class demo2 extends JFrame{
    JPanel p;
    JButton bR,bG,by;

    public demo2(){
        super("匿名监听类实现");
        p=new JPanel();
        bR=new JButton("红");
        bG=new JButton("绿");
        by=new JButton("黄");

        //直接使用匿名监听类注册监听
        bR.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                p.setBackground(Color.red);
            }
        });
        bG.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                p.setBackground(Color.GREEN);
            }
        });
        by.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                p.setBackground(Color.yellow);
            }
        });

        p.add(bR);
        p.add(bG);
        p.add(by);
        this.add(p);
        this.setBounds(400,500,700,650);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }
    public static void main(String[] args) {
        new demo2();
    }
}

案例2:创建一个窗口,在窗口中加入一个按钮组件,用适配器类实现:当鼠标进入按钮,则改变按钮文字内容,记录进入次数。

上面动作监听器的实现使用内部类或匿名内部类是比较方便的,,但是看一下鼠标监听器接口,若我只是要监听鼠标进入按钮,而不用监听其他鼠标事件,还要实现鼠标监听器接口全部抽象方法是不是太过分了呢?

适配器类

为了简化代码,JDK提供了对应的适配器类,该类是对应接口的实现类

  • MouseListener —> MouseAdapter
  • KeyListener —> KeyAapter
  • MouseMotionListener —>MouseMotionAdapter

 下面利用适配器类来写下案例2:

public class demo3 extends JFrame{
    JPanel p;
    JButton b;
    int count=0;
    
    public demo3(){
        p=new JPanel();
        b=new JButton("鼠标已进入本按钮"+count+"次");
        p.add(b);
        //b.addMouseListener(new myListener());
        b.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                b.setText("鼠标已进入本按钮"+(++count)+"次");
            }
        });
        this.add(p);
        this.setBounds(400,300,700,500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }
    /*class myListener extends MouseAdapter{
        @Override
        public void mouseEntered(MouseEvent e) {
            b.setText("鼠标已进入本按钮"+(++count)+"次");
        }
    }*/
    public static void main(String[] args) {
        new demo3();
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到