java - 保存数据并创建一个不包含该数据的新面板

标签 java swing

我正在用 Java 编写一个 GUI,并且有一个布局,您可以在其中找到一个 JTable 和两个用于“操作”JTable 的按钮(尽管功能仍然缺失)。每当单击两个按钮之一时,就会出现一个面板,用户可以在其中输入信息,然后在保存数据时单击“保存”按钮。

example screenshot

从可见框架的设计中可以清楚地看出,我希望“添加行”按钮向 JTable 添加新行,而“编辑行”按钮应该更改数据。

这是我的两个问题:

1

如何保存在单击“保存”时打开的新 JDialog 中输入的数据(最好在内存中)。现在,我使用 saveData() 方法和一个名为 lastData 的全局 Object[]。有更好的方法吗?此外我无法让它工作。

2

如何确保每次单击两个按钮中的任何一个时都打开一个新的 JDialog(其中没有以前的输入)。他们对打开的面板使用相同的模板。 不同之处在于“编辑行”按钮从 JTable 获取内容并将其输入到文本字段(此 MCVE 中未显示)。我的问题是,如果我在“添加行 JDialog”中输入某些内容,那么当我下次打开对话框时,输入仍然存在。如何以最佳方式在每次打开时创建新的 JDialog 或清除 JDialog 中的数据?

这是一个 MCVE:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;

public class Test extends JPanel{

    private dialogTemplate diagPanel1 = new dialogTemplate();
    private dialogTemplate diagPanel2 = new dialogTemplate();
    Object[] columnIdentifiers = {
        "id",
        "imei",
    };

    Object[][] data = {
        {"1", "123"},
        {"2", "123"},
        {"3", "123"}
    };

    private JDialog addDialog;
    private JDialog editDialog;
    private static DefaultTableModel model;
    private JTable table;

    public Test(){ 
        setLayout(new BorderLayout());
        JPanel pane = new JPanel(new BorderLayout());

        JButton addRow = new JButton("Add Row");
        addRow.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                openAddRowPane("Add Row");
            }
        });
        JButton editRow = new JButton("Edit Row");
        editRow.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                openEditRowPane("Edit Row");
            }
        });

        JPanel buttonPane = new JPanel(new GridLayout(0, 1));
        TitledBorder buttonBorder = new TitledBorder("Buttons");
        buttonPane.setBorder(buttonBorder);

        buttonPane.add(addRow);
        buttonPane.add(editRow);

        model = new DefaultTableModel();
        model.setColumnIdentifiers(columnIdentifiers);
        JTable table = new JTable(model);

        for(int i = 0; i < data.length; i++){
            model.insertRow(i, data[i]);
        }

        JScrollPane scrollPane = new JScrollPane(table);

        pane.add(buttonPane, BorderLayout.LINE_END);
        pane.add(scrollPane, BorderLayout.CENTER);

        add(pane, BorderLayout.CENTER);
    }

    public void openAddRowPane(String name){
        if(addDialog == null){
            Window win = SwingUtilities.getWindowAncestor(this);
            if(win != null){
                addDialog = new JDialog(win, name,    ModalityType.APPLICATION_MODAL);
                addDialog.getContentPane().add(diagPanel1);
                addDialog.pack();
                addDialog.setLocationRelativeTo(null);
            }
        }
        addDialog.setVisible(true);
        printRow(diagPanel1.getData());
    }

    public void openEditRowPane(String name){
        if(editDialog == null){
            Window win = SwingUtilities.getWindowAncestor(this);
            if(win != null){
                editDialog = new JDialog(win, name,    ModalityType.APPLICATION_MODAL);
                editDialog.getContentPane().add(diagPanel2);
                editDialog.pack();
                editDialog.setLocationRelativeTo(null);
            }
        }
        editDialog.setVisible(true);
        printRow(diagPanel2.getData());
    }

    public void printRow(Object[] data){
        int length = data.length;
        String s = "[";
        for(int i = 0; i < length; i++){
            if(i == length-1){
                s += data[i].toString() + "]";
            } else {
                s += data[i].toString() + ", ";
            }
        }
        System.out.println(s);
    }

    public static void createAndShowGUI(){
        JFrame frame = new JFrame("MCVE");      
        Template_StackOverflowExample mainPanel = new     Template_StackOverflowExample();
        frame.add(mainPanel);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

class dialogTemplate extends JPanel{

    private JComponent[] content;
    private String[] labelHeaders = {
        "ID:",
        "IMEI:",
    };

    private Object[] lastData;

    public dialogTemplate(){
        JPanel diagTemplate = new JPanel();
        diagTemplate.setLayout(new BorderLayout());
        JPanel rowContent = new JPanel(new GridLayout(0, 2));

        JLabel idLabel = null;
        JLabel imeiLabel = null;

        JLabel[] labels = {
            idLabel,
            imeiLabel,
        };

        JTextField idTextField = new JTextField(20);
        JTextField imeiTextField = new JTextField(20);

        content = new JComponent[] {
            idTextField,
            imeiTextField,
        };

        for(int i = 0; i < labels.length; i++){
            labels[i] = new JLabel(labelHeaders[i]);
            rowContent.add(labels[i]);
            rowContent.add(content[i]);
            labels[i].setLabelFor(content[i]);
        }

        JButton save = new JButton("Save"); 
        save.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                saveData();
                closeWindow();
            }
        });
        JButton cancel = new JButton("Cancel");
        cancel.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                closeWindow();
            }
        });

        JPanel buttonPane = new JPanel(new GridLayout(0, 1, 5, 5));
        buttonPane.add(save);
        buttonPane.add(cancel);

        buttonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        diagTemplate.add(buttonPane, BorderLayout.PAGE_END);
        diagTemplate.add(rowContent, BorderLayout.CENTER);

        add(diagTemplate);
    }

    public void saveData(){
        lastData = new Object[content.length];

        for(int i = 0; i < lastData.length; i++){
            if(content[i] instanceof JTextField){
                JTextField temp = (JTextField) content[i];
                lastData[i] = temp.getText();
            }
        }
    }

    public Object[] getData(){
        return lastData;
    }

    public void closeWindow(){
        Window win = SwingUtilities.getWindowAncestor(this);
        if(win != null) {
            win.dispose();
        }
    }
}

作为一个小旁注,我已经在自己的示例中实现了在表中创建添加和编辑行,并且它们已被排除在此 MCVE 之外。在此示例中,我只想看到我获得了一些“数据”,因此使用了 printRow() 方法。

最佳答案

我修复了编译错误并回答了你的第二个问题。查看评论:

import java.awt.BorderLayout;
import java.awt.Dialog.ModalityType;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;

public class Template_StackOverflowExample extends JPanel{

    //changed type to DialogTemplate so you can use getData()
    //Alternatively you can keep the type as JPanle and cast:
    // ((DialogTemplate)diagPanel1).getData()
    private DialogTemplate diagPanel1 = new DialogTemplate();
    private DialogTemplate diagPanel2 = new DialogTemplate();

    Object[] columnIdentifiers = {
        "id",
        "imei",
    };

    Object[][] data = {
        {"1", "123"},
        {"2", "123"},
        {"3", "123"}
    };

    private JDialog addDialog;
    private JDialog editDialog;
    private static DefaultTableModel model;
    private JTable table;

    public Template_StackOverflowExample(){
        setLayout(new BorderLayout());
        JPanel pane = new JPanel(new BorderLayout());

        JButton addRow = new JButton("Add Row");
        addRow.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                openAddRowPane("Add Row");
            }
        });
        JButton editRow = new JButton("Edit Row");
        editRow.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                openEditRowPane("Edit Row");
            }
        });

        JPanel buttonPane = new JPanel(new GridLayout(0, 1));
        TitledBorder buttonBorder = new TitledBorder("Buttons");
        buttonPane.setBorder(buttonBorder);

        buttonPane.add(addRow);
        buttonPane.add(editRow);

        model = new DefaultTableModel();
        model.setColumnIdentifiers(columnIdentifiers);
        JTable table = new JTable(model);

        for(int i = 0; i < data.length; i++){
            model.insertRow(i, data[i]);
        }

        JScrollPane scrollPane = new JScrollPane(table);

        pane.add(buttonPane, BorderLayout.LINE_END);
        pane.add(scrollPane, BorderLayout.CENTER);

        add(pane, BorderLayout.CENTER);
    }

    public void openAddRowPane(String name){
        //remove to make a new JDiag each time
        //if(addDialog == null){
            Window win = SwingUtilities.getWindowAncestor(this);
            //if(win != null){ //it is ok if win is null
                addDialog = new JDialog(win, name,    ModalityType.APPLICATION_MODAL);
                addDialog.getContentPane().add(diagPanel1);
                addDialog.pack();
                addDialog.setLocationRelativeTo(null);
            //}
        //}
        addDialog.setVisible(true);
        printRow(diagPanel1.getData());
    }

    public void openEditRowPane(String name){
        //remove to make a new JDiag each time
        //if(editDialog == null){
            Window win = SwingUtilities.getWindowAncestor(this);
            //if(win != null){//it ok if win = null
                editDialog = new JDialog(win, name,    ModalityType.APPLICATION_MODAL);
                editDialog.getContentPane().add(diagPanel2);
                editDialog.pack();
                editDialog.setLocationRelativeTo(null);
            //}
        //}
        editDialog.setVisible(true);
        printRow(diagPanel2.getData());
    }

    public void printRow(Object[] data){

        //add null protection
        if(data == null) {
            return;
        }
        int length = data.length;
        String s = "[";
        for(int i = 0; i < length; i++){
            if(i == (length-1)){
                s += data[i].toString() + "]";
            } else {
                s += data[i].toString() + ", ";
            }
        }
        System.out.println(s);
    }

    public static void createAndShowGUI(){
        JFrame frame = new JFrame("MCVE");
        Template_StackOverflowExample mainPanel = new     Template_StackOverflowExample();
        frame.add(mainPanel);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

//changed name to start with capital letter
class DialogTemplate extends JPanel{

    private JComponent[] content;
    private String[] labelHeaders = {
        "ID:",
        "IMEI:",
    };

    private Object[] lastData;

    public DialogTemplate(){
        JPanel diagTemplate = new JPanel();
        diagTemplate.setLayout(new BorderLayout());
        JPanel rowContent = new JPanel(new GridLayout(0, 2));

        JLabel idLabel = null;
        JLabel imeiLabel = null;

        JLabel[] labels = {
            idLabel,
            imeiLabel,
        };

        JTextField idTextField = new JTextField(20);
        JTextField imeiTextField = new JTextField(20);

        content = new JComponent[] {
            idTextField,
            imeiTextField,
        };

        for(int i = 0; i < labels.length; i++){
            labels[i] = new JLabel(labelHeaders[i]);
            rowContent.add(labels[i]);
            rowContent.add(content[i]);
            labels[i].setLabelFor(content[i]);
        }

        JButton save = new JButton("Save");
        save.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                saveData();
                closeWindow();
            }
        });
        JButton cancel = new JButton("Cancel");
        cancel.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                closeWindow();
            }
        });

        JPanel buttonPane = new JPanel(new GridLayout(0, 1, 5, 5));
        buttonPane.add(save);
        buttonPane.add(cancel);

        buttonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        diagTemplate.add(buttonPane, BorderLayout.PAGE_END);
        diagTemplate.add(rowContent, BorderLayout.CENTER);

        add(diagTemplate);
    }

    public void saveData(){
        lastData = new Object[content.length];

        for(int i = 0; i < lastData.length; i++){
            if(content[i] instanceof JTextField){
                JTextField temp = (JTextField) content[i];
                lastData[i] = temp.getText();
            }
        }
    }

    public Object[] getData(){
        return lastData;
    }

    public void closeWindow(){
        Window win = SwingUtilities.getWindowAncestor(this);
        if(win != null) {
            win.dispose();
        }
    }
}

(顺便说一句:为什么每次都想打开一个新的诊断?)

为了解决第二个问题,我添加了一个带有 getData() 功能的 JDialog 子类。查看评论:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;

public class Template_StackOverflowExample extends JPanel{

    //changed type to DialogTemplate so you can use getData()
    //Alternatively you can keep the type as JPanle and cast:
    // ((DialogTemplate)diagPanel1).getData()
    private DialogTemplate diagPanel1 = new DialogTemplate();
    private DialogTemplate diagPanel2 = new DialogTemplate();

    Object[] columnIdentifiers = {
            "id",
            "imei",
    };

    Object[][] data = {
            {"1", "123"},
            {"2", "123"},
            {"3", "123"}
    };

    //changed type to JDialog subclass
    private Dialog addDialog;
    private Dialog editDialog;

    private static DefaultTableModel model;
    private JTable table;

    public Template_StackOverflowExample(){
        setLayout(new BorderLayout());
        JPanel pane = new JPanel(new BorderLayout());

        JButton addRow = new JButton("Add Row");
        addRow.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                addDialog = openDialog("Add Row");
                Object[] getData = addDialog.getData();
                printRow(getData);
            }
        });
        JButton editRow = new JButton("Edit Row");
        editRow.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                editDialog = openDialog("Edit Row");
                Object[] getData = editDialog.getData();
                printRow(getData);

            }
        });

        JPanel buttonPane = new JPanel(new GridLayout(0, 1));
        TitledBorder buttonBorder = new TitledBorder("Buttons");
        buttonPane.setBorder(buttonBorder);

        buttonPane.add(addRow);
        buttonPane.add(editRow);

        model = new DefaultTableModel();
        model.setColumnIdentifiers(columnIdentifiers);
        JTable table = new JTable(model);

        for(int i = 0; i < data.length; i++){
            model.insertRow(i, data[i]);
        }

        JScrollPane scrollPane = new JScrollPane(table);

        pane.add(buttonPane, BorderLayout.LINE_END);
        pane.add(scrollPane, BorderLayout.CENTER);

        add(pane, BorderLayout.CENTER);
    }

    public Dialog openDialog(String name){

        Window win = SwingUtilities.getWindowAncestor(this);
        return new Dialog(win, new DialogTemplate(), name);
    }

    public void printRow(Object[] data){

        //add null protection
        if(data == null) {
            return;
        }
        int length = data.length;
        String s = "[";
        for(int i = 0; i < length; i++){
            if(i == (length-1)){
                s += data[i].toString() + "]";
            } else {
                s += data[i].toString() + ", ";
            }
        }
        System.out.println(s);
    }

    public static void createAndShowGUI(){
        JFrame frame = new JFrame("MCVE");
        Template_StackOverflowExample mainPanel = new     Template_StackOverflowExample();
        frame.add(mainPanel);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

//subclassed JDialog to add get data functionality
class Dialog extends JDialog {

    DialogTemplate diagPanel;

    Dialog(Window win, DialogTemplate diagPanel, String name) {

        super(win, name,  ModalityType.APPLICATION_MODAL);
        this.diagPanel = diagPanel;
        getContentPane().add(diagPanel);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    Object[] getData(){
        return diagPanel.getData();
    }
}


//changed name to start with capital letter
class DialogTemplate extends JPanel{

    private JComponent[] content;
    private String[] labelHeaders = {
            "ID:",
            "IMEI:",
    };

    private Object[] lastData;

    public DialogTemplate(){
        JPanel diagTemplate = new JPanel();
        diagTemplate.setLayout(new BorderLayout());
        JPanel rowContent = new JPanel(new GridLayout(0, 2));

        JLabel idLabel = null;
        JLabel imeiLabel = null;

        JLabel[] labels = {
                idLabel,
                imeiLabel,
        };

        JTextField idTextField = new JTextField(20);
        JTextField imeiTextField = new JTextField(20);

        content = new JComponent[] {
                idTextField,
                imeiTextField,
        };

        for(int i = 0; i < labels.length; i++){
            labels[i] = new JLabel(labelHeaders[i]);
            rowContent.add(labels[i]);
            rowContent.add(content[i]);
            labels[i].setLabelFor(content[i]);
        }

        JButton save = new JButton("Save");
        save.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                saveData();
                closeWindow();
            }
        });
        JButton cancel = new JButton("Cancel");
        cancel.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                closeWindow();
            }
        });

        JPanel buttonPane = new JPanel(new GridLayout(0, 1, 5, 5));
        buttonPane.add(save);
        buttonPane.add(cancel);

        buttonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        diagTemplate.add(buttonPane, BorderLayout.PAGE_END);
        diagTemplate.add(rowContent, BorderLayout.CENTER);

        add(diagTemplate);
    }

    public void saveData(){
        lastData = new Object[content.length];

        for(int i = 0; i < lastData.length; i++){
            if(content[i] instanceof JTextField){
                JTextField temp = (JTextField) content[i];
                lastData[i] = temp.getText();
            }
        }
    }

    public Object[] getData(){
        return lastData;
    }

    public void closeWindow(){
        Window win = SwingUtilities.getWindowAncestor(this);
        if(win != null) {
            win.dispose();
        }
    }
}

关于java - 保存数据并创建一个不包含该数据的新面板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38219675/

相关文章:

java - ControlsFX 电子表格 View : How to hide column?

java - Swing Worker 无法更新模态 jdialog 中的 GUI 组件

java - JMS 选择器奇怪的行为

java - 子集和问题: Returning a Variant of the Required Subset

java - Spring Boot、Thymeleaf 和@Controller

java - 在 web.xml 中使用带有过滤器符号的 Jersey2 ContainerRequestFilter

java - 禁用鼠标将文本放入 JTextField 并允许粘贴按键事件

java - Swing样本表格申请

java - 从 C 驱动器以 Java 代码加载图像

java - 从 GUI 启动命令行工具