• 老师又双叒叕留了大作业了,这次这个比较大,废了不少劲也掉了不少头发,虽然实现的方方有点笨,没有其他同学的漂亮,但还是写出来了,这个过程真是心酸有心累,还赶上期末,叫人抓狂,有两天晚上废了一晚上去找bug,还是没有找到,最后我舍友十分钟给找出来的.
  • 当晚破防,我是伞兵,我是伞兵,我是伞兵。重要的事情说三遍。
  • 如果要是想看实现的结果,直接将三个类CV一下到 idea 上就能编辑出来了,后边的就可以不看了,如果想看个个功能的实现方法和我遇到问题怎么解决的可以看后边,跳过代码,我看代码我也烦。
  • 废话不在多说了,直接给大家分析一下代码和我其中遇到的问题和解决的方法。希望可以帮助到大家
  • 我是先写的一个界面类布置好界面,在实现的各个功能,都写到界面类的构造方法中去了,最后直接在主类中new一个对象,显示出来。
  • 第一个类JavaPhone 界面类,里边有一些实现功能都写一起了。
package Java;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.*;
import java.io.File;

public class JavaPhone extends JFrame implements ActionListener, MouseListener, ListSelectionListener {

    JButton jButton4;
    JPanel jPanelLeft, jPanelRight, jPanelUp, jPanelDown, jPanel1, jPanel2;//四个Jpanel面板来划分
    JSplitPane jSplitPaneLR, jSplitPaneUD; // 分割窗口
    JTable jTable;
    JScrollPane jScrollPane;
    DefaultTableModel defaultTableModel; // 表格的模板
    JTextField jTextField1, jTextField2, jTextField3;
    JRadioButton man, woman;
    String sex;
    JButton addButten, deleteButton, openButton, saveButton;
    JComboBox<String> jComboBox, jComboBox2;  // 下拉列表框
    JCheckBox jCheckBox;
    JComboBox<Integer> jComboBoxNum;
    JList<String> jList; // 左侧姓氏的列表框
    private String string1 = "姓名", string2 = "电话号码", string3 = "关系";
    DefaultListModel<String> defaultListModel; // 列表的模板
    ButtonGroup buttonGroup;
    String[][] myfriends = new String[1024][4]; // 二维数组分别 存放 姓名 性别 电话号码, 关系
    String[] surname = new String[1024]; // 用来存放姓氏
    String string_name = "Text.txt";
    int count = 0; // 记录缓存对象的个数
    int count1 = 0; // 用来记录数组中不重复的姓氏的个数 和数组中的下标差一要用另外一个变量来记录数组的下标
    Founction founction;
    public JavaPhone() {
        super("My电话薄");
// TODO Auto-generated constructor stub
        founction = new Founction(); // 新建一个功能类的对象,用来调用功能类的方法。
        this.setSize(900, 350); // 设置窗口的大小
        this.setLocationRelativeTo(null);
        this.setResizable(false);

        jButton4 = new JButton("确定");

        jPanelLeft = new JPanel(); // 左侧面板
        jPanelLeft.setBackground(Color.WHITE);
        jPanelLeft.setSize(200, 500); //由于在使用JSplitPane的时候 分割的位置就确定了所以就不用在设置大小了 下同

        jPanelRight = new JPanel(); // 右侧面板
//jPanelRight.setSize(800,500);
        jPanelRight.setBackground(Color.WHITE);

// 新建一个分割窗口 并且将左右两侧的面板添加进去
        jSplitPaneLR = new JSplitPane(1, jPanelLeft, jPanelRight);
        jSplitPaneLR.setDividerLocation(130); // 左右的分割距离

        this.getContentPane().add(jSplitPaneLR);

        jPanelRight.setLayout(new BorderLayout());
        jPanelUp = new JPanel();
        jPanelUp.setBackground(Color.WHITE);
//jPanelUp.setSize(800, 250); 由于在使用JSplitPane的时候 分割的位置就确定了所以就不用在设置大小了
        jPanelDown = new JPanel();
        jPanelDown.setBackground(Color.WHITE);
//jPanelDown.setSize(800, 250);

        jSplitPaneUD = new JSplitPane(0, jPanelUp, jPanelDown);
        jSplitPaneUD.setDividerLocation(200); // 上下分割的位置大小
        jPanelRight.add(jSplitPaneUD);

        String[] headers = {"姓名", "性别", "电话号码", "关系"};
        defaultTableModel = new DefaultTableModel(headers, 0) { // 重写一个方法使列表不可以被编辑
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
        jTable = new JTable(defaultTableModel); // 新建一个表格
        jTable.getTableHeader().setReorderingAllowed(false); // 设置Jtable模板不能改变位置顺序
        jTable.getTableHeader().setResizingAllowed(false); // 不能改变Jtable的大小
        jScrollPane = new JScrollPane(jTable); // 将Jtable 添加到滚动面板中去才能使表格的表头显示出来,这里叫做隐式显示
        jScrollPane.setPreferredSize(new Dimension(730, 200));// 设置JScorllPanel 的初始大小
        jPanelUp.add(jScrollPane);

        jPanelDown.setLayout(new FlowLayout());
// 添加面板
        jPanel1 = new JPanel();
        jPanel1.setLayout(new FlowLayout(0));
        jPanel1.setBackground(Color.WHITE);
        jPanel1.setSize(1000, 50); // 设置Jpanel1的大小
        jPanelDown.add(jPanel1);

        JLabel jLabel = new JLabel("My Friends");
        jPanel1.add(jLabel);
        jTextField1 = new JTextField(15);
        jTextField1.setText(string1);
        jTextField1.setForeground(Color.GRAY);
        jTextField1.addFocusListener(new FocusListener() {
            @Override
            public void focusLost(FocusEvent e) {
// TODO Auto-generated method stub
                if (jTextField1.getText().equals("") == true) {
                    jTextField1.setText(string1);
                }
            }

            @Override
            public void focusGained(FocusEvent e) {
// TODO Auto-generated method stub

                if (jTextField1.getText().equals(string1) == true) {
                    jTextField1.setText("");
                }
            }
        });
        jPanel1.add(jTextField1);

        man = new JRadioButton("男");
        man.setSelected(true);
        man.setBackground(Color.white);
        woman = new JRadioButton("女");
        woman.setBackground(Color.white);
        buttonGroup = new ButtonGroup();
        buttonGroup.add(man);
        buttonGroup.add(woman);
        jPanel1.add(man);
        jPanel1.add(woman);

        jTextField2 = new JTextField(15);
        jTextField2.setText(string2);
        jTextField2.setForeground(Color.GRAY);
        jTextField2.addFocusListener(new FocusListener() {

            @Override
            public void focusLost(FocusEvent e) {
// TODO Auto-generated method stub
                if (jTextField2.getText().equals("") == true) {
                    jTextField2.setText(string2);
                }
            }

            @Override
            public void focusGained(FocusEvent e) {
// TODO Auto-generated method stub

                if (jTextField2.getText().equals(string2) == true) {
                    jTextField2.setText("");
                }
            }
        });
        jPanel1.add(jTextField2);

        jTextField3 = new JTextField(15);
        jTextField3.setText(string3);
        jTextField3.setForeground(Color.GRAY);
        jTextField3.addFocusListener(new FocusListener() {

            @Override
            public void focusLost(FocusEvent e) {
// TODO Auto-generated method stub
                if (jTextField3.getText().equals("") == true) {
                    jTextField3.setText(string3);
                }
            }

            @Override
            public void focusGained(FocusEvent e) {
// TODO Auto-generated method stub
                if (jTextField3.getText().equals(string3) == true) {
                    jTextField3.setText("");
                }
            }
        });
        jPanel1.add(jTextField3);

        jPanel2 = new JPanel();
        jPanel2.setSize(770, 50);// 设置Jpanel2的大小
        jPanel2.setBackground(Color.WHITE);
        jPanelDown.add(jPanel2);

        jPanel2.setLayout(new FlowLayout());
        addButten = new JButton("添加");
        addButten.addActionListener(this);


        jPanel2.add(addButten);

        deleteButton = new JButton("删除选中多行");
        deleteButton.addActionListener(this);
        jPanel2.add(deleteButton);
        JLabel jLabel2 = new JLabel("查找关键字");
        jPanel2.add(jLabel2);

        String[] string1 = {"姓名", "关系", "电话","无关键字"}; // 下拉框设置
        jComboBox = new JComboBox<String>(string1);
        jComboBox.addActionListener(this);
        jPanel2.add(jComboBox);
        JLabel jLabel3 = new JLabel("排序关键字");
        jPanel2.add(jLabel3);
        String string2[] = {"姓名","关系"};
        jComboBox2 = new JComboBox<String>(string2);
        jComboBox2.addActionListener(this);
        jComboBox2.addActionListener(this);
        jPanel2.add(jComboBox2);
        openButton = new JButton("打开");
        openButton.addActionListener(this);
        jPanel2.add(openButton);
        saveButton = new JButton("保存");
        saveButton.addActionListener(this);
        jPanel2.add(saveButton);

        jCheckBox = new JCheckBox("定时保存"); // 复选框按钮
        jCheckBox.setBackground(Color.WHITE);
        jCheckBox.addActionListener(this);

        jPanel2.add(jCheckBox);

        jComboBoxNum = new JComboBox<Integer>();
        jPanel2.add(jComboBoxNum);
        for (int i = 1; i <= 15; i++) // 设置自动保存的时长
            jComboBoxNum.addItem(i);

        JLabel jLabel4 = new JLabel("分钟");
        jPanel2.add(jLabel4);

        defaultListModel = new DefaultListModel<>();
        jList = new JList<String>(defaultListModel);

        defaultListModel.addElement("全部");

        jList.addListSelectionListener(this); // 给左侧列表添加事件监听

        jPanelLeft.setLayout(new FlowLayout(0));
        jPanelLeft.add(jList);
// 以上是对图形界面的使用

        this.setVisible(true);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
    public static void main(String[] args) {
        JavaPhone javaPhone = new JavaPhone();
    }


    // 添加对于事件的监听并且调用Founction的方法对文件进行操作
    @Override// 在Jable中添加对象
    public void actionPerformed(ActionEvent event) {
// TODO Auto-generated method stub
        // 点击添加按钮是的操作
        if (event.getSource() == addButten) {
            String string2[] = {jTextField1.getText().replace(" ", ""), sex, jTextField2.getText().replace(" ", ""), jTextField3.getText().replace(" ", "")};
            boolean bl = true;
            if(string2[2].length()!=11)
                bl = false;
            else{
                    for(int i = 0 ; i<11; i++)
                    {
                        if(string2[2].charAt(i)>'9'||string2[2].charAt(i)<'0'){
                            bl = false;
                            break;
                        }
                    }
            }
            if(bl){
            if (man.isSelected())
                sex = "男";
            else
                sex = "女";
            String string[] = {jTextField1.getText().replace(" ", ""), sex, jTextField2.getText().replace(" ", ""), jTextField3.getText().replace(" ", "")};
            boolean flag = true;
            if (count == 0) {
                for (int b1 = 0; b1 < 4; b1++) // 将新添加的人物 添加到缓存数组中
                    myfriends[count][b1] = string[b1];
                count++;
                defaultTableModel.addRow(string);
                surname[count1] = string[0].charAt(0) + "";
                count1++;
                defaultListModel.addElement(string[0].charAt(0) + "");
            } else {
                boolean b = true;
                for (int i = 0; i < count; i++) {
                    if (myfriends[i][0].equals(string[0]) && myfriends[i][1].equals(string[1]) && myfriends[i][2].equals(string[2]) && myfriends[i][3].equals(string[3])) {
                        b = false;
                        break;
                    }
                }
                if (b == true) {
                    for (int b1 = 0; b1 < 4; b1++)
                        myfriends[count][b1] = string[b1];
                    count++;
                    defaultTableModel.addRow(string);
// 对左侧列表进行添加操作
                    {
                        boolean flag4 = true;
                        for (int i = 0; i < count1; i++) {
                            if (surname[i].charAt(0) == string[0].charAt(0)) {
                                flag = false;
                                break;
                            }
                        }
                        if (flag == true) {
                            surname[count1] = string[0].charAt(0) + "";
                            count1++;
                            defaultListModel.addElement(string[0].charAt(0) + "");
                        }
                    }
                }
                else{
                    JOptionPane.showMessageDialog(null,"相同信息不能重复添加");
                }
            }
            }
            else {
                JOptionPane.showMessageDialog(null,"请输入正确的电话号码");
            }
        }
        //点击删除列表时的操作
        if (event.getSource() == deleteButton) {
            int rows[] = jTable.getSelectedRows();
            if (rows.length <= 0)
                return;

            else {
                String friends[] = new String[4];

                for (int i = rows.length; i > 0; i--) {
                    friends[0] = (String) jTable.getValueAt(jTable.getSelectedRow(), 0);
                    friends[1] = (String) jTable.getValueAt(jTable.getSelectedRow(), 1);
                    friends[2] = (String) jTable.getValueAt(jTable.getSelectedRow(), 2);
                    friends[3] = (String) jTable.getValueAt(jTable.getSelectedRow(), 3);
                    for (int b = 0; b < count; b++) {
                        if (myfriends[b][0].equals(friends[0]) && myfriends[b][1].equals(friends[1]) && myfriends[b][2].equals(friends[2]) && myfriends[b][3].equals(friends[3])) {
                            for (int k = b; k < count - 1; k++) {
                                for (int c = 0; c < 4; c++)
                                    myfriends[k][c] = myfriends[k + 1][c];
                            }
                        }
                    }

                    defaultTableModel.removeRow(jTable.getSelectedRow());// 1、更新左侧的列表
                    count--; // 改变数组有数据的大小
                    //myfriends[count] = null;//前进后将最后一位设置为空避免出现问题

                    // 输出数据观察myfriends数组的变化
                   /* for (int l = 0; l < count; l++)
                        System.out.println(myfriends[l][0]);
                    System.out.println(count + "----------");*/
                    if (count == 0) {
                        for (int f = 0; f < count1; f++) {
                            surname[f] = null;
                        }
                        defaultListModel.removeAllElements();
                        count1 = 0;
                        defaultListModel.addElement("全部");
                    } else {
/*
            遍历姓氏数组每一个,与对象数组每一个比较遍历一边对象数组如果对象数组中没有这个姓,则删除
*/
                        boolean b;
                        for (int k = 0; k < count1; k++) {
                            b = true;
                            for (int j = 0; j < count; j++) { // 如果 b是真的则在对象数组中没有姓氏和 b 相同 需要删除b当前的姓氏
                                if (surname[k].charAt(0) == myfriends[j][0].charAt(0)) {
                                    b = false;
                                    break;
                                }
                            }
                            if (b) {//如果有重复的则进行覆盖并且数组大小减一
                                for (int p = k; p < count1; p++) {
                                    surname[p] = surname[p + 1];
                                }
                                count1--;
                            }
                            // 更新左侧列表中的数据调用founction的方法
                            founction.upDate(surname, count1, defaultListModel);
                        }
                    }
                }
/*
                for(int o=0;o <count1;o++)
                {
                    System.out.println(surname[o]);
                }
                System.out.println("----------"+count1);*/ // 调试代码
            }
        }

        if (event.getSource() instanceof JComboBox) { 
//查找关键字是先在文本框中写入名字或其他的信息,在打开是对于查找
            String string_search = jComboBox.getSelectedItem().toString();
            String  string_sort = jComboBox2.getSelectedItem().toString();
            String friends[][] = new String[1024][4];
            int p = 0 ;
            int count3 = 0;

            if(string_search.equals("姓名"))
            {
                for(int i = 0 ; i<count; i++)
                {
                    if(myfriends[i][0].equals(jTextField1.getText().replace(" ","")))
                    {
                        friends[p] = myfriends[i];
                        p++;
                    }
                }
                count3 = p;
            }
            else if(string_search.equals("关系")){
                for(int i = 0 ; i<count; i++)
                {
                    if(myfriends[i][3].equals(jTextField3.getText().replace(" ","")))
                    {
                        friends[p] = myfriends[i];
                        p++;
                    }
                }
                count3 = p;
            }
            else if(string_search.equals("电话")) {
                for(int i = 0 ; i<count; i++)
                {
                    if(myfriends[i][2].equals(jTextField2.getText().replace(" ","")))
                    {
                        friends[p] = myfriends[i];
                        p++;
                    }
                }
                count3 = p;
            }
            else if(string_search.equals("无关键字"))
            {
                for(int i = 0 ; i<count; i++)
                {
                        friends[p] = myfriends[i];
                        p++;
                }
                count3 = p;
            }

            if(string_sort.equals("姓名")){
                founction.StringArraySort(friends,count3,0);
            }
            else if(string_sort.equals("关系")){
                founction.StringArraySort(friends,count3,3);
            }
            founction.upDate(friends,count3,defaultTableModel);
// 先查找,找出满足条件的人 存进一个数组 在列表中刷新显示出来, 如果排序的话在调用排序方法对数组进行排序,最后将数组刷新显示。
        }
        if (event.getSource() == openButton)  // 打开按钮
        {
            JFileChooser jFileChooser = new JFileChooser();
              jFileChooser.showOpenDialog(this);
             File file = jFileChooser.getSelectedFile();
             string_name = file.getName();
            count = FIleOption.read(myfriends,file.getPath());
            count1 = 0;
            for(int i = 0; i<count;i++)
            {
                if(count1 == 0)
                {
                    surname[count1] = myfriends[i][0].charAt(0)+"";
                    count1++;
                }
                else {
                    boolean b = new Boolean(true);
                    for(int k = 0;k< count1; k++)
                    {
                        if(myfriends[i][0].charAt(0)==surname[k].charAt(0))
                        {
                            b = false;
                            break;
                        }
                    }
                    if(b)
                    {
                        surname[count1] = myfriends[i][0].charAt(0)+" ";
                        count1++;
                    }
                }
            }
            founction.upDate(surname,count1,defaultListModel);
            founction.upDate(myfriends,count,defaultTableModel);
        }
        if (event.getSource() == saveButton)  // 保存按钮
        {
            for(int i=0;i<count;i++)
            {
                FIleOption.writer(myfriends,string_name,count);
            }
        }
        if(jCheckBox.isSelected())
        {
            Integer n = (Integer)jComboBoxNum.getSelectedItem();

            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(n*1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            Thread thread = new Thread(runnable);
            thread.start();
        }
    }
    @Override // 列表事件监听的方法
    public void valueChanged(ListSelectionEvent listSelectionEvent) {
// 鼠标按下会响应一次,鼠标松开也会相应一次所以会相应两次所以 要用getValueIsAdjusting()的真假来判断如果为真则为鼠标点击时,如果为假则为鼠标释放的时候
        if (listSelectionEvent.getValueIsAdjusting() == true) // 只对鼠标点击时进行动作
        {
            if (jList.getSelectedValue().equals("全部")) {
                defaultTableModel.setRowCount(0);
                for (int i = 0; i < count; i++)
                    defaultTableModel.addRow(myfriends[i]);
            } else {
                defaultTableModel.setRowCount(0);
// System.out.println(jList.getSelectedValue()); // jList.getSelectedValue() 获取当前元素的字符串
                for (int i = 0; i < count; i++) {
                    if (jList.getSelectedValue().charAt(0) == myfriends[i][0].charAt(0)) {
                        defaultTableModel.addRow(myfriends[i]);
                    }
                }
            }
        } else if (listSelectionEvent.getValueIsAdjusting() == false) // 鼠标释放后的情况
        {

        }
    }

    @Override
    public void mouseClicked(MouseEvent event) {
// TODO Auto-generated method stub

    }

    @Override
    public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub

    }

    @Override
    public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub

    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub

    }
}
  • 第二个在创建一个功能类,虽然一些功能在界面上已经实现了,但是还是要有点层次感的,写了写功能类,Founction类
package Java;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;

/*
 * 用于对界面事件发生后对文件的操作情况
 * 建立文件与缓存的关系
 * 拥有对文件的读写和操作的权限,创建类对象后,调用类对象的方法然后再写入文件进行操作
 *
 */
public class Founction {

    //对于右侧表格的数据进行更新 count 不能删除,count 表示数组中有效对象的个数,不能用 length 来表示
    public void upDate(String friends [][],int count ,DefaultTableModel tableModel) {
        tableModel.setRowCount(0); // 清空列表中的内容并重新添加数组中的数据
        for(int i = 0 ;i<count;i++)
            tableModel.addRow(friends[i]);
    }
    // 对于左侧的Jlist中的列表进行更新
    public void upDate(String name[],int count,DefaultListModel<String> tableModel) {
        tableModel.removeAllElements();// 清空列表中的内容并重新添加数组中的数据
        tableModel.addElement("全部");
        for(int i = 0 ;i<count;i++)
            tableModel.addElement(name[i]);

    }

    public void StringArraySort (String friends[][],int count,int flag)
    {
        String string[] = new String[4];
      //  int p, q, k;// 直接按flag进行排序   flag是 3 的时候是关系 0 是姓名

        for(int i = 1;i<count ;i++)
        {
            int j;
            if(friends[i][flag].compareTo(friends[i-1][flag])<0)
            {
                for(int c = 0; c< 4;c++)
                    string[c] = friends[i][c];
                for( j  = i-1;j>0&&string[flag].compareTo(friends[j][flag])<0 ;j--)
                {
                    for(int c =0;c<4 ;c++)
                    friends[j+1][c] = friends[j][c];
                }
                for(int c= 0;c<4;c++)
                {
                    friends[j+1][c] = string[c];
                }
            }
        }
    }
}
  • 第三个类是文件操作类,主要用于缓存对象在文件中的的缓存和读取,FileOption类
package Java;

import java.io.*;

public class FIleOption {

    public static void writer(String myFriend[][], String path,int count) {
        File file = new File(path);
        FileWriter fileWriter = null;
        BufferedWriter bufferedWriter = null;
        try {
            fileWriter = new FileWriter(file, false);
            bufferedWriter = new BufferedWriter(fileWriter);
            for (int i = 0 ;i<count;i++)
            {
                bufferedWriter.write(myFriend[i][0] + " " + myFriend[i][1] + " " + myFriend[i][2] + " " + myFriend[i][3] +"\n");
            }

            bufferedWriter.close();
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static int read(String myfriend[][], String path) {

        File file = new File(path);
        int count=0;
        try {
            FileReader fileReader = new FileReader(file);
            BufferedReader  bufferedReader = new BufferedReader(fileReader);
            String string = null;
            while ((string = bufferedReader.readLine())!=null){
                myfriend[count] = string.split(" ");
                count++;
            }
            fileReader.close();
            bufferedReader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            }
        return count ;
    }
}

图形界面

  • 一开始是现将面板分为左右两个部分
    这个时候就离不开了JSplitPane 分割面板框 ,他的好处是可以在分割的时候左右或上下拉动,在边布局中使用的JSplitPane,左右分开后,在在右边的面板中添加一个JSplitPane,用来上下分,添加四个边Jpanel面板,这个时候的右边要设置成边界布局要不会有问题。这样界面的分界就出来了,再向各个界面里边添加东西就好了
  • 最左边是添加的Jlist 存储姓氏,在用Jlist的时候不要直接向里边添加东西,要用 DefaultListModel,给Jlist添加模板,在在模板中操作,进行添加和删除。
  • 右边是分为上下两个部分,上边的是用的JTable,同Jlist一样,也是要用一个模板来做,不过是用的DefaultTableModel,在表格的设置的时候是先设置表格的表头,并设置成不可编辑不可改变大小,设定行数,为了好看,将表格添加到滚动面板中去。
String[] headers = {"姓名", "性别", "电话号码", "关系"};
        defaultTableModel = new DefaultTableModel(headers, 0) { // 重写一个方法使列表不可以被编辑
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
        jTable = new JTable(defaultTableModel); // 新建一个表格
        jTable.getTableHeader().setReorderingAllowed(false); // 设置Jtable模板不能改变位置顺序
        jTable.getTableHeader().setResizingAllowed(false); // 不能改变Jtable的大小
        jScrollPane = new JScrollPane(jTable); // 将Jtable 添加到滚动面板中去才能使表格的表头显示出来,这里叫做隐式显示
        jScrollPane.setPreferredSize(new Dimension(730, 200));// 设置JScorllPanel 的初始大小
        jPanelUp.add(jScrollPane);

剩下的是下方的面板,因为这个要设置添加按钮和文本框,所以是流布局,设置好文本框的大小后添加组件,这样一个界面就完成了。

功能实现和事件监听

  • 事件的监听一开始我就写错了好在现在改过来了,两种方法,一个是对按钮添加匿名内部类,一个是继承事件监听接口。我在按钮上用的第二种,在文本框中用的第一种。先是继承了ActionListener, MouseListener, ListSelectionListener ,动作监听事件,鼠标监听事件和列表监听事件,注意在事件监听后一定要实现他的方法,不管是不是有用先导入方法,再在有用的方法下进行实现。
  • 添加,因为是用的是数组缓存,所以是对数组进行便利,我的同学有用Set集合的,高大上,但是我比较笨,把握不住,只能用笨的方法了,就是先看满不满足条件,全部相同的不能添加,电话不符合11位的不能添加。每次添加一个都要遍历一边,(有点笨),同时对于姓氏也是用的一个缓存数组,专门来存储姓氏,在添加的时候取出姓名的第一个字符如果在姓氏数组中没有,那么在姓氏数组中添加这个姓,如果有就不添加,总的来说是将两个数组完全的分开了,一个存个人信息的二维数组,一个存姓氏的一维数组。虽然每个数组的大小是1024 但是都是用了全局变量count来记录当前数组中有效的个数。每次点击的时候就要在按钮的监听中进行操作。
  • 删除多行,其实一行和多行是一回事,删除就行了,不过要注意,这里我是获取到的列表中的被选中的行数,然后返回他的各个信息(注意返回信息的函数,一开始没有找到,又废了好长时间,所以在有必要的时候查一查API也是很有用的,我舍友拿着API写程序,没毛病,提醒了我,CSDN和API结合用yyds),在大的数组中进行遍历,如果是一毛一样的直接删除就好了 ,这个时候就要注意了不是删除了就万事大吉了还有姓氏呢,如果是是最后一个姓氏你的姓氏数组也要删除这个姓了,所以就要反过来遍历了,获得被删除的人的姓氏,对信息数组进行便利,看是不是还有这个姓,如果没有的话,在姓氏数组中删除就好了,最后刷新 ,在刷新上我写了两个函数,一个是对Jtable中元素进行修改后刷新,一个是对Jlist进行刷新这都在Founction中。是方法的重载。
  • 查找,这个就很简单了根据你选中什么关键字,获取关键字文本框中的字符串,在大数组中查找,添加的Jtable中。
  • 排序 使用的插入排序,也是写在了Founction中的,直接获取选中排序的关键字进行排序就好了调用函数。
  • 打开 调用read函数,获取打开文件的地址,和名称,直接读取,保存的时候保存到打开的文件中去。
JFileChooser jFileChooser = new JFileChooser();  // 打开文件
              jFileChooser.showOpenDialog(this);
             File file = jFileChooser.getSelectedFile();  //获得选择的文件
             string_name = file.getName();  // 获得文件名称用于读写

在后边就是对文件读取后进行刷新了

  • 保存 调用write函数,将缓存数组写进文件中去,在Fileoption中的函数,
  • 定时保存 调用线程,新建一个线程,检查定时保存是否被选中,如果是被选中的话获得保存时间,开启线程进行线程休眠,每当到达一定的时间调用一次保存函数。
  • 左侧点击姓氏出现所对姓氏的对象 这个是个好问题 。添加事件监听ListSelectionListener 获得选中的姓氏,在显示出来,这里要注意,当鼠标点击的时候会有点击和释放两种状态,这时候要分为两种情况这样就能把点击和释放轻松分开了,要不然会有出现问题。
@Override // 列表事件监听的方法
    public void valueChanged(ListSelectionEvent listSelectionEvent) {
// 鼠标按下会响应一次,鼠标松开也会相应一次所以会相应两次所以 要用getValueIsAdjusting()的真假来判断如果为真则为鼠标点击时,如果为假则为鼠标释放的时候
        if (listSelectionEvent.getValueIsAdjusting() == true) // 只对鼠标点击时进行动作
        {
            if (jList.getSelectedValue().equals("全部")) {
                defaultTableModel.setRowCount(0);
                for (int i = 0; i < count; i++)
                    defaultTableModel.addRow(myfriends[i]);
            } else {
                defaultTableModel.setRowCount(0);
// System.out.println(jList.getSelectedValue()); // jList.getSelectedValue() 获取当前元素的字符串
                for (int i = 0; i < count; i++) {
                    if (jList.getSelectedValue().charAt(0) == myfriends[i][0].charAt(0)) {
                        defaultTableModel.addRow(myfriends[i]);
                    }
                }
            }
        } else if (listSelectionEvent.getValueIsAdjusting() == false) // 鼠标释放后的情况
        {

        }
    }

对于文本框中的自动提示,使用的焦点监听事件,添加的内部类,所以没有继承方法,以其中一个为例。

jTextField3.addFocusListener(new FocusListener() {
            @Override
            public void focusLost(FocusEvent e) {
// TODO Auto-generated method stub
                if (jTextField3.getText().equals("") == true) {
                    jTextField3.setText(string3);
                }
            }
            @Override
            public void focusGained(FocusEvent e) {
// TODO Auto-generated method stub
                if (jTextField3.getText().equals(string3) == true) {
                    jTextField3.setText("");
                }
            }
        });

有什么不对或者是可以优化的地方,欢迎指出。评论即可。谢谢。