原创

开发篇:Linux下的swing窗体程序开发

2022-04-25 15:17:13 星期一


    为完成大三下 Linux 课程的结课作业,我用 swing 为银河麒麟V10操作系统做了一个简单的带有图形界面的用户管理工具。现将开发过程记录于此,留作今后参考。本博文将从模板构建开始,一步步记录直到实现所有具体的功能需求,从零开始开发一个完整的 Linux 窗体程序。本次开发过程中遇到的 bug 已全部汇总到另一篇文章:《特别篇:Linux图形工具开发中遇到的坑》

    开发环境:Windows 10
    开发工具:IntelliJ IDEA
    测试环境:银河麒麟 V10

    本程序的功能需求:
    1、程序包含用户清单、用户增加界面、用户删除界面、用户参数设置界面四个功能模块。
    2、用户清单:列出全部的用户;包括用户的各种详细信息。
    3、 用户增加界面:可以快速增加新的用户;可以添加用户组。
    4、用户删除界面:可以删除用户;可删除用户组。
    5、用户参数设置:设置所选用户的密码、用户使用的shell、可快速更换用户的用户组。

根据上述需求,我将本程序划分为五个模块,通过对这五个模块的剖析(从界面设计到功能实现)来讲解我的设计思路与开发流程。

模块1:程序主窗体

    首先创建一个 JFrame 用以承载其它的显示面板,然后创建 JPanel ,再创建四个按钮:用户清单、用户增加界面、用户删除界面、用户参数设置界面,将这四个按钮全部添加到面板 JPanel ,最后将 JPanel 加载到 JFrame 中。代码如下:

package com.hyc;

import javax.swing.*;
import java.awt.*;

public class MainForm {
    public static void main(String[] args) {
        JFrame jf=new JFrame("用户管理工具");
        jf.setBounds(500, 250, 800, 600);
        JPanel jp=new JPanel();
        jp.setBackground(Color.white);
        jf.add(jp);
        jf.setVisible(true);

        JButton b1=new JButton("用户清单");
        JButton b2=new JButton("用户增加界面");
        JButton b3=new JButton("用户删除界面");
        JButton b4=new JButton("用户参数设置");
        jp.add(b1);
        jp.add(b2);
        jp.add(b3);
        jp.add(b4);
    }
}

效果如图,可以看到在窗体中出现了四个按钮:

模块2:用户清单

    首先定义一个 JFrame,并构建一个 Object 类的二维数组用以存放用户清单的数据(为什么要用二维数组,因为 JTable 的构造方法只允许用 Object 类的二维数组去接收 JTable 的内容),然后构建一个 String 数组用来存放用户清单的七个列名:用户名、密码、用户 ID、用户所在组 ID、备注、用户家目录、shell 命令所在目录,最后再为 JTable 加上一个滚动条代码如下:

package com.hyc;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class UserList {

    //绘制用户清单表格
    public void getTable(){
        JFrame f = new JFrame();
        f.setBounds(600, 300, 800, 400);
        Object[][] obj = {
                // 创建表格中的数据
                { "a", "sss", "sss", "sss",
                        "sss" , "sss", "sss"},
                { "a", "sss", "sss", "sss",
                        "sss" , "sss", "sss"},
                { "a", "sss", "sss", "sss",
                        "sss" , "sss", "sss"},
                { "a", "sss", "sss", "sss",
                        "sss" , "sss", "sss"},
                { "a", "sss", "sss", "sss",
                        "sss" , "sss", "sss"}, };
        // 创建表格中的横标题
        String[] Names = { "用户名", "密码", "用户ID", "用户所在组ID", "备注","用户家目录","shell命令所在目录"};
        // 以Names和playerInfo为参数,创建一个表格
        JTable table = new JTable(obj, Names);
        // 设置此表视图的首选大小
        table.setPreferredScrollableViewportSize(new Dimension(800, 400));
        // 将表格加入到滚动条组件中
        JScrollPane scrollPane = new JScrollPane(table);
        f.getContentPane().add(scrollPane, BorderLayout.CENTER);
        // 再将滚动条组件添加到中间容器中
        f.setTitle("用户清单");
        f.pack();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
    
    public static void main(String[] args) {
        UserList userList = new UserList();
        userList.getTable();
    }
}

效果如图,可以看到用户清单窗体及其七个参数列名都已经成功显示,(由于尚未开发此模块功能,为了便于测试窗体的显示,我在 Object 中随意写入了一些数据用作展示)

模块3:用户增加界面

    首先定义两个按钮(增加用户、增加用户组),两个文本框(用户、用户组),三个面板(用以分层次装载用户文本框、用户组文本框、两个按钮)。然后分别将三个层次的控件装入三个面板中,最后将三个面板加载到 JFrame,代码如下:

package com.hyc;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class AddUserAndGroup extends JFrame implements ActionListener {
    JButton Button_addUser, Button_addUserGroup;  //按钮
    JPanel jp1,jp2,jp3;        //面板
    JTextField jtf;   //用户文本框
    JLabel jlb1, jlb2, jlb3; //标签
    JTextField jpf; //用户组文本框

    public void addUserAndGroup() {
        LinuxInstructions linuxInstructions = new LinuxInstructions();
        Button_addUser = new JButton("增加用户");
        Button_addUserGroup = new JButton("增加用户组");

        jp1 = new JPanel();  //创建面板
        jp2 = new JPanel();
        jp3 = new JPanel();

        jlb1 = new JLabel("用户名:");  //添加标签
        jlb2 = new JLabel("用户组:");

        jtf = new JTextField(10);  //创建文本框和密码框
        jpf = new JTextField(10);

        //加入面板中
        jp1.add(jlb1);
        jp1.add(jtf);

        jp2.add(jlb2);
        jp2.add(jpf);

        jp3.add(Button_addUser);
        jp3.add(Button_addUserGroup);

        //将JPane加入JFrame中
        this.add(jp1);
        this.add(jp2);
        this.add(jp3);

        //设置布局
        this.setTitle("用户增加");
        this.setLayout(new FlowLayout());
        this.setSize(300, 200);   //设置窗体大小
        this.setLocationRelativeTo(null);//在屏幕中间显示(居中显示)
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);  //设置可关闭

        this.setVisible(true);  //设置可见
        this.setResizable(false);   //设置不可拉伸大小
    }

    @Override
    public void actionPerformed(ActionEvent e) {

    }

    public static void main(String[] args) {
        AddUserAndGroup addUserAndGroup = new AddUserAndGroup();
        addUserAndGroup.addUserAndGroup();
    }

}

效果如图,可以看到用户清单窗体中出现了我们刚刚构建的控件:

模块4:用户删除界面

    首先创建一个只有用户名的用户清单窗体、一个只有用户组名的用户组窗体,便于我们查看当前系统中存在的用户和用户组。再创建一个删除界面窗体(参照模块3),代码如下:

package com.hyc;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

public class DeleteUserAndGroup {

