Java实验--基于Swing的简单的歌曲信息管理系统

Posted meiqing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java实验--基于Swing的简单的歌曲信息管理系统相关的知识,希望对你有一定的参考价值。

  原创不易,转载请注明出处。

  上一篇《Java实验--基于Swing的简单的歌曲信息管理系统(三) 》中,我们绘制了登录、注册和管理员主界面,本篇主要讲解歌曲管理界面。第一次涉及到对表格的操作,参见的教材上的代码,具体代码如下:

package test.swing;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableModel;

public class ExampleFrame_06 extends JFrame {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private DefaultTableModel tableModel;// 定义表格模型对象
    private JTable table;// 定义表格对象
    private JTextField aTextField;
    private JTextField bTextField;
    
    public static void main(String args[]) {
        ExampleFrame_06 frame = new ExampleFrame_06();
        frame.setVisible(true);
    }
    
    public ExampleFrame_06() {
        super();
        setTitle("维护表格模型");
        setBounds(100, 100, 500, 375);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JScrollPane scrollPane = new JScrollPane();
        getContentPane().add(scrollPane, BorderLayout.CENTER);
        String[] columnNames = { "A", "B" };// 定义表格列名数组
        String[][] tableValues = { { "A1", "B1" }, { "A2", "B2" },
                { "A3", "B3" } };// 定义表格数据数组
        // 创建指定表格列名和表格数据的表格模型
        tableModel = new DefaultTableModel(tableValues, columnNames);
        
        table = new JTable(tableModel);// 创建指定表格模型的表格
//        table.setRowSorter(new TableRowSorter(tableModel));// 设置表格的排序器
        // 设置表格的选择模式为单选
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        // 为表格添加鼠标事件监听器
        table.addMouseListener(new MouseAdapter() {
            // 发生了点击事件
            public void mouseClicked(MouseEvent e) {
                // 获得被选中行的索引
                int selectedRow = table.getSelectedRow();
                // 从表格模型中获得指定单元格的值
                Object oa = tableModel.getValueAt(selectedRow, 0);
                // 从表格模型中获得指定单元格的值
                Object ob = tableModel.getValueAt(selectedRow, 1);
                aTextField.setText(oa.toString());// 将值赋值给文本框
                bTextField.setText(ob.toString());// 将值赋值给文本框
            }
        });
        scrollPane.setViewportView(table);
        final JPanel panel = new JPanel();
        getContentPane().add(panel, BorderLayout.SOUTH);
        panel.add(new JLabel("A:"));
        aTextField = new JTextField("A4", 10);
        panel.add(aTextField);
        panel.add(new JLabel("B:"));
        bTextField = new JTextField("B4", 10);
        panel.add(bTextField);
        final JButton addButton = new JButton("添加");
        addButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String[] rowValues = { aTextField.getText(),
                        bTextField.getText() };// 创建表格行数组
                tableModel.addRow(rowValues);// 向表格模型中添加一行
                int rowCount = table.getRowCount() + 1;
                aTextField.setText("A" + rowCount);
                bTextField.setText("B" + rowCount);
            }
        });
        panel.add(addButton);
        final JButton updButton = new JButton("修改");
        updButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int selectedRow = table.getSelectedRow();// 获得被选中行的索引
                if (selectedRow != -1) {// 判断是否存在被选中行
                    tableModel.setValueAt(aTextField.getText(),
                            selectedRow, 0);// 修改表格模型当中的指定值
                    tableModel.setValueAt(bTextField.getText(),
                            selectedRow, 1);// 修改表格模型当中的指定值
                }
            }
        });
        panel.add(updButton);
        final JButton delButton = new JButton("删除");
        delButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int selectedRow = table.getSelectedRow();// 获得被选中行的索引
                if (selectedRow != -1)// 判断是否存在被选中行
                    // 从表格模型当中删除指定行
                    tableModel.removeRow(selectedRow);
            }
        });
        panel.add(delButton);
    }
}
View Code

   创建表格,使用JTable即可,表格中的数据一般使用java swing提供的DefaultTableModel即可,DefaultTableModel有如下构造方法,通过这种方式,可以设置表头和表格中的数据。然后再创建JTable时,把DefaultTableModel传入即可,再把表格给放入滚动面板JScrollPane就完成了。

  

  创建表格的具体代码如下所示:

