一、   Swing相关的概念:

  1. 1.  GUI:(Graphical User Interface):图形化用户界面,通过图形化的方式提供与用户交互的平台,向用户展示信息、收集用户提交的数据。
  2. 2.  Swing:是Java用于开发图形化用户界面的一个模块,其中提供了类似于HTML的一些组件,如:按钮、输入框、文本域等。
  3. 3.  JFrame:是一个容器,是在进行Swing组件开发时的一个组织管理其他组件的特殊类,类似于Windows中的窗口,具体使用过程中可以通过“继承他”、“创建它的对象”访问其属性和方法。
  4. 4.  JPanel:面板,若将整个JFrame窗口设计为一种单一的布局模式,不能满足我们设计的需求,因此会将组件(如:按钮、输入框、文本域等)放置到JPanel中,再将JPanel放置到JFrame中。

二、   Swing中常用的组件:

  1. 1.  按钮组件(JButton)
  2. 2.  文本框(JTextField)
  3. 3.  密码框(JPasswordField)
  4. 4.  文本域(JTextArea)
  5. 5.  标签(JLabel)
  6. 6.  单选按钮(JRadioButton)
  7. 7.  复选按钮(JCheckBox)
  8. 8.  下拉按钮(JComboBox)
  9. 9.  列表框(JList)
  10. 10.     滚动窗体组件(JScrollPane)容器类组件
  11. 11.     面板(JPanel)容器类组件


三、   流式布局管理器:(FlowLayout)

流式布局管理器就像流水一样,也像打字时从上到下,从左到右依次排列。

代码参见:com.oop.ch14.FlowLayoutTest

package com.oop.ch14;

import java.awt.FlowLayout;

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

/**
 * 练习流式布局管理器的使用,从上到下,从左到右
 */
public class FlowLayoutTest extends JFrame {
    private static final long serialVersionUID = 1L;

    public static void main(String[] args) {
        FlowLayoutTest flowLayoutTest =  new FlowLayoutTest();
        flowLayoutTest.view();
        
    }

    private void view() {
        //1、创建组件元素(以按钮为例)
        JButton jb1,jb2,jb3,jb4,jb5;
        jb1 = new JButton("按钮1");
        jb2 = new JButton("按钮2");
        jb3 = new JButton("按钮3");
        jb4 = new JButton("按钮4");
        jb5 = new JButton("按钮5");
        
        //2、将以上创建号的组件元素放置到JFrame窗体中
        this.add(jb1);
        this.add(jb2);
        this.add(jb3);
        this.add(jb4);
        this.add(jb5);
        
        //3、设置JFrame窗体的一些参数
        //设置布局管理器为流式布局,对齐方式、行间距、列间距
        this.setLayout(new FlowLayout(FlowLayout.CENTER,5,10));
        //设置在关闭窗体时默认要执行的操作,通常时退出程序本身
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //设置窗体起始位置、宽高
        this.setBounds(200, 150, 200, 300);
        //设置窗体可见性
        this.setVisible(true);
        //设置窗体标题
        this.setTitle("流式布局管理器");
        
    }
}

 

四、   网格布局管理器:(GridLayout)

网格布局管理器与HTML中的table表格一样,需要设置行数、列数、行间距、列间距

代码参见:com.oop.ch14. GridLayoutTest

package com.oop.ch14;

import java.awt.GridLayout;

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

/**
 * 练习网格布局管理器GridLayout
 * 需要设置行数、列数、行间距、列间距
 *
 */
public class GridLayoutTest {
    
    public static void main(String[] args) {
        JFrame jFrame = new JFrame("网格布局管理器");
        
        //1、创建组件元素(以按钮为例)
        JButton jb1,jb2,jb3,jb4,jb5;
        jb1 = new JButton("按钮1");
        jb2 = new JButton("按钮2");
        jb3 = new JButton("按钮3");
        jb4 = new JButton("按钮4");
        jb5 = new JButton("按钮5");
        
        //2、将以上创建号的组件元素放置到JFrame窗体中
        jFrame.add(jb1);
        jFrame.add(jb2);
        jFrame.add(jb3);
        jFrame.add(jb4);
        jFrame.add(jb5);
        
        //3、设置JFrame窗体的一些参数
        //设置布局管理器为网格布局,需要设置行数、列数、列间距、行间距
        jFrame.setLayout(new GridLayout(4,3,10,15));
        //设置在关闭窗体时默认要执行的操作,通常时退出程序本身
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //设置窗体起始位置、宽高
        jFrame.setBounds(200, 150, 200, 300);
        //设置窗体可见性
        jFrame.setVisible(true);
    }
    
}

 

