当前位置: 首页 > 知识库问答 >
问题:

保存单元格更改在JTable仅如果按钮按下,如果不停留之前

姬宝
2023-03-14

如果我在上面的JTable中选择一行,那么与该数据对应的一行将出现在下面的JTable中。以下Jtable中的所有单元格都是可编辑的。我需要的是:

如果我按下按钮,下面Jtable中的更改将被保存。如果我不按下按钮,JTable单元格将保持应用程序的原始状态。

PS:这是一个演示,真实案例包含更多参数,但目的是一样的。

    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);
    }
}

共有1个答案

奚英朗
2023-03-14

一般的解决方案是制作患者数据的深度副本,并使用该数据副本创建辅助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
                + "]";
    }

}
 类似资料:
  • 问题内容: 我正在尝试获取所有用户,并通过另一个表上的字段对他们进行排序,但是此字段并不总是存在吗? 用户-持有用户用户元-持有元数据,特别是“权重”,这是我要根据其排序的内容。 一个更具体的解决方案是自动为它们定义默认权重,但是无论如何,我可以使它不起作用吗?当前工作查询: 失去部分订单,任何/所有帮助将不胜感激! 问题答案: 如果您在表()之间具有关键关系,并且想要列出所有用户,则可以使用类似

  • 问题内容: 我正在使用此处找到的自定义表格模型。我已经使用该帖子中提供的建议更新了我的代码,并遇到了一个新问题。我对我的代码所做的改变是一个注入到我,以避免与线程的问题。完成此操作后,通过按按钮更新我的表的代码已停止工作。 用于初始化的代码如下: 我用来更新的代码如下: 我也尝试过使用,但这也不起作用。截至目前,更新的唯一方法是关闭并重新打开程序。具有我正在使用的,随着用户添加更多玩家,尺寸会增加

  • 我正在制作一个表单,其中使用jQuery进行客户端验证,然后在提交后使用PHP进行服务器端验证。我的问题是,通过使用$(“Form”).Submit(函数(e){},当我单击Cancel和Delete按钮时,验证消息也会出现,而这是不应该的。我只希望只有当单击Save按钮时才会发生验证。有没有其他方法可以做到这一点?非常感谢。下面是我的代码:

  • 我有一些问题与内置的Android按钮栏样式。在给我的每个按钮宽度0和重量1之后,两个按钮之间仍然有大约1px的间隙(见图)。 消除这种差距的最好方法是什么?为什么它一开始就在那里?

  • 问题内容: 我有一个包含几个用户可编辑项(EditText字段,RatingBar等)的活动。我想提示用户是否按下了后退/主页按钮,并且所做的更改尚未保存。阅读完android文档后,似乎这段代码应该放在onPause方法中。我尝试将AlertDialog放在onPause中,但是显示对话框然后立即将其删除,因为没有任何内容可以阻止暂停完成。 到目前为止,这是我想出的: 我是在正确的轨道上吗,还是

  • 我想更改按钮的背景色和前景色。我使用了setBackground、setForeground和SetObque(true),它适用于前景,但不适用于按钮的背景。按钮周围有点像黑色边框,但我希望按钮本身是黑色的。我该怎么修?