package test.swing;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;

public class ExampleFrame_06 extends JFrame {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private DefaultTableModel tableModel;// 定义表格模型对象
    private JTable table;// 定义表格对象
    private JTextField aTextField;
    private JTextField bTextField;
    
    public static void main(String args[]) {
        ExampleFrame_06 frame = new ExampleFrame_06();
        frame.setVisible(true);
    }
    
    public ExampleFrame_06() {
        super();
        setTitle("维护表格模型");
        setBounds(100, 100, 500, 375);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JScrollPane scrollPane = new JScrollPane();
        getContentPane().add(scrollPane, BorderLayout.CENTER);
        String[] columnNames = { "A", "B" };// 定义表格列名数组
        String[][] tableValues = { { "A1", "B1" }, { "A2", "B2" }, { "A3", "B3" } };// 定义表格数据数组
        // 创建指定表格列名和表格数据的表格模型
        tableModel = new DefaultTableModel(tableValues, columnNames);
        
        table = new JTable(tableModel);// 创建指定表格模型的表格
        table.setRowSorter(new TableRowSorter(tableModel));// 设置表格的排序器
        // 设置表格的选择模式为单选
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        scrollPane.setViewportView(table);
    }
}

   我们给表格填充一些数据,再加一些按钮(添加、修改、删除)和输入框(用来输入数据),来对表格中的数据进行增改删操作。(代码部分参见上面的教材源码)让最终的界面看起来如下所示:

  

   这里我们为表格添加鼠标事件监听器,想要得到的效果就是,当我们选中表格中的某一行时,将表格中的数据给显示在下面的输入框中。具体做法,先通过JTable的getSelectedRow()方法获取选中的行,再通过DefaultTableModel中的getValueAt(行,列)获取单元格里面的值,再将获取到的值赋到文本框即可。代码如下:

// 为表格添加鼠标事件监听器
table.addMouseListener(new MouseAdapter() {
    // 发生了点击事件
    public void mouseClicked(MouseEvent e) {
        // 获得被选中行的索引
        int selectedRow = table.getSelectedRow();
        // 从表格模型中获得指定单元格的值
        Object oa = tableModel.getValueAt(selectedRow, 0);
        // 从表格模型中获得指定单元格的值
        Object ob = tableModel.getValueAt(selectedRow, 1);
        aTextField.setText(oa.toString());// 将值赋值给文本框
        bTextField.setText(ob.toString());// 将值赋值给文本框
    }
});

  添加一行,我们为添加按钮给添加监听器,输入从文本框中获取,使用DefaultTableModel中的addRow(String[] rowValues),来进行添加。具体代码如下

addButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        String[] rowValues = { aTextField.getText(), bTextField.getText() };// 创建表格行数组
        tableModel.addRow(rowValues);// 向表格模型中添加一行
        int rowCount = table.getRowCount() + 1;
        aTextField.setText("A" + rowCount);
        bTextField.setText("B" + rowCount);
    }
});

  修改,都是先获取改行类容(需要检验改行是否在表格中存在),再进行修改。先为修改按钮给添加事件监听器,在使用DefaultTableModel中的为单元格赋值方法setValueAt(值,行号,列号)即可,具体代码如下:

updButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        int selectedRow = table.getSelectedRow();// 获得被选中行的索引
        if (selectedRow != -1) {// 判断是否存在被选中行
            tableModel.setValueAt(aTextField.getText(), selectedRow, 0);// 修改表格模型当中的指定值
            tableModel.setValueAt(bTextField.getText(), selectedRow, 1);// 修改表格模型当中的指定值
        }
    }
});            

  删除就比较简单了,先获取到行号,判断该行号是否有效,再使用DefaultTableModel提供的removeRow(行号),即可,具体代码如下。

delButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        int selectedRow = table.getSelectedRow();// 获得被选中行的索引
        if (selectedRow != -1)// 判断是否存在被选中行
            // 从表格模型当中删除指定行
            tableModel.removeRow(selectedRow);
    }
});

 

  其实,这里的难点就是如何显示数据,根据教材的代码,能够大致模仿写出,然后就根据就把后台的数据显示出来就好了。为了实现让表格里面的行为不可编辑的状态,所以自己定义一个类,继承至DefaultTableMode,重写了isCellEditable方法,设置为了false。其他的都没有变。如果当时静下心再想想,可能就会重写很多的方法(还好这些在用户管理里面做了),使用的时候也会更简单,代码也会更少。

  其它的部分还有就是根据条件搜索,下面的JRadioButton和搜索框中显示的提示消息相对应等,之前考虑的是点击添加、删除、修改按钮,是弹出一个新的窗体来进行,无奈当时试了几次也不行(还好用户管理里面是这样实现的),只有模仿书上面的例子来做了,在表格的下面多增加了一排,里面包含了歌曲信息的输入框和增加、修改、删除的按钮,模仿例子来实现的。

  设计图如下,歌曲管理的窗体(它是一个JInterFrame)出现在之前的DeskPanel面板中,歌曲管理的窗体中,有一个主面板用来存放所有的子面板,采用了边界布局模式。主面板的上部(NORTH)放的是一个子面板,主要用来存放搜索框和一行单选按钮;主面板的中部(CENTER)主要是用来放了一个滚动面板,用它来放一个表格;主面板的下部(SOUTH)放了一个子面板,主要用来存放一系列的输入框和几个按钮。

  

  单选按钮处理,因为是单选按钮,所以需要把这些单选按钮给放入一个ButtonGroup中。其中表格的数据是从数据中查找出来的,再把List数据类型给转换成了二位数组类型,其实这里应该在Service层做。为了使单元格为不可编辑状态,在网上找了很久都没有找到办法,索性就定义了一个内部类(继承至DefaultTableModel),重写了isCellEditable方法,让其不可编辑,界面布局代码如下所示: 

/**
 * 管理员--管理歌曲信息界面
 *
 */
public class AdminSongManageView extends JInternalFrame {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private JPanel panelMain; // 主面板

    private JPanel panelTop; // 主面板的上部
    private JPanel panelSearch; // 搜索面板
    private JLabel labKey; // 关键字
    private JTextField tfSearch; // 搜索框
    private JButton btnSearch; // 查找按钮

    private JPanel panelSearchType; // 按什么查找
    private ButtonGroup buttonGroup = new ButtonGroup();
    private JRadioButton[] btnSearchTypes = new JRadioButton[4]; // 条件,如歌名,语言,类别,歌手
    private JLabel labSearch;

    private JScrollPane panelTable; // 表格面板
    private myTableModel tableModel;// 定义表格模型对象
    private JTable table;// 定义表格对象

    private JPanel panelBottom; // 底部面板,包括输入框,添加、删除、修改
    private JLabel labName;
    private JLabel labLanguage;
    private JLabel labCategory;
    private JLabel labSinger;
    private JTextField tfName; // 输入歌曲名字
    private JTextField tfLanguage; // 输入语言
    private JTextField tfCategory; // 输入类别
    private JTextField tfSinger; // 歌手
    private JButton btnAdd; // 添加按钮
    private JButton btnEdit; // 修改按钮
    private JButton btnDelete; // 删除按钮

    private SongService songService;

    public AdminSongManageView() {
        songService = new SongServiceImpl();
        init();
    }