    //绘制用户清单表格
    public void getTable(){
        JFrame f = new JFrame();
        f.setBounds(200, 300, 800, 400);
        ArrayList<Object[]> alist = new ArrayList<>();
        for (int i = 0;i<alstring.size();i++){
            String[] split = alstring.get(i).split(":");
            alist.add(new String[]{split[0]});
        }
        Object[][] obj = alist.toArray(new Object[alist.size()][]);
        // 创建表格中的横标题
        String[] Names = { "用户名"};
        // 以Names和playerInfo为参数,创建一个表格
        JTable table = new JTable(obj, Names);
        // 设置此表视图的首选大小
        table.setPreferredScrollableViewportSize(new Dimension(400, 300));
        // 将表格加入到滚动条组件中
        JScrollPane scrollPane = new JScrollPane(table);
        f.getContentPane().add(scrollPane, BorderLayout.CENTER);
        // 再将滚动条组件添加到中间容器中
        f.setTitle("用户清单");
        f.pack();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    //绘制用户组表格
    public void getGroup(){
        JFrame f = new JFrame();
        f.setBounds(650, 300, 800, 400);
        ArrayList<Object[]> alist = new ArrayList<>();
        for (int i = 0;i<alstring.size();i++){
            String[] split = alstring.get(i).split(":");
            alist.add(new String[]{split[2]});
        }
        Object[][] obj = alist.toArray(new Object[alist.size()][]);
        // 创建表格中的横标题
        String[] Names = { "用户组"};
        // 以Names和playerInfo为参数,创建一个表格
        JTable table = new JTable(obj, Names);
        // 设置此表视图的首选大小
        table.setPreferredScrollableViewportSize(new Dimension(400, 300));
        // 将表格加入到滚动条组件中
        JScrollPane scrollPane = new JScrollPane(table);
        f.getContentPane().add(scrollPane, BorderLayout.CENTER);
        // 再将滚动条组件添加到中间容器中
        f.setTitle("用户组");
        f.pack();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    //绘制删除菜单
    class DeleteUG extends JFrame implements ActionListener{
        UserList userList = new UserList();
        JButton Button_addUser, Button_addUserGroup;  //按钮
        JPanel jp1,jp2,jp3;        //面板
        JTextField jtf;   //文本框
        JLabel jlb1, jlb2; //标签
        JTextField jpf; //密码框

        public void deleteUserAndGroup() {
            LinuxInstructions linuxInstructions = new LinuxInstructions();
            Button_addUser = new JButton("删除用户");
            Button_addUserGroup = new JButton("删除用户组");

            jp1 = new JPanel();  //创建面板
            jp2 = new JPanel();
            jp3 = new JPanel();

            jlb1 = new JLabel("用户名:");  //添加标签
            jlb2 = new JLabel("用户组:");

            jtf = new JTextField(10);  //创建文本框和密码框
            jpf = new JTextField(10);

            //加入面板中
            jp1.add(jlb1);
            jp1.add(jtf);

            jp2.add(jlb2);
            jp2.add(jpf);

            jp3.add(Button_addUser);
            jp3.add(Button_addUserGroup);

            //将JPane加入JFrame中
            this.add(jp1);
            this.add(jp2);
            this.add(jp3);

            //设置布局
            this.setTitle("删除界面");
            this.setLayout(new FlowLayout());
            this.setBounds(1100,400,300,200);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);  //设置可关闭

            this.setVisible(true);  //设置可见
            this.setResizable(false);   //设置不可拉伸大小

        }

        @Override
        public void actionPerformed(ActionEvent e) {

        }
    }

    public void deleteUserAndGroup(){
        UserList userList = new UserList();
        this.getTable(userList.getUser());
        this.getGroup(userList.getUserGroup());
        DeleteUG deleteUG = new DeleteUG();
        deleteUG.deleteUserAndGroup();
    }

    public static void main(String[] args) {
        DeleteUserAndGroup deleteUserAndGroup = new DeleteUserAndGroup();
        deleteUserAndGroup.deleteUserAndGroup();
    }
}

效果如图,成功显示出我刚刚构建的三个窗体,由于未填充数据,所以前两个显示信息的窗体里没有内容:

模块5:用户参数设置界面

    首先创建一个用户参数窗体,窗体中提供用户名、用户组、用户使用的 shell 三个参数。再创建一个用户参数设置菜单,菜单中提供四个输入文本框:用户名、设置密码、设置 shell、设置 group。最后创建两个按钮:更新密码、更新 shell 和 group。代码如下:

package com.hyc;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

public class SetUserParameters {