五、   边界布局管理器:(BorderLayout)

将容器分为东、南、西、北、中五个组成部分,通过String类型的静态常量可以设置组件元素放置在容器的哪个位置,是默认的布局管理器。

代码参见:com.oop.ch14. BorderLayoutTest

package com.oop.ch14;


import java.awt.BorderLayout;

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

/**
 * 练习使用边界 布局管理器BorderLayout
 *将容器分为东、南、西、北、中五个组成部分,
 *通过String类型的静态常量可以设置组件元素放置在容器的哪个位置,是默认的布局管理器。
 */
public class BorderLayoutTest {
    public static void main(String[] args) {
        JFrame jFrame = new JFrame("边界布局管理器");
        
        //1、创建组件元素(以按钮为例)
        JButton jb1,jb2,jb3,jb4,jb5;
        jb1 = new JButton("按钮1");
        jb2 = new JButton("按钮2");
        jb3 = new JButton("按钮3");
        jb4 = new JButton("按钮4");
        jb5 = new JButton("按钮5");
        
        //2、将以上创建号的组件元素放置到JFrame窗体中
        //通过String类型的静态常量可以设置组件元素放置在容器的哪个位置
        jFrame.add(jb1,BorderLayout.EAST);
        jFrame.add(jb2,BorderLayout.SOUTH);
        jFrame.add(jb3,BorderLayout.WEST);
        jFrame.add(jb4,BorderLayout.NORTH);
        jFrame.add(jb5,BorderLayout.CENTER);
        
        //3、设置JFrame窗体的一些参数
        
        //设置在关闭窗体时默认要执行的操作,通常时退出程序本身
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //设置窗体起始位置、宽高
        jFrame.setBounds(200, 150, 300, 300);
        //设置窗体可见性
        jFrame.setVisible(true);
    }
}

 

六、   使用面板布局(JPanel):

以上是将组件元素直接放置在窗体JFrame中,整个窗体就是一种布局管理器,不利于完成更复杂的布局,因此需要使用JPanel面板。使用的流程:组件==》面板==》窗体。

代码参见:com.oop.ch14. JPanelTest

package com.oop.ch14;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

/**
 * 练习使用面板JPanel
 * 以上是将组件元素直接放置在窗体JFrame中,整个窗体就是一种布局管理器,
 * 不利于完成更复杂的布局,因此需要使用JPanel面板。
 * 
 * 使用的流程:组件==》面板==》窗体。
 *
 */
public class JPanelTest {
    public static void main(String[] args) {
        JFrame jFrame = new JFrame("面板布局");
        
        //1、创建组件元素:按钮、输入框、密码框
        JButton jb1,jb2,jb3,jb4,jb5;
        jb1 = new JButton("按钮1");
        jb2 = new JButton("按钮2");
        jb3 = new JButton("按钮3");
        jb4 = new JButton("按钮4");
        jb5 = new JButton("按钮5");
        
        JLabel jLabel1 ;
        JLabel jLabel2;
        jLabel1 = new JLabel("用户名:");
        jLabel2 = new JLabel("密    码:");
        
        //可写30个字符
        JTextField jTextField = new JTextField(30);
        JPasswordField jPasswordField = new JPasswordField(30);
        
        //2、创建面板:用于放置上中下三块内容
        JPanel jPanel1 = new JPanel() ;
        JPanel jPanel2 = new JPanel() ;
        JPanel jPanel3 = new JPanel() ;
        //设置面板布局
        jPanel1.setLayout(new GridLayout(3,2,10,5));
        jPanel2.setLayout(new FlowLayout(FlowLayout.LEFT,5,10));
        jPanel3.setLayout(new BorderLayout(5,5));
        
        //组件放入面板
        jPanel1.add(jb1);
        jPanel1.add(jb2);
        jPanel1.add(jb3);
        jPanel1.add(jb4);
        jPanel1.add(jb5);
        
        jPanel2.add(jLabel1);
        jPanel2.add(jTextField);
        
        jPanel3.add(jLabel2,BorderLayout.WEST);
        jPanel3.add(jPasswordField);
        
        //面板放入窗体
        jFrame.add(jPanel1);
        jFrame.add(jPanel2);
        jFrame.add(jPanel3);
        
        //设置窗体布局
        jFrame.setLayout(new FlowLayout(FlowLayout.CENTER,5,10));
        //设置在关闭窗体时默认要执行的操作,通常是退出程序本身
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //设置窗体起始位置、宽高
        jFrame.setBounds(200, 150, 400, 300);
        //设置窗体可见性
        jFrame.setVisible(true);
    }
}

 

七、   使用卡片布局管理器(CardLayout):