    /**
     * 初始化各组件
     */
    private void init() {
        this.setTitle("歌曲管理");
        this.setSize(new Dimension(750, 550));
        this.setIconifiable(true); // 窗体最小化
        this.setClosable(true); // 可被关闭
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); // 退出
        panelMain = new JPanel(new BorderLayout());

        panelTop = new JPanel(new GridLayout(2, 1, 0, 0));
        panelTop.setLocation(0, 20);
        panelSearch = new JPanel();
        panelSearch.setPreferredSize(new Dimension(750, 30));
        labKey = new JLabel("关键字");
        tfSearch = new JTextField("请输入歌名",20);
        tfSearch.setPreferredSize(new Dimension(100, 20));
        btnSearch = new JButton("查找");
        btnSearch.setPreferredSize(new Dimension(60, 20));
        panelSearch.add(new JLabel());
        panelSearch.add(labKey);
        panelSearch.add(tfSearch);
        panelSearch.add(new JLabel());
        panelSearch.add(btnSearch);
        panelSearch.add(new JLabel());
        panelTop.add(panelSearch);

        panelSearchType = new JPanel();
        panelSearchType.setPreferredSize(new Dimension(750, 30));
        labSearch = new JLabel("查询");
        panelSearchType.add(labSearch);
        btnSearchTypes[0] = new JRadioButton("歌名", true);
        btnSearchTypes[1] = new JRadioButton("语言");
        btnSearchTypes[2] = new JRadioButton("类别");
        btnSearchTypes[3] = new JRadioButton("歌手");

        // System.out.println("名字"+btnSearchTypes[1].getText());
        for (JRadioButton jRadioButton : btnSearchTypes) {
            buttonGroup.add(jRadioButton);
            panelSearchType.add(jRadioButton);
        }
        panelTop.add(panelSearchType);
        panelMain.add(panelTop, BorderLayout.NORTH);

        String[] columnNames = { "id", "歌名", "语言", "类别", "歌手" };
        // 从数据库中查询所有数据
        List<Song> songs = songService.findAll();
        System.out.println(songs);
        String[][] tableValues = new String[songs.size()][5];
        for (int i = 0; i < songs.size(); i++) {
            tableValues[i][0] = songs.get(i).getId();
            tableValues[i][1] = songs.get(i).getName();
            tableValues[i][2] = songs.get(i).getLanguage();
            tableValues[i][3] = songs.get(i).getCategory();
            tableValues[i][4] = songs.get(i).getSinger();
            // System.out.println(tableValues[i][0]);
        }
        tableModel = new myTableModel(tableValues, columnNames);
        tableModel.isCellEditable(0, 0);
        table = new JTable(tableModel);
        table.setRowHeight(20); // 设置行高
        table.getTableHeader().setBackground(Color.GRAY); // 表头颜色
        table.setLocation(20, 80);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // 只能选中单行
        panelTable = new JScrollPane(table);
        panelTable.setBorder(BorderFactory.createTitledBorder("歌曲信息"));
        panelMain.add(panelTable, BorderLayout.CENTER);

        panelBottom = new JPanel();
        labName = new JLabel("歌名");
        tfName = new JTextField(8);
        labLanguage = new JLabel("语言");
        tfLanguage = new JTextField(8);
        labCategory = new JLabel("类别");
        tfCategory = new JTextField(8);
        labSinger = new JLabel("歌手");
        tfSinger = new JTextField(8);
        panelBottom.add(labName);
        panelBottom.add(tfName);
        panelBottom.add(labLanguage);
        panelBottom.add(tfLanguage);
        panelBottom.add(labCategory);
        panelBottom.add(tfCategory);
        panelBottom.add(labSinger);
        panelBottom.add(tfSinger);
        btnAdd = new JButton("增加");
        btnEdit = new JButton("修改");
        btnDelete = new JButton("删除");
        panelBottom.add(btnAdd);
        panelBottom.add(btnEdit);
        panelBottom.add(btnDelete);