    //绘制用户参数表格
    public void getTable(){
        JFrame f = new JFrame();
        f.setBounds(600, 300, 800, 400);
        ArrayList<Object[]> alist = new ArrayList<>();
        for (int i = 0;i<alstring.size();i++){
            String[] split = alstring.get(i).split(":");
            alist.add(new String[]{split[0], split[3],split[6]});
        }
        Object[][] obj = alist.toArray(new Object[alist.size()][]);
        // 创建表格中的横标题
        String[] Names = { "用户名","用户组","用户使用的shell"};
        // 以Names和playerInfo为参数,创建一个表格
        JTable table = new JTable(obj, Names);
        // 设置此表视图的首选大小
        table.setPreferredScrollableViewportSize(new Dimension(400, 300));
        // 将表格加入到滚动条组件中
        JScrollPane scrollPane = new JScrollPane(table);
        f.getContentPane().add(scrollPane, BorderLayout.CENTER);
        // 再将滚动条组件添加到中间容器中
        f.setTitle("用户参数");
        f.pack();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    //设置用户参数菜单
    class SetUP extends JFrame implements ActionListener {
        UserList userList = new UserList();
        JButton Button_setPassword,Button_setShellAndGroup;  //按钮
        JPanel jp1,jp2,jp3,jp4,jp5,jp6;        //面板
        JTextField jtf;   //用户名框
        JLabel jlb1,jlb2,jlb3,jlb4; //标签
        JTextField jpf; //设置密码框
        JTextField jsf; //设置shell框
        JTextField jgf; //设置group框

        public void setUP() {
            LinuxInstructions linuxInstructions = new LinuxInstructions();
            Button_setPassword = new JButton("更新密码");
            Button_setShellAndGroup = new JButton("更新shell和group");

            jp1 = new JPanel();  //创建面板
            jp2 = new JPanel();
            jp3 = new JPanel();
            jp4 = new JPanel();
            jp5 = new JPanel();
            jp6 = new JPanel();

            jlb1 = new JLabel("用户名:");  //添加标签
            jlb2 = new JLabel("设置密码:");
            jlb3 = new JLabel("设置shell");
            jlb4 = new JLabel("设置group");

            jtf = new JTextField(10);  //创建文本框
            jpf = new JTextField(10);
            jsf = new JTextField(10);
            jgf = new JTextField(10);

            //加入面板中
            jp1.add(jlb1);
            jp1.add(jtf);

            jp2.add(jlb2);
            jp2.add(jpf);

            jp3.add(jlb3);
            jp3.add(jsf);

            jp4.add(jlb4);
            jp4.add(jgf);

            jp5.add(Button_setPassword);
            jp6.add(Button_setShellAndGroup);

            //将JPane加入JFrame中
            this.add(jp1);
            this.add(jp2);
            this.add(jp3);
            this.add(jp4);
            this.add(jp5);
            this.add(jp6);

            //设置布局
            this.setTitle("用户参数设置");
            this.setLayout(new FlowLayout());
            this.setBounds(1020,300,300,500);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);  //设置可关闭

            this.setVisible(true);  //设置可见
            this.setResizable(false);   //设置不可拉伸大小
        }

        @Override
        public void actionPerformed(ActionEvent e) {

        }
    }

    public void setUserParameters(){
        UserList userList = new UserList();
        this.getTable(userList.getUser());
        SetUP setUP = new SetUP();
        setUP.setUP();
    }

    public static void main(String[] args) {
        SetUserParameters setUserParameters = new SetUserParameters();
        setUserParameters.setUserParameters();
    }
}

效果如图:


至此,模块的界面设计已全部完成,现在进行模块功能的实现。

功能1:实现获取 Linux 系统上的用户信息并显示到用户清单

    通过在模块1 Userlist 中定义两个方法来实现本功能:一个用于获取用户信息,一个用于将获取到的用户信息输出到窗体内,即 getUser() 方法与 getTable() 方法,代码如下:

    //获取用户信息的每一行,返回一个ArrayList<String>
    public ArrayList<String> getUser(){
        ArrayList<String> arrayList = new ArrayList<>();
        try {
            File file = new File("/etc/passwd");
            InputStreamReader inputReader = new InputStreamReader(new FileInputStream(file),"UTF-8");
            BufferedReader bf = new BufferedReader(inputReader);
            // 按行读取字符串
            String str;
            while ((str = bf.readLine()) != null) {
                arrayList.add(str);
            }
            bf.close();
            inputReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return arrayList;
    }
    //绘制用户清单表格
    public void getTable(ArrayList<String> alstring){
        JFrame f = new JFrame();
        f.setBounds(600, 300, 800, 400);
        ArrayList<Object[]> alist = new ArrayList<>();
        for (int i = 0;i<alstring.size();i++){
            String[] split = alstring.get(i).split(":");
            alist.add(new String[]{split[0], split[1],split[2],split[3],
                    split[4], split[5], split[6]});
        }
        Object[][] obj = alist.toArray(new Object[alist.size()][]);
        // 创建表格中的横标题
        String[] Names = { "用户名", "密码", "用户ID", "用户所在组ID", "备注","用户家目录","shell命令所在目录"};
        // 以Names和playerInfo为参数,创建一个表格
        JTable table = new JTable(obj, Names);
        // 设置此表视图的首选大小
        table.setPreferredScrollableViewportSize(new Dimension(800, 400));
        // 将表格加入到滚动条组件中
        JScrollPane scrollPane = new JScrollPane(table);
        f.getContentPane().add(scrollPane, BorderLayout.CENTER);
        // 再将滚动条组件添加到中间容器中
        f.setTitle("用户清单");
        f.pack();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

有关这两段代码的说明:getUser()方法提供 I / O 去读取 Linux 系统中 /etc/passwd 中的每一行,把读取到的每一行储存在一个 String 中,构造一个 ArrayList<String> 去存所有的 String ,最后返回这个 ArrayList<String>getTable()方法为带参方法,首先接收到 ArrayList<String>,遍历出里面的每一个 String,然后用冒号将这些 String 进行分割,将分割出来的七条字符串存放在 String 数组中,再将这个 String 数组放入 Object 二维数组内。构造一个新的 String 数组存放用户参数的七个列名,然后用这个数组与 Object 二维数组构造一个 JTable,通过 String 数组的下标去访问用户的所有参数的值,并将之填充到 JTable 中。实现效果如图:

功能2:实现为 Linux 系统增加用户、增加用户组

    首先构造一个执行器 LinuxInstructions,为 Java 程序与 Linux 系统交互提供支持。当传入 Linux 指令到 LinuxInstructions 时,执行器会将传入的指令放到 Linux 系统中执行,并返回执行的结果。然后在 UserList 中加入 getUserName()getGroupName()方法,这两个方法都会返回一个 boolean 值,用以判断待增加的用户或用户组是否已经存在。最后在模块2 AddUserAndGroup 的 addUserAndGroup()方法中监听增加用户与增加用户组这两个按钮,当发生鼠标点击事件时传入相应的指令给执行器,执行增加用户或增加用户组操作。代码如下:

package com.hyc;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

//执行器
public class LinuxInstructions {

    //Linux
    public String executeLinuxCmd(String cmd) {
        Runtime run = Runtime.getRuntime();
        try {
            Process process = run.exec(cmd);
            String line;
            BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            StringBuffer out = new StringBuffer();
            while ((line = stdoutReader.readLine()) != null ) {
                out.append(line);
            }
            try {
                process.waitFor();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            process.destroy();
            return out.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    //Java
    public String executeJava(String cmd) {
        Runtime run = Runtime.getRuntime();
        try {
            Process process = run.exec(new String[] {"/bin/sh", "-c", cmd});
            String line;
            BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            StringBuffer out = new StringBuffer();
            while ((line = stdoutReader.readLine()) != null ) {
                out.append(line);
            }
            try {
                process.waitFor();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            process.destroy();
            return out.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

    //判断用户名是否存在
    public boolean getUserName(String name){
        ArrayList<String> user = this.getUser();
        ArrayList<String> username = new ArrayList<>();
        for(int i =0;i<user.size();i++){
            String[] split = user.get(i).split(":");
            String s = split[0];
            username.add(s);
        }
        return username.contains(name);
    }

    //判断用户组是否存在
    public boolean getGroupName(String name){
        ArrayList<String> user = this.getUserGroup();
        ArrayList<String> username = new ArrayList<>();
        for(int i =0;i<user.size();i++){
            String[] split = user.get(i).split(":");
            String s = split[2];
            username.add(s);
        }
        return username.contains(name);
    }
        //设置按钮监听
        Button_addUser.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String userame = jtf.getText();
                if (userList.getUserName(userame)){
                    JOptionPane.showMessageDialog(null, "用户已存在!", "提示", 2);
                }else {
                    linuxInstructions.executeLinuxCmd("useradd "+userame);
                    JOptionPane.showMessageDialog(null, "增加用户成功!", "提示", 2);
                }
            }
        });
        Button_addUserGroup.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String usergroup = jpf.getText();
                if (userList.getGroupName(usergroup)){
                    JOptionPane.showMessageDialog(null, "用户组已存在!", "提示", 2);
                }else {
                    linuxInstructions.executeLinuxCmd("groupadd "+usergroup);
                    JOptionPane.showMessageDialog(null, "增加用户组成功!", "提示", 2);
                }
            }
        });

有关这几段代码的说明:LinuxInstructions 中提供了两个方法,executeLinuxCmd 用来执行普通的 Linux 命令,executeJava 用来执行管道命令。getUserName()getGroupName()方法的返回值用来判断是否执行增加操作。

功能3:实现为 Linux 系统删除用户、删除用户组

    首先重新绘制用户清单与用户组清单窗体,动态加载 Linux 系统中的用户信息到窗体内容中,然后监听两个删除按钮,提供相应的点击事件。代码如下:

    //绘制用户清单表格
    public void getTable(ArrayList<String> alstring){
        JFrame f = new JFrame();
        f.setBounds(200, 300, 800, 400);
        ArrayList<Object[]> alist = new ArrayList<>();
        for (int i = 0;i<alstring.size();i++){
            String[] split = alstring.get(i).split(":");
            alist.add(new String[]{split[0]});
        }
        Object[][] obj = alist.toArray(new Object[alist.size()][]);
        // 创建表格中的横标题
        String[] Names = { "用户名"};
        // 以Names和playerInfo为参数,创建一个表格
        JTable table = new JTable(obj, Names);
        // 设置此表视图的首选大小
        table.setPreferredScrollableViewportSize(new Dimension(400, 300));
        // 将表格加入到滚动条组件中
        JScrollPane scrollPane = new JScrollPane(table);
        f.getContentPane().add(scrollPane, BorderLayout.CENTER);
        // 再将滚动条组件添加到中间容器中
        f.setTitle("用户清单");
        f.pack();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    //绘制用户组表格
    public void getGroup(ArrayList<String> alstring){
        JFrame f = new JFrame();
        f.setBounds(650, 300, 800, 400);
        ArrayList<Object[]> alist = new ArrayList<>();
        for (int i = 0;i<alstring.size();i++){
            String[] split = alstring.get(i).split(":");
            alist.add(new String[]{split[2]});
        }
        Object[][] obj = alist.toArray(new Object[alist.size()][]);
        // 创建表格中的横标题
        String[] Names = { "用户组"};
        // 以Names和playerInfo为参数,创建一个表格
        JTable table = new JTable(obj, Names);
        // 设置此表视图的首选大小
        table.setPreferredScrollableViewportSize(new Dimension(400, 300));
        // 将表格加入到滚动条组件中
        JScrollPane scrollPane = new JScrollPane(table);
        f.getContentPane().add(scrollPane, BorderLayout.CENTER);
        // 再将滚动条组件添加到中间容器中
        f.setTitle("用户组");
        f.pack();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
            //设置按钮监听
            Button_addUser.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String userame = jtf.getText();
                    if (userList.getUserName(userame)){
                        linuxInstructions.executeLinuxCmd("userdel "+userame);
                        JOptionPane.showMessageDialog(null, "删除用户成功!", "提示", 2);
                    }else {
                        JOptionPane.showMessageDialog(null, "该用户不存在!", "提示", 2);
                    }
                }
            });
            Button_addUserGroup.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String usergroup = jpf.getText();
                    if (userList.getGroupName(usergroup)){
                        linuxInstructions.executeLinuxCmd("userdel "+usergroup);
                        linuxInstructions.executeLinuxCmd("groupdel "+usergroup);
                        JOptionPane.showMessageDialog(null, "删除用户组成功!", "提示", 2);
                    }else {
                        JOptionPane.showMessageDialog(null, "该用户组不存在!", "提示", 2);
                    }
                }
            });
功能4:实现设置用户的密码、用户使用的shell、更换用户的用户组

    首先重新绘制用户的参数表格,动态加载真实的用户参数,然后监听更新密码、更新shell和group两个按钮,提供相关的点击事件,代码如下:

 //绘制用户参数表格
    public void getTable(ArrayList<String> alstring){
        JFrame f = new JFrame();
        f.setBounds(600, 300, 800, 400);
        ArrayList<Object[]> alist = new ArrayList<>();
        for (int i = 0;i<alstring.size();i++){
            String[] split = alstring.get(i).split(":");
            alist.add(new String[]{split[0], split[3],split[6]});
        }
        Object[][] obj = alist.toArray(new Object[alist.size()][]);
        // 创建表格中的横标题
        String[] Names = { "用户名","用户组","用户使用的shell"};
        // 以Names和playerInfo为参数,创建一个表格
        JTable table = new JTable(obj, Names);
        // 设置此表视图的首选大小
        table.setPreferredScrollableViewportSize(new Dimension(400, 300));
        // 将表格加入到滚动条组件中
        JScrollPane scrollPane = new JScrollPane(table);
        f.getContentPane().add(scrollPane, BorderLayout.CENTER);
        // 再将滚动条组件添加到中间容器中
        f.setTitle("用户参数");
        f.pack();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
//设置按钮监听_更新密码
            Button_setPassword.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String username = jtf.getText();
                    String password = jpf.getText();
                    if (userList.getUserName(username)){
                        linuxInstructions.executeJava("echo " + username+":" + password + " | chpasswd");
                        JOptionPane.showMessageDialog(null, "更改密码成功!", "提示", 2);
                    }else {
                        JOptionPane.showMessageDialog(null, "该用户不存在!", "提示", 2);
                    }
                }
            });

            //设置按钮监听_更新shell和group
            Button_setShellAndGroup.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String username = jtf.getText();
                    String shell = jsf.getText();
                    String group = jgf.getText();
                    if (userList.getUserName(username)){
                        if (userList.getGroupName(group)){
                            linuxInstructions.executeJava("usermod -s " + shell + " " + username);
                            linuxInstructions.executeJava("usermod -g " + group + " " + username);
                            JOptionPane.showMessageDialog(null, "更改shell和用户组成功!", "提示", 2);
                        }else {
                            JOptionPane.showMessageDialog(null, "该用户组不存在!", "提示", 2);
                        }
                    }else {
                        JOptionPane.showMessageDialog(null, "该用户不存在!", "提示", 2);
                    }
                }
            });

代码说明:因为此处涉及到管道命令,需要调用 LinuxInstructions 下的 executeJava()方法才能正确执行 Linux 指令,否则将无法设置用户参数。

功能5:实现点击主窗体上的按钮跳转到对应的子窗体

    在 MainForm 中监听四个按钮,并提供相应的点击事件,在点击后创建一个相应的子窗体即可,代码如下:

//用户清单界面
        b1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                UserList userList = new UserList();
                userList.getTable(userList.getUser());
            }
        });

        //用户增加界面
        b2.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                JFrame f2 = new JFrame("用户增加");
                AddUserAndGroup addUserAndGroup = new AddUserAndGroup();
                addUserAndGroup.addUserAndGroup();
            }
        });

        //用户删除界面
        b3.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                JFrame f3 = new JFrame("用户删除");
                DeleteUserAndGroup deleteUserAndGroup = new DeleteUserAndGroup();
                deleteUserAndGroup.deleteUserAndGroup();
            }
        });

        //用户参数设置界面
        b4.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                JFrame f4 = new JFrame("用户参数设置");
                SetUserParameters setUserParameters = new SetUserParameters();
                setUserParameters.setUserParameters();
            }
        });

效果如图:

点击按钮弹出用户清单子窗体:

点击按钮弹出用户增加界面:

点击按钮弹出用户删除界面:

点击按钮弹出用户参数设置界面:

至此,Linux 下的用户管理工具开发完成!如果发现错误或有疑问,欢迎在评论区留言!
如果觉得这篇文章对您有帮助的话,请点击文章下方的赞赏,扫描弹出的二维码支持博主创作!!!
本工具已开源至 GitHub:点击访问

Java
Linux
  • 作者:年轻的空指针(联系作者)
  • 发表时间:2022-04-26 08:30
  • 版权声明:严禁商用,转载请注明出处
  • 公众号转载:请在文末添加作者公众号二维码
  • 评论