是将组件元素放置在同一个位置,通过“事件”触发切换。

代码参见:com.oop.ch14. CardLayoutTest

package com.oop.ch14;


import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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


/**
 *练习使用卡片布局管理器 
 *
 *将组件元素放置在同一个位置,通过“事件”触发切换。
 */
public class CardLayoutTest  {
    static CardLayout cardLayout =  new CardLayout();
    static JPanel jp_images = new JPanel(cardLayout);
    
    public static void main(String[] args) {
        JFrame jFrame = new JFrame("卡片布局管理器");
        //1、定义需要的组件元素:面板、按钮
        JPanel jp_image1,jp_image2,jp_image3;
        jp_image1 = new JPanel();
        jp_image2 = new JPanel();
        jp_image3 = new JPanel();
        //设置图片面板的背景,模拟在卡片上放置一张图片
        jp_image1.setBackground(Color.RED);
        jp_image2.setBackground(Color.GREEN);
        jp_image3.setBackground(Color.BLUE);
        //创建放置卡片的面板,同时将卡片布局管理器传入其中
        //jp_images = new JPanel(cardLayout);
        //将放置了图片的子面板放置到jp_iamges中
        jp_images.add(jp_image1);
        jp_images.add(jp_image2);
        jp_images.add(jp_image3);
        //定义jp_button面板放置按钮
        JPanel jp_button;
        jp_button = new JPanel();
        //准备两个按钮
        JButton jb_pre,jb_next;
        jb_pre = new JButton("上一张");
        jb_next = new JButton("下一张");
        //将按钮放置到面板中
        jp_button.add(jb_pre,BorderLayout.WEST);
        jp_button.add(jb_next,BorderLayout.EAST);
        
        //2、将已经包含了组件元素的两个面板放置到窗体中
        jFrame.add(jp_images);
        jFrame.add(jp_button, BorderLayout.SOUTH);
        
        
        //3、设置JFrame窗体的一些参数
        //设置在关闭窗体时默认要执行的操作,通常时退出程序本身
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //设置窗体起始位置、宽高
        jFrame.setBounds(200, 150, 400, 300);
        //设置窗体可见性
        jFrame.setVisible(true);
        
        /**
         * 4、给上一张、下一张两个按钮添加点击事件
         * 具体实施时需要通过”匿名内部类“来完成
         * “匿名内部类”是一个方法中的一个类
         * 但它没有名字,他要实现ActionListener接口,并实现其中的监听方法
         */
        jb_pre.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                cardLayout.previous(jp_images);
            }
            
        });
        
        jb_next.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                cardLayout.next(jp_images);
            }
            
        });
        
    }
    
/*
    //如果实现ActionListener接口可以用实现方法的方式做
    @Override
    public void actionPerformed(ActionEvent e) {
        
        
    }*/
}


 

 

 

使用Swing和网络编程实现的demo,可以在不同主机上进行聊天

package com.oop.ch14;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.IOException;
import java.net.*;
public class GuiChat extends JFrame {
    private static final int DEFAULT_PORT = 8899;
    // 把主窗口分为NORTH、CENTER和SOUTH三个部分
    private JLabel stateLB; // 显示监听状态
    private JTextArea centerTextArea;       // 显示聊天记录
    private JPanel southPanel;               // 最下面的面板
    private JTextArea inputTextArea;        // 聊天输入框
    private JPanel bottomPanel;              // 放置 IP输入框,按钮等
    private JTextField ipTextField;         // IP输入框
    private JTextField remotePortTF;        // 端口号输入框
    private JButton sendBT;                   // 发送按钮
    private JButton clearBT;                  // 清除聊天记录按钮
    private DatagramSocket datagramSocket; // 用于后面功能的实现
private void setUpUI() {               // 初始化Swing窗口
        // 初始化窗口
        setTitle("GUI聊天");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 400);             // 设置窗口的大小
        setResizable(false);           // 窗口大小不可调整
        setLocationRelativeTo(null); // 窗口居中
        // 窗口的NORTH部分
        stateLB = new JLabel("当前还未启动监听");
        stateLB.setHorizontalAlignment(JLabel.RIGHT);
        // 窗口的CENTER部分
        centerTextArea = new JTextArea();     // 聊天记录显示区域
        centerTextArea.setEditable(false);
        centerTextArea.setBackground(new Color(211, 211, 211));
        // 窗口的SOUTH部分
        southPanel = new JPanel(new BorderLayout());
        inputTextArea = new JTextArea(5, 20);// 内容输入区域
        bottomPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
        ipTextField = new JTextField("127.0.0.1", 8);
        remotePortTF = new JTextField(String.valueOf(DEFAULT_PORT), 3);
        sendBT = new JButton("发送");
        clearBT = new JButton("清屏");
        bottomPanel.add(ipTextField);
        bottomPanel.add(remotePortTF);
        bottomPanel.add(sendBT);
        bottomPanel.add(clearBT);
        southPanel.add(new JScrollPane(inputTextArea), BorderLayout.CENTER);
        southPanel.add(bottomPanel, BorderLayout.SOUTH);
        // 添加窗口NORTH、CENTER、SOUTH部分的组件
        add(stateLB, BorderLayout.NORTH);
        add(new JScrollPane(centerTextArea), BorderLayout.CENTER);
        add(southPanel, BorderLayout.SOUTH);
        setVisible(true);
    }