        panelMain.add(panelBottom, BorderLayout.SOUTH);
        
        this.getContentPane().add(panelMain);
        this.setVisible(true);
        // System.out.println("1234");
    }
/**
     * myTableModel,继承DefaultTableModel,
     * 只重写了isCellEditable,让其不可编辑 
     *
     */
    private class myTableModel extends DefaultTableModel {
        
        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        public myTableModel(Object[][] data, Object[] columnNames) {
            super(data, columnNames);
            // TODO Auto-generated constructor stub
        }

        // 让表格不可编辑,重写了DefaultTableModel中的方法
        public boolean isCellEditable(int row, int column) {
            return false;
        }
    }
}
View Code

   实际效果如下图所示:

  

  同理,为表格添加鼠标点击事件,具体代码如下所示:

table.addMouseListener(new MouseAdapter() {
    // 发生了点击事件
    public void mouseClicked(MouseEvent e) {
        // 获得被选中行的索引
        int selectedRow = table.getSelectedRow();
        // 从表格模型中获得指定单元格的值
        // Object id = tableModel.getValueAt(selectedRow, 0);
            Object name = tableModel.getValueAt(selectedRow, 1);
            Object language = tableModel.getValueAt(selectedRow, 2);
            Object category = tableModel.getValueAt(selectedRow, 3);
            Object singer = tableModel.getValueAt(selectedRow, 4);

            tfName.setText(name.toString());
            tfLanguage.setText(language.toString());
            tfCategory.setText(category.toString());
            tfSinger.setText(singer.toString());
        }
    });
}
View Code

  增加、修改、删除和前面的类似,只是要涉及到对数据库的操作了。代码如下所示:

/**
     * 添加一行
     */
    private void addTableRow() {
        btnAdd.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // String[] rowValues = {"add",tfName.getText(),tfLanguage.getText(),
                // tfCategory.getText(),tfSinger.getText()};
                String name =  tfName.getText().trim();
                String language =  tfLanguage.getText().trim();
                String category =  tfCategory.getText();
                String singer = tfSinger.getText();
                if (name.equals("") || name == null 
                        || language.equals("") || language == null
                        || category.equals("") || category == null
                        || singer.equals("") || singer == null) {
                    JOptionPane.showMessageDialog(panelTable, "不能为空", "信息提示框", JOptionPane.INFORMATION_MESSAGE);
                    return;
                }
                Song song = new Song(Common.getUuid(),name,language, category, singer);
                String[] rowValues = new String[5];
                if (songService.addSong(song)) {
                    JOptionPane.showMessageDialog(panelMain, "添加成功", "信息提示框", JOptionPane.INFORMATION_MESSAGE);
                    rowValues[0] = song.getId();
                    rowValues[1] = song.getName();
                    rowValues[2] = song.getLanguage();
                    rowValues[3] = song.getCategory();
                    rowValues[4] = song.getSinger();
                    // 将输入框清空
                    tfName.setText("");
                    tfCategory.setText("");
                    tfSearch.setText("");
                    tfLanguage.setText("");
                    // 将新增的行加入表格中
                    tableModel.addRow(rowValues);
                } else {
                    JOptionPane.showMessageDialog(panelTable, "添加失败", "信息提示框", JOptionPane.INFORMATION_MESSAGE);
                }
            }
        });
    }

    /**
     * 修改信息
     */
    private void editTableRow() {
        btnEdit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int selectedRow = table.getSelectedRow(); // 获取被选中行的索引
                Song song = new Song();
                if (selectedRow != -1) { // 判断是否存在被选中行
                    // System.out.println(tableModel.getValueAt(selectedRow, 0));
                    song.setId(tableModel.getValueAt(selectedRow, 0).toString());
                    song.setName(tfName.getText());
                    song.setLanguage(tfLanguage.getText());
                    song.setCategory(tfCategory.getText());
                    song.setSinger(tfSinger.getText());
                    if (songService.updateSong(song)) {
                        song = songService.findById(song.getId());
                        JOptionPane.showMessageDialog(panelMain, "修改成功", "信息提示框", JOptionPane.INFORMATION_MESSAGE);
                        tableModel.setValueAt(song.getId(), selectedRow, 0);
                        tableModel.setValueAt(song.getName(), selectedRow, 1);
                        tableModel.setValueAt(song.getLanguage(), selectedRow, 2);
                        tableModel.setValueAt(song.getCategory(), selectedRow, 3);
                        tableModel.setValueAt(song.getSinger(), selectedRow, 4);
                    } else {
                        JOptionPane.showMessageDialog(panelTable, "修改失败", "信息提示框", JOptionPane.INFORMATION_MESSAGE);
                    }

                }
            }
        });
    }

    /**
     * 删除一条信息
     */
    private void deleteTableRow() {
        btnDelete.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int selectedRow = table.getSelectedRow(); // 获取被选中行的索引
                if (selectedRow != -1) {
                    String id = tableModel.getValueAt(selectedRow, 0).toString();
                    if (songService.deletSong(id)) {
                        JOptionPane.showMessageDialog(panelMain, "删除成功", "信息提示框", JOptionPane.INFORMATION_MESSAGE);
                        // 将输入框清空
                        tfName.setText("");
                        tfCategory.setText("");
                        tfSearch.setText("");
                        tfLanguage.setText("");
                        tableModel.removeRow(selectedRow);
                        
                    } else {
                        JOptionPane.showMessageDialog(panelTable, "删除失败", "信息提示框", JOptionPane.INFORMATION_MESSAGE);
                    }
                }
            }
        });
    }
