JTextField in JDialog retaining value after dispos

2019-08-12 17:17发布

问题:

I'm having a JTextField problem. I am needing to get text from a JTextField and modify it later in a JDialog. I am using the same variable for the JTextField. As long as you don't enter the dialog, the string printed is whatever you entered in the text field. If you enter a string in the dialog, it will only print that string until you change it again in the dialog (renders the primary text field useless). I can fix this by adding a separate variable, but would like to try to avoid unnecessary declarations. I was under the impression that this shouldn't matter since I'm creating a new JTextField object and also disposing of the dialog. Am I missing something? Any thoughts?

Here is a mock up of my problem.

import java.awt.event.*;
import javax.swing.*;

public class textfield extends JPanel {

    private JTextField textfield;
    private JButton printButton, dialogButton, okayButton;
    private static JFrame frame;

    public static void main(String[] args) {
        frame = new JFrame();
        frame.setSize(200,200);
        frame.getContentPane().add(new textfield());
        frame.setVisible(true);
    }

    private textfield() {
        textfield = new JTextField(10);
        add(textfield);
        ((AbstractButton) add(printButton = new JButton("Print"))).addActionListener(new printListener());
        ((AbstractButton) add(dialogButton = new JButton("Dialog"))).addActionListener(new dialogListener());

    }

    private class printListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            String string = null;
            string = textfield.getText();
            System.out.println(string);
        }
    }

    private class dialogListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            final JDialog dialog = new JDialog(frame, "Dialog", true);
            JPanel p = new JPanel();
            textfield = new JTextField(10);
            p.add(textfield);
            p.add(okayButton = new JButton(new AbstractAction("Okay") {
                public void actionPerformed(ActionEvent e) {
                    String string = null;
                    string = textfield.getText();
                    System.out.println(string);
                    dialog.dispose();
                }
            }));
            dialog.add(p);
            dialog.pack();
            dialog.setVisible(true);

        }
    }   
}

回答1:

you need to make JTextField inside the dialog, because when you are using one textfield, your main panel will point to new JTextField that was created in child dialog that was disposed when you press okey button (destroyed all its components). so don't change panel textfield pointer to new textfield object in disposed window.



回答2:

your variable private JTextField textfield; is used twice, firstly for JFrame, and second time for JDialod, little bit changed ..

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class MyTextfield extends JPanel {

    private static final long serialVersionUID = 1L;
    private JTextField textfield, textfield1; //added new variable
    private JButton printButton, dialogButton, okayButton;
    private static JFrame frame;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {//added initial thread

            @Override
            public void run() {
                frame = new JFrame();
                frame.setSize(200, 200);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//added default close operation
                frame.getContentPane().add(new MyTextfield());
                frame.setVisible(true);
            }
        });
    }

    private MyTextfield() {
        textfield = new JTextField(10);
        add(textfield);
        ((AbstractButton) add(printButton = new JButton("Print"))).addActionListener(new printListener());
        ((AbstractButton) add(dialogButton = new JButton("Dialog"))).addActionListener(new dialogListener());

    }

    private class printListener implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            String string = null;
            string = textfield.getText();
            System.out.println(string);
        }
    }

    private class dialogListener implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            final JDialog dialog = new JDialog(frame, "Dialog", true);
            JPanel p = new JPanel();
            textfield1 = new JTextField(10);
            p.add(textfield1);
            p.add(okayButton = new JButton(new AbstractAction("Okay") {

                private static final long serialVersionUID = 1L;

                public void actionPerformed(ActionEvent e) {
                    String string = null;
                    textfield.setText(textfield1.getText());
                    System.out.println(string);
                    dialog.dispose();
                }
            }));
            dialog.add(p);
            dialog.pack();
            dialog.setVisible(true);
        }
    }
}