簡體   English   中英

Java Swing:如何解析電話號碼,對其進行格式化並將其顯示在JTable中

[英]Java Swing: How To Parse A Phone Number, Format It, And Display It In A JTable

我正在嘗試將JTable的電話號碼列格式化為(Area) Prefix-Number 我不確定我做錯了什么,因為它可以正確編譯,並且根據getTableCellRenderer教程和我仔細研究過的其他眾多示例來看,它們是否可以正常工作。 但這不是...在JTable中它仍然被格式化為一個字符串。

我首先接受來自一個文本字段的用戶輸入的電話號碼:

//import necessary API

public class AddPatientDialog extends JDialog {

    private final JPanel contentPanel = new JPanel();
    private JTextField txtFieldPhneNum;

    private PatientDAO patientDAO;

    private PatientSessionTrackerApp patientSessionTrackerApp;

    public AddPatientDialog(PatientSessionTrackerApp thePatientSessionTracker, PatientDAO thePatientDAO) {
        this();
        patientDAO = thePatientDAO;
        patientSessionTrackerApp = thePatientSessionTracker;
    }

    public final class LengthRestrictedDocument extends PlainDocument {

          private final int limit;

          public LengthRestrictedDocument(int limit) {
            this.limit = limit;
          }

          @Override
          public void insertString(int offs, String str, AttributeSet a)
              throws BadLocationException {
            if (str == null)
              return;

            if ((getLength() + str.length()) <= limit) {
              super.insertString(offs, str, a);
            }
          }
        }

    /**
     * Create the dialog.
     */
    public AddPatientDialog() {
        setSize(450, 300);
        setResizable(false);
        setTitle("Add New Patient");
        getContentPane().setLayout(new BorderLayout());
        contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        getContentPane().add(contentPanel, BorderLayout.CENTER);
        contentPanel.setLayout(null);
        {
            JLabel lblPhneNum = new JLabel("Phone Number");
            lblPhneNum.setBounds(10, 86, 104, 14);
            contentPanel.add(lblPhneNum);
        }

        txtFieldPhneNum = new JTextField();
        txtFieldPhneNum.setBounds(124, 83, 86, 20);
        contentPanel.add(txtFieldPhneNum);
        txtFieldPhneNum.setColumns(10);
        txtFieldPhneNum.setDocument(new LengthRestrictedDocument(10));

        JPanel buttonPane = new JPanel();
        buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
        getContentPane().add(buttonPane, BorderLayout.SOUTH);
        {
            JButton okButton = new JButton("Add Patient");
            okButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {
                    savePatient();
                }
            });
            okButton.setActionCommand("OK");
            buttonPane.add(okButton);
            getRootPane().setDefaultButton(okButton);
        }

        JTextArea txtAddPatientWarning = new JTextArea();
        txtAddPatientWarning.setText("WARNING!!! Once a patient is created it is added to the database and cannot be removed from the database via the Patient Session Tracker. If a patient is added in error, please contact Sudo Technologies at (701) 388-3752.");
        txtAddPatientWarning.setBounds(10, 132, 424, 60);
        txtAddPatientWarning.setEditable(false);
        txtAddPatientWarning.setBackground(Color.YELLOW);
        txtAddPatientWarning.setLineWrap(true);
        contentPanel.add(txtAddPatientWarning);

        JLabel lblIe = new JLabel("Enter numbers only (i.e. 1234567890)");
        lblIe.setBounds(220, 86, 214, 14);
        contentPanel.add(lblIe);
    }

    protected void savePatient() {

        // get the patient info from the gui
        String firstName = txtFieldFName.getText();
        String middleName = txtFieldMName.getText();
        String lastName = txtFieldLName.getText();
        String phneNum = txtFieldPhneNum.getText();
        String email = txtFieldEmail.getText();

        Patient tempPatient = new Patient(phneNum);

        if ((firstName.trim().length() != 0) && (lastName.trim().length() != 0)) {  

            try{
                // save to the database
                patientDAO.addPatient(tempPatient);

                // close dialog
                setVisible(false);
                dispose();

                // refresh gui list
                patientSessionTrackerApp.refreshPatientsView();

                // show success message
                JOptionPane.showMessageDialog(patientSessionTrackerApp, "Patient added to the database.", 
                    "Patient Added",
                    JOptionPane.INFORMATION_MESSAGE);
            } catch (Exception exc) {
                JOptionPane.showMessageDialog(patientSessionTrackerApp, 
                        "Error saving patient: " +
                        exc.getMessage(), "Error",
                        JOptionPane.ERROR_MESSAGE);
            } 
        } else 
            JOptionPane.showMessageDialog(patientSessionTrackerApp, "<html>Please fill in all required fields as denoted by the <font color='red'>*</font>.</html>");
    }
}