private void setListener() {
          // 为sendBT按钮添加事件监听器
        sendBT.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // 获取发送的目标ip地址和端口号
                final String ipAddress = ipTextField.getText();
                final String remotePort = remotePortTF.getText();
                // 判断ip地址和端口号是否为空
                if (ipAddress == null || ipAddress.trim().equals("")
                        || remotePort == null || remotePort.trim().equals("")) {
                    JOptionPane.showMessageDialog(GuiChat.this, "请输入IP地址和端口号");
                    return;
                }
                if (datagramSocket == null || datagramSocket.isClosed()) {
                    JOptionPane.showMessageDialog(GuiChat.this, "监听不成功");
                    return;
                }
                // 获得需要发送的内容
                String sendContent = inputTextArea.getText();
                byte[] buf = sendContent.getBytes();
                try {
                    // 将发送的内容显示在自己的聊天记录中
                    centerTextArea.append("我对 " + ipAddress + ":" + remotePort
                            + " 说:\n" + inputTextArea.getText() + "\n\n");
                    // 添加内容后,使滚动条自动滚动到最底端
                    centerTextArea.setCaretPosition(centerTextArea.getText()
                            .length());
                    // 发送数据
                    datagramSocket.send(new DatagramPacket(buf, buf.length,
                            InetAddress.getByName(ipAddress), Integer
                                    .parseInt(remotePort)));
                    inputTextArea.setText("");
                } catch (IOException e1) {
                    JOptionPane.showMessageDialog(GuiChat.this, "出错了,发送不成功");
                    e1.printStackTrace();
                }
            };
        });
         // 为clearBT按钮添加事件监听器
        clearBT.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                centerTextArea.setText(""); // 清空聊天记录的内容
            }
        });
    }
private void initSocket() {
        int port = DEFAULT_PORT;
        while (true) {
            try {
                if (datagramSocket != null && !datagramSocket.isClosed()) {
                    datagramSocket.close();
                }
                try { // 判断端口号是否在1-65535之间
                    port = Integer.parseInt(JOptionPane.showInputDialog(this,
                            "请输入端口号", "端口号", JOptionPane.QUESTION_MESSAGE));
                    if (port < 1 || port > 65535) {
                        throw new RuntimeException("端口号超出范围");
                    }
                } catch (Exception e) {
                    JOptionPane.showMessageDialog(null,
                            "你输入的端口不正确,请输入1-65535之间的数");
                    continue; // 端口不正确重新填写
                }
                // 启动DatagramSocket
                datagramSocket = new DatagramSocket(port);
                startListen(); // 调用startListen方法
                // 在stateLB中显示程序监听的端口号
                stateLB.setText("已在 " + port + " 端口监听");
                break;
            } catch (SocketException e) { // 端口号被占用重新填写
                JOptionPane.showMessageDialog(this, "端口已被占用,请重新设置端口");
                stateLB.setText("当前还未启动监听");
            }
        }
    }
private void startListen() {
        new Thread() {
            private DatagramPacket p;
            public void run() {
                byte[] buf = new byte[1024];
                // 创建DatagramPacket
                p = new DatagramPacket(buf, buf.length);
                while (!datagramSocket.isClosed()) {
                    try {
                        datagramSocket.receive(p); // 接收聊天消息
                        // 添加到聊天记录框
                        centerTextArea.append(p.getAddress().getHostAddress()
                                + ":"
                                + ((InetSocketAddress) p.getSocketAddress())
                                        .getPort() + " 对我说:\n"
                                + new String(p.getData(), 0, p.getLength())
                                + "\n\n");
                        // 使滚动条自动滚动到最底端
                        centerTextArea.setCaretPosition(centerTextArea
                                .getText().length());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }
    public GuiChat() {
        setUpUI();
        initSocket();
        setListener();
    }
    public static void main(String[] args) {
        new GuiChat();
    }
}