Java Swing:如何解析一个 Phone 数字、格式化它并在 JTable 中显示它
Java Swing: How To Parse A Phone Number, Format It, And Display It In A JTable
我正在尝试将 JTable
中的 phone 数字列格式化为 (Area) Prefix-Number
。我不确定我做错了什么,因为它编译时没有错误,并且根据 getTableCellRenderer
教程和我仔细研究过的其他大量示例,它应该可以工作。但它没有...它仍然被格式化为 JTable 中的一个字符串。
我首先接受来自一个文本字段的用户输入 phone 数字:
//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>");
}
}
然后我尝试将它传递到 Phone 数字 class 以尝试解析字符串:
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
class:
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);
}
}
}
phone 号码从 MySQL database
的 tinytext
列中存储和检索。如果需要,请随时索取更多代码,我砍掉了很多部分来尝试缩短问题。
好吧...我完全迷路了,诚然,我是 Java Swing.I 的新手,尝试将 class Phone 编号调用到自定义 CellRenderer Class.我得到的结果是 (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);
}
}
Phone人数Class:
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;
}
}
it compiles without errors and according to the getTableCellRenderer tutorials and other numerous examples I've poured over it should work
问题是您没有正确实现渲染器。我建议您从 Using Custom Renderers 上的 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 class 中创建一个 getFormattedPhoneNumber()
方法来 return 格式化字符串中的 phone 号码。其他 classes 不应该直接访问变量,在一个地方格式化数据总是一个好主意。
我正在尝试将 JTable
中的 phone 数字列格式化为 (Area) Prefix-Number
。我不确定我做错了什么,因为它编译时没有错误,并且根据 getTableCellRenderer
教程和我仔细研究过的其他大量示例,它应该可以工作。但它没有...它仍然被格式化为 JTable 中的一个字符串。
我首先接受来自一个文本字段的用户输入 phone 数字:
//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>");
}
}
然后我尝试将它传递到 Phone 数字 class 以尝试解析字符串:
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
class:
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);
}
}
}
phone 号码从 MySQL database
的 tinytext
列中存储和检索。如果需要,请随时索取更多代码,我砍掉了很多部分来尝试缩短问题。
好吧...我完全迷路了,诚然,我是 Java Swing.I 的新手,尝试将 class Phone 编号调用到自定义 CellRenderer Class.我得到的结果是 (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);
}
}
Phone人数Class:
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;
}
}
it compiles without errors and according to the getTableCellRenderer tutorials and other numerous examples I've poured over it should work
问题是您没有正确实现渲染器。我建议您从 Using Custom Renderers 上的 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 class 中创建一个 getFormattedPhoneNumber()
方法来 return 格式化字符串中的 phone 号码。其他 classes 不应该直接访问变量,在一个地方格式化数据总是一个好主意。