然后,我嘗試將其傳遞給PhoneNumber類,以嘗試解析字符串:

public class PhoneNumber {
    public String areaCode;
    public String prefix;
    public String num;

    public PhoneNumber(String areaCode, String prefix, String num) {
        this.areaCode = areaCode;
        this.prefix = prefix;
        this.num = num;
    }

    public PhoneNumber() {}

    public PhoneNumber parsePhoneNumber(String phneNum) {
        String[] phneNumArr = {phneNum.substring(0,3), phneNum.substring(3,6), phneNum.substring(6)};
        areaCode = phneNumArr[0];
        prefix = phneNumArr[1];
        num = phneNumArr[2];
        return new PhoneNumber(areaCode, prefix, num);
    }

    @Override
    public String toString() {
        return "areaCode=" + areaCode + "; prefix=" + prefix + "; num=" + num;
    }
}

從那里,我嘗試使用對象解析器在CellRenderer類中設置其格式:

import java.awt.Component;

import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;

import com.patientsessiontracker.core.*;

public class PatientSessionTrackerCellRenderer extends DefaultTableCellRenderer {
    private static final long serialVersionUID = 1L;
    public String areaCode;
    public String prefix;
    public String num;
    public String phneNum;

    public Component getTableCellRendererComponent(JTable table, PhoneNumber value, boolean isSelected, 
                                                   boolean hasFocus, int row, int column) {
        //Component cellComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        PhoneNumber phneNum = new PhoneNumber();
        value = phneNum;
        String text =  "(" + phneNum.areaCode + ") " + phneNum.prefix + "-" + phneNum.num;
        setHorizontalAlignment(SwingConstants.CENTER);
        setText(text);
        return this;
    }
}

最后,我嘗試在JTable中實現新格式:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.EventQueue;
import java.awt.FlowLayout;

import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JScrollPane;

import java.util.List;

import com.patientsessiontracker.core.*;
import com.patientsessiontracker.dao.*;

public class PatientSessionTrackerApp extends JFrame {

    private JPanel contentPane;
    private JTextField txtFieldSrchFName;
    private JButton btnSearch;
    private JScrollPane scrollPane;
    private static JTable table;

    private static PatientDAO patientDAO;
    private JPanel panelBtn;
    private JButton btnAddPatient;
    private JTextField txtFieldSrchLName;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    PatientSessionTrackerApp frame = new PatientSessionTrackerApp();
                    frame.setVisible(true);
                    PatientSessionTrackerApp.refreshPatientsView();
                    table.getColumnModel().getColumn(3).setCellRenderer(new PatientSessionTrackerCellRenderer());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public PatientSessionTrackerApp() {

        // create the DAO
        try {
            patientDAO = new PatientDAO();
        } catch (Exception exc) {
            JOptionPane.showMessageDialog(this, "Error: " + exc, "Error", JOptionPane.ERROR_MESSAGE); 
        }

        setTitle("Patient Session Tracker");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(600, 300);
        setResizable(false);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JPanel panelSrch = new JPanel();
        panelSrch.setBounds(5, 5, 579, 33);
        contentPane.add(panelSrch);
        panelSrch.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

        JLabel lblFirstName = new JLabel("First Name");
        panelSrch.add(lblFirstName);

        txtFieldSrchFName = new JTextField();
        panelSrch.add(txtFieldSrchFName);
        txtFieldSrchFName.setColumns(13);

        btnSearch = new JButton("Search");
        btnSearch.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {        

                try {
                    String firstName = txtFieldSrchFName.getText();
                    String lastName = txtFieldSrchLName.getText();

                    List<Patient> patients = null;

                    if (((firstName != null) && (firstName.trim().length() > 0)) ||
                        ((lastName != null) && (lastName.trim().length() > 0))) 
                        patients = patientDAO.searchPatients(firstName, lastName);
                    else
                        patients = patientDAO.getAllPatients();

                    // create the model and update the "table"
                    PatientTableModel model = new PatientTableModel(patients);

                    table.setModel(model);
                    table.getColumnModel().getColumn(3).setCellRenderer(new PatientSessionTrackerCellRenderer());

                } catch (Exception exc) {
                    JOptionPane.showMessageDialog(PatientSessionTrackerApp.this, "Error: " + exc, "Error", JOptionPane.ERROR_MESSAGE); 
                }

            }
        });

        JLabel lblLastName = new JLabel("Last Name");
        panelSrch.add(lblLastName);

        txtFieldSrchLName = new JTextField();
        panelSrch.add(txtFieldSrchLName);
        txtFieldSrchLName.setColumns(13);
        panelSrch.add(btnSearch);

        scrollPane = new JScrollPane();
        scrollPane.setBounds(5, 38, 579, 186);
        contentPane.add(scrollPane);

        table = new JTable();
        scrollPane.setViewportView(table);

        panelBtn = new JPanel();
        panelBtn.setBounds(5, 224, 579, 38);
        contentPane.add(panelBtn);

        btnAddPatient = new JButton("Add Patient");
        btnAddPatient.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // create dialog
                AddPatientDialog addPatient = new AddPatientDialog(PatientSessionTrackerApp.this, patientDAO);

                // show dialog
                addPatient.setModal(true);
                addPatient.setVisible(true);
            }
        });
        panelBtn.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        panelBtn.add(btnAddPatient);
    }

    public static void refreshPatientsView() {

        try {
            List<Patient> patients = patientDAO.getAllPatients();
            PatientTableModel model = new PatientTableModel(patients);

            table.setModel(model);
        } catch (Exception exc) {
            JOptionPane.showMessageDialog(null, "Error: " + exc, "Error",
                    JOptionPane.ERROR_MESSAGE);
        }

    }
}

