Java 仅当按下按钮时才将单元格更改保存在JTable中,而不是像以前一样保留
如果我在上面的JTable中选择一行,那么与该数据对应的一行将出现在下面的JTable中。以下Jtable中的所有单元格都是可编辑的。我需要的是: 如果我按下按钮,下面Jtable中的更改将被保存。如果我不按下按钮,JTable单元格将保持应用程序的原始状态 PS:这是一个演示,真实案例包含更多参数,但目的是一样的Java 仅当按下按钮时才将单元格更改保存在JTable中,而不是像以前一样保留,java,swing,jtable,Java,Swing,Jtable,如果我在上面的JTable中选择一行,那么与该数据对应的一行将出现在下面的JTable中。以下Jtable中的所有单元格都是可编辑的。我需要的是: 如果我按下按钮,下面Jtable中的更改将被保存。如果我不按下按钮,JTable单元格将保持应用程序的原始状态 PS:这是一个演示,真实案例包含更多参数,但目的是一样的 package guarreo; import java.awt.BorderLayout; import java.awt.EventQueue; import jav
package guarreo;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.JButton;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class demo extends JFrame {
private JPanel contentPane;
private JTable tablePATIENTS;
private JTable tableREPORTS;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
demo frame = new demo();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public demo() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 571, 336);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
tablePATIENTS = new JTable();
tablePATIENTS.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
if(tablePATIENTS.getSelectedRow()!=-1){//If there is a patient selected with a report, enable the save changes button
DefaultTableModel dtm2 = (DefaultTableModel) tableREPORTS.getModel();
dtm2.addRow(new Object[]{"200$", "Pills", "Headache"});
tableREPORTS.setModel(dtm2);
}
}
});
tablePATIENTS.setModel(new DefaultTableModel(
new Object[][] {
},
new String[] {
"Name", "Surrname", "Doctor"
}
));
DefaultTableModel dtm = (DefaultTableModel) tablePATIENTS.getModel();
dtm.addRow(new Object[]{"Jon", "Snow", "Jack"});
JButton btnSaveChanges = new JButton("Save changes tableREPORTS");
btnSaveChanges.setEnabled(false);
btnSaveChanges.setBounds(155, 260, 212, 23);
contentPane.add(btnSaveChanges);
tablePATIENTS.setModel(dtm);
tablePATIENTS.setBounds(20, 11, 486, 107);
contentPane.add(tablePATIENTS);
tableREPORTS = new JTable();
tableREPORTS.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
btnSaveChanges.setEnabled(true); //Enabled only if something selected in this table
}
});
tableREPORTS.setModel(new DefaultTableModel(
new Object[][] {
},
new String[] {
"Cost", "Treatment", "Disease"
}
));
tableREPORTS.setBounds(20, 144, 486, 105);
contentPane.add(tableREPORTS);
}
}
一般的解决方案是制作患者数据的深度副本,并使用此副本创建辅助JTable数据。然后,用户可以根据自己的意愿对JTable数据进行任何更改,而无需担心副作用。一旦按下按钮,它的ActionListener就会将JTable模型的数据转换回患者的数据,替换原始数据。因此,关键是在按下按钮之前不要进行更换 如果Patient类拥有一个信息类对象的ArrayList,那么该列表的获取者应该通过创建一个新的ArrayList来创建一个深度副本,并在for循环中,使用原始列表中所拥有对象的深度副本来填充它 例如:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
@SuppressWarnings("serial")
public class MyDemo extends JPanel {
private static final int GAP = 3;
private MyPatientTableModel patientModel = new MyPatientTableModel();
private JTable patientTable = new JTable(patientModel);
private JTable ptVisitTable = new JTable(new MyPtVisitTableModel(new ArrayList<MyPtVisit>()));
public MyDemo() {
MyPatient pt0 = new MyPatient("001", "Johnson", "Michael");
pt0.addVisit(new MyPtVisit(200, "Head Ache", "Narcotics"));
pt0.addVisit(new MyPtVisit(300, "Body Ache", "Aspirin"));
pt0.addVisit(new MyPtVisit(400, "Total Ache", "Nothing"));
MyPatient pt1 = new MyPatient("002", "Smith", "John");
pt1.addVisit(new MyPtVisit(220, "Head Ache", "Narcotics"));
pt1.addVisit(new MyPtVisit(320, "Body Ache", "Aspirin"));
pt1.addVisit(new MyPtVisit(420, "Total Ache", "Nothing"));
MyPatient pt2 = new MyPatient("003", "Baker", "Betty");
pt2.addVisit(new MyPtVisit(240, "Head Ache", "Narcotics"));
pt2.addVisit(new MyPtVisit(340, "Body Ache", "Aspirin"));
pt2.addVisit(new MyPtVisit(440, "Total Ache", "Nothing"));
MyPatient pt3 = new MyPatient("004", "Duck", "Donald");
pt3.addVisit(new MyPtVisit(260, "Head Ache", "Narcotics"));
pt3.addVisit(new MyPtVisit(360, "Body Ache", "Aspirin"));
pt3.addVisit(new MyPtVisit(460, "Total Ache", "Nothing"));
MyPatient[] pts = { pt0, pt1, pt2, pt3 };
for (MyPatient myPatient : pts) {
patientModel.addRow(myPatient);
}
patientTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
patientTable.getSelectionModel().addListSelectionListener(new PatientTableListener());
TableColumnModel tcm = patientTable.getColumnModel();
tcm.removeColumn(tcm.getColumn(3)); // visits column should be invisible
patientTable.setFillsViewportHeight(true);
ptVisitTable.setFillsViewportHeight(true);
Dimension size = patientTable.getPreferredScrollableViewportSize();
size = new Dimension(size.width, size.height / 2);
patientTable.setPreferredScrollableViewportSize(size);
size = ptVisitTable.getPreferredScrollableViewportSize();
size = new Dimension(size.width, size.height / 2);
ptVisitTable.setPreferredScrollableViewportSize(size);
JScrollPane ptTableScrollPane = new JScrollPane(patientTable);
JScrollPane ptVisitScrollPane = new JScrollPane(ptVisitTable);
JPanel btnPanel = new JPanel();
btnPanel.add(new JButton(new SaveChangesAction("Save Changes")));
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(ptTableScrollPane);
add(Box.createVerticalStrut(GAP));
add(ptVisitScrollPane);
add(Box.createVerticalStrut(GAP));
add(btnPanel);
}
private class SaveChangesAction extends AbstractAction {
public SaveChangesAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
int index = patientTable.getSelectedRow();
if (index < 0) {
return;
}
// to capture edits not yet complete
if (ptVisitTable.isEditing()) {
CellEditor cellEditor = ptVisitTable.getCellEditor();
if (cellEditor != null) {
cellEditor.stopCellEditing();
}
}
index = patientTable.convertRowIndexToModel(index);
MyPatient selectedPatient = patientModel.getPatient(index);
MyPtVisitTableModel visitsModel = (MyPtVisitTableModel) ptVisitTable.getModel();
List<MyPtVisit> visits = visitsModel.getVisits();
selectedPatient.setVisits(visits);
patientModel.setPatientAt(index, selectedPatient);
}
}
private class PatientTableListener implements ListSelectionListener {
@Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
return;
}
int index = patientTable.getSelectedRow();
if (index < 0) {
return;
}
index = patientTable.convertRowIndexToModel(index);
MyPatient selectedPatient = patientModel.getPatient(index);
List<MyPtVisit> visits = selectedPatient.getVisits();
MyPtVisitTableModel visitsModel = new MyPtVisitTableModel(visits);
ptVisitTable.setModel(visitsModel);
}
}
private static void createAndShowGui() {
MyDemo mainPanel = new MyDemo();
JFrame frame = new JFrame("My Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
@SuppressWarnings("serial")
class MyPatientTableModel extends DefaultTableModel {
public MyPatientTableModel() {
super(MyPatient.HEADINGS, 0);
}
@SuppressWarnings("unchecked")
public MyPatient getPatient(int index) {
String patientId = (String) getValueAt(index, 0);
String lastName = (String) getValueAt(index, 1);
String firstName = (String) getValueAt(index, 2);
// non-displayed data
List<MyPtVisit> visits = (List<MyPtVisit>) getValueAt(index, 3);
MyPatient patient = new MyPatient(patientId, lastName, firstName);
patient.setVisits(visits);
return patient;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
if (getRowCount() != 0 && getValueAt(0, columnIndex) != null) {
return getValueAt(0, columnIndex).getClass();
} else {
return super.getColumnClass(columnIndex);
}
}
public void addRow(MyPatient patient) {
Vector<Object> rowData = new Vector<>();
rowData.add(patient.getPatientId());
rowData.add(patient.getLastName());
rowData.add(patient.getFirstName());
rowData.add(patient.getVisits()); // not displayed!
addRow(rowData);
}
public void setPatientAt(int row, MyPatient patient) {
setValueAt(patient.getPatientId(), row, 0);
setValueAt(patient.getLastName(), row, 1);
setValueAt(patient.getFirstName(), row, 2);
setValueAt(patient.getVisits(), row, 3);
}
}
@SuppressWarnings("serial")
class MyPtVisitTableModel extends DefaultTableModel {
public MyPtVisitTableModel(List<MyPtVisit> visits) {
super(MyPtVisit.HEADINGS, 0);
for (MyPtVisit myPtVisit : visits) {
addRow(myPtVisit);
}
}
@Override
public Class<?> getColumnClass(int columnIndex) {
if (getRowCount() != 0 && getValueAt(0, columnIndex) != null) {
return getValueAt(0, columnIndex).getClass();
} else {
return super.getColumnClass(columnIndex);
}
}
public void addRow(MyPtVisit myPtVisit) {
Vector<Object> rowData = new Vector<>();
rowData.add(myPtVisit.getCost());
rowData.add(myPtVisit.getSymptom());
rowData.add(myPtVisit.getTreatment());
addRow(rowData);
}
// extract data from table model
public List<MyPtVisit> getVisits() {
List<MyPtVisit> visits = new ArrayList<>();
for (int i = 0; i < getRowCount(); i++) {
double cost = (double) getValueAt(i, 0);
String symptom = (String) getValueAt(i, 1);
String treatment = (String) getValueAt(i, 2);
visits.add(new MyPtVisit(cost, symptom, treatment));
}
return visits;
}
}
// class that represents each patient
class MyPatient {
public static final String[] HEADINGS = { "Patient ID", "Last Name", "First Name", "Visits" };
private String patientId;
private String lastName;
private String firstName;
private List<MyPtVisit> visits = new ArrayList<>();
public MyPatient(String patientId, String lastName, String firstName) {
this.patientId = patientId;
this.lastName = lastName;
this.firstName = firstName;
}
public String getPatientId() {
return patientId;
}
public void setPatientId(String patientId) {
this.patientId = patientId;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void addVisit(MyPtVisit ptVisit) {
visits.add(ptVisit);
}
public List<MyPtVisit> getVisits() {
// create new ArrayList to hold copy
List<MyPtVisit> copyVisits = new ArrayList<>();
for (MyPtVisit myPtVisit : visits) {
// use MyPtVisit's copy constructor to create a new MyPtVisit
copyVisits.add(new MyPtVisit(myPtVisit));
}
return copyVisits;
}
public void setVisits(List<MyPtVisit> visits) {
this.visits = visits;
}
@Override
public String toString() {
return "MyPatient [patientId=" + patientId + ", lastName=" + lastName + ", firstName="
+ firstName + ", visits=" + visits + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
result = prime * result + ((patientId == null) ? 0 : patientId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MyPatient other = (MyPatient) obj;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
if (patientId == null) {
if (other.patientId != null)
return false;
} else if (!patientId.equals(other.patientId))
return false;
return true;
}
}
// my patient visit
// holds information for each patient's visit to the doctor
class MyPtVisit {
public static final String[] HEADINGS = { "Cost", "Chief Symptom", "Treatment" };
private double cost;
private String symptom;
private String treatment;
public MyPtVisit(double cost, String symptom, String treatment) {
this.cost = cost;
this.symptom = symptom;
this.treatment = treatment;
}
// copy constructor
public MyPtVisit(MyPtVisit original) {
this.cost = original.cost;
this.symptom = original.symptom;
this.treatment = original.treatment;
}
public double getCost() {
return cost;
}
public void setCost(double cost) {
this.cost = cost;
}
public String getSymptom() {
return symptom;
}
public void setSymptom(String symptom) {
this.symptom = symptom;
}
public String getTreatment() {
return treatment;
}
public void setTreatment(String treatment) {
this.treatment = treatment;
}
@Override
public String toString() {
return "MyPtVisit [cost=" + cost + ", symptom=" + symptom + ", treatment=" + treatment
+ "]";
}
}
导入java.awt.Dimension;
导入java.awt.event.ActionEvent;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Vector;
导入javax.swing.*;
导入javax.swing.event.ListSelectionEvent;
导入javax.swing.event.ListSelectionListener;
导入javax.swing.table.DefaultTableModel;
导入javax.swing.table.TableColumnModel;
@抑制警告(“串行”)
公共类MyDemo扩展了JPanel{
专用静态最终内部间隙=3;
私有MyPatientTableModel patientModel=新MyPatientTableModel();
私有JTable patientTable=新JTable(patientModel);
私有JTable ptVisitTable=newjtable(newmyptvisittablemodel(newarraylist());
公共MyDemo(){
MyPatient pt0=新的MyPatient(“001”、“约翰逊”、“迈克尔”);
pt0.addVisit(新的MyPtVisit(200,“头痛”、“麻醉品”);
pt0.addVisit(新的MyPtVisit(300,“身体疼痛”、“阿司匹林”);
pt0.addVisit(新的MyPtVisit(400,“总疼痛”,“无”);
MyPatient pt1=新的MyPatient(“002”、“Smith”、“John”);
pt1.AddVisite(新的MyPTVisite(220,“头痛”、“麻醉品”);
pt1.AddVisite(新MyPtVisite(320,“身体疼痛”、“阿司匹林”);
pt1.addVisit(新的MyPtVisit(420,“总疼痛”,“无”);
MyPatient pt2=新的MyPatient(“003”、“Baker”、“Betty”);
pt2.AddVisite(新的MyPTVisite(240,“头痛”、“麻醉品”);
pt2.addVisit(新的MyPtVisit(340,“身体疼痛”、“阿司匹林”);
pt2.addVisit(新的MyPtVisit(440,“总疼痛”,“无”);
MyPatient pt3=新MyPatient(“004”、“Duck”、“Donald”);
pt3.addVisit(新的MyPtVisit(260,“头痛”、“麻醉品”);
pt3.addVisit(新MyPtVisit(360,“身体疼痛”、“阿司匹林”);
pt3.addVisit(新的MyPtVisit(460,“总疼痛”,“无”);
MyPatient[]pts={pt0,pt1,pt2,pt3};
用于(我的患者我的患者:pts){
patientModel.addRow(我的患者);
}
patientTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
patientTable.getSelectionModel().addListSelectionListener(新的PatientTableListener());
TableColumnModel tcm=patientTable.getColumnModel();
tcm.removeColumn(tcm.getColumn(3));//访问列应不可见
可耐心等待。设置FillsViewPerthweight(真);
ptVisitTable.setFillsViewPerthight(true);
维度大小=patientTable.getPreferredScrollableViewportSize();
尺寸=新尺寸(尺寸.宽度,尺寸.高度/2);
patientTable.setPreferredScrollableViewportSize(大小);
size=ptVisitTable.getPreferredScrollableViewportSize();
尺寸=新尺寸(尺寸.宽度,尺寸.高度/2);
ptVisitTable.setPreferredScrollableViewportSize(大小);
JScrollPane ptTableScrollPane=新的JScrollPane(patientTable);
JScrollPane ptVisitScrollPane=新的JScrollPane(ptVisitTable);
JPanel btnPanel=新的JPanel();
添加(newjbutton(newsavechangesaction(“savechanges”));
setBorder(BorderFactory.createEmptyByOrder(间隙,间隙,间隙));
setLayout(新的BoxLayout(这是BoxLayout.PAGE_轴));
添加(ptTableScrollPane);
增加(垂直支柱盒(间隙));
添加(ptVisitScrollPane);
增加(垂直支柱盒(间隙));
添加(btnPanel);
}
私有类SaveChangesAction扩展了AbstractAction{
公共存储更改操作(字符串名称){
超级(姓名);
int助记符=(int)name.charAt(0);
putValue(助记符键,助记符);
}
@凌驾
已执行的公共无效操作(操作事件e){
int index=patientTable.getSelectedRow();
如果(指数<0){
返回;
}
//捕获尚未完成的编辑
if(ptVisitTable.isEditing()){
CellEditor CellEditor=ptVisitTable.getCellEditor();
如果(cellEditor!=null){
stopCellEditing();
}
}
索引=patientTable.convertRowIndexToModel(索引);
MyPatient selectedPatient=patientModel.getPatient(索引);
MyPtVisitTableModel visitsModel=(MyPtVisitTableModel)ptVisitTable.getModel();
列表访问=visitsModel.getvisions();
选择患者。设置就诊次数(就诊次数);
patientModel.SetPatientTat(索引,selectedPatient);
}
}
私有类PatientTableListener实现ListSelectionListener{
@凌驾
public void值已更改(ListSelectionEvent e){
如果(如getValueIsAdjusting()){
返回;
}
int index=patientTable.getSelectedRow();