View Code

  现在只剩下了对查询的处理。

  为了实现,当我们点击下面的单选按钮,搜索输入框中提示相应的消息,所以需要为单选按钮添加事件监听器,代码如下所示:

/**
 * 获取勾选框中的值,将该值的信息给放入到tfsearch中,用作提示信息
 */
private void getSearchTypeValue() {
    for (JRadioButton jRadioButton : btnSearchTypes) {
        jRadioButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                jRadioButton.setSelected(true); // 将该jRadioButton设置为选中状态
            String type = jRadioButton.getText();
            tfSearch.setText("请输入" + type);
            // System.out.println(type);
            }
        });
    }
}

  我们还需要为搜索输入框给加一个光标进入的事件,当光标移入时,我们把提示信息给清空(之前一直再想为什么java swing中没有html中的placeholder属性),具体代码如下:

/**
 * 处理输入框的提示消息处理,当光标进入search输入框时,将输入框清空
 */
private void displayMessage() {
    tfSearch.addFocusListener(new FocusAdapter() {
        public void focusGained(FocusEvent e) {
            tfSearch.setText("");
        }
    });
}

  下面就是具体的查询了,再把查询到数据显示在表中之前,我们需要先使用DefaultTableModel中的setRowCount(0),将表格清空(其实是设置表格的行数为0行,以达到清空的目的)。所以把该步骤给提取了出来,单独封装成一个方法,具体代码如下所示:

// 查询时使用,清空表格数据,再重新添加行
private void fillSonginfo

以上是关于Java实验--基于Swing的简单的歌曲信息管理系统的主要内容,如果未能解决你的问题,请参考以下文章

Java实验--基于Swing的简单的歌曲信息管理系统

Java实验--基于Swing的简单的歌曲信息管理系统

Java实验--基于Swing的简单的歌曲信息管理系统

Java Swing 课程设计 ---- 实验室设备管理系统

关于java Swing 的学生管理信息系统的问题

使用 Java Swing 编写 IpChat, 基于 IP Messenger 协议,支持 IPv6