電話號碼從MySQL databasetinytext列中存儲和檢索。 如果需要,可以隨時請求更多代碼,我破解了很多部分以嘗試縮短問題。


好的...我完全迷失了方向,對Java Swing毫無幫助。我嘗試將“電話號碼”類調用到Custom CellRenderer類中。 我得到的結果是(null)null-null。 我不確定自己做錯了什么,是否應該嘗試使用CustomCellRenderer教程中所示的MaskFormatter API? 這是經過修改的代碼:

CustomCellRenderer:
public class PatientSessionTrackerCellRenderer extends DefaultTableCellRenderer {
    private static final long serialVersionUID = 1L;

    public PatientSessionTrackerCellRenderer() {
        super();
        setHorizontalAlignment(SwingConstants.CENTER);
    }

    @Override
    public void setValue(Object value) {
        PhoneNumber phneNum = new PhoneNumber();
        value.toString();
        value =  "(" + phneNum.areaCode + ") " + phneNum.prefix + "-" + phneNum.num;

        super.setValue(value);
    }
}

電話號碼類別:

public class PhoneNumber {
    public String areaCode;
    public String prefix;
    public String num;

    private PhoneNumber(String areaCode, String prefix, String num) {
        this.areaCode = areaCode;
        this.prefix = prefix;
        this.num = num;
    }

    public PhoneNumber() {}

    public PhoneNumber parsePhoneNumber(String value) {
        String[] phneNumArr = {value.substring(0,3), value.substring(3,6), value.substring(6)};
        areaCode = phneNumArr[0];
        prefix = phneNumArr[1];
        num = phneNumArr[2];
        return new PhoneNumber(areaCode, prefix, num);
    }

    @Override
    public String toString() {
        return "areaCode=" + areaCode + "; prefix=" + prefix + "; num=" + num;
    }
}

它可以毫無錯誤地進行編譯,並且根據getTableCellRenderer教程和我為之傾倒的其他眾多示例應該可以正常工作

問題是您沒有正確實現渲染器。 我建議您從有關使用自定義渲染器的Swing教程開始,以獲取適當的示例。

您創建的方法永遠不會被調用。 DefaultTableCellRenderer的getTableCellRendererComponent(...)方法沒有將PhoneNumber作為參數。 它有一個Object

每當您嘗試覆蓋方法時,請不要忘記@Override注釋:

@Override
getTableCellRendererComponent(JTable table, PhoneNumber value, boolean isSelected, boolean hasFocus, int row, int column)

現在嘗試編譯您的代碼,因為您要覆蓋的方法的方法簽名不存在,您將收到錯誤消息。

要在渲染器中格式化數據,更簡單的方法是重寫渲染器的setValue(...)方法。 該代碼將類似於:

public class PhoneNumberRenderer extends DefaultTableCellRenderer
{
    public PhoneNumberRenderer()
    {
        super();
        setHorizontalAlignment(SwingConstants.CENTER);
    }

    @Override
    public void setValue(Object value)
    {
        if (value instanceof PhoneNumber)
        {
            PhoneNumber pn = (PhoneNumber)value;
            value = "(" + pn.areaCode + ") " + pn.prefix" + "...";
        }

        super.setValue(value);
    }
}

您可能要在PhoneNumber類中創建getFormattedPhoneNumber()方法,以格式化的String形式返回電話號碼。 其他類不應真正直接訪問變量,而將數據格式化在單個位置始終是一個好主意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM