I’m working on a homework assignment that has four text fields and one text area, and a button that saves the text fields and text area to a text file, one element per line. Then, a dialog should notify the user that the file has been saved. It should then empty the text fields and text area when the dialog is closed. However, I’m having some issues with the program.
Regarding the dialog window, the program displays the following error when I attempt to compile:
emailProg.java:81: error: no suitable method found for showMessageDialog(emailProg.sendAction, String)
JOptionPane.showMessageDialog(this, "Saved");
^
Second, I am unsure of how to empty the textfields and textareas after closing the dialog. I know that emptying a textfield can be done by using code such as:
[textfield].setText("");
But I’m not sure how to do this only after closing the dialog.
Here is my code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class emailProg extends JFrame {
private JPanel panNorth;
private JPanel panCenter;
private JPanel panSouth;
private JLabel toLabel;
private JLabel ccLabel;
private JLabel bccLabel;
private JLabel subLabel;
private JLabel msgLabel;
private JTextField toField;
private JTextField ccField;
private JTextField bccField;
private JTextField subField;
private JTextArea msgArea;
private JButton send;
//The Constructor
public emailProg() {
setTitle("Compose Email");
setLayout(new BorderLayout());
panNorth = new JPanel();
panNorth.setLayout(new GridLayout(4, 2));
JLabel toLabel = new JLabel("To:");
panNorth.add(toLabel);
JTextField toField = new JTextField(15);
panNorth.add(toField);
JLabel ccLabel = new JLabel("CC:");
panNorth.add(ccLabel);
JTextField ccField = new JTextField(15);
panNorth.add(ccField);
JLabel bccLabel = new JLabel("Bcc:");
panNorth.add(bccLabel);
JTextField bccField = new JTextField(15);
panNorth.add(bccField);
JLabel subLabel = new JLabel("Subject:");
panNorth.add(subLabel);
JTextField subField = new JTextField(15);
panNorth.add(subField);
add(panNorth, BorderLayout.NORTH);
panCenter = new JPanel();
panCenter.setLayout(new GridLayout(2, 1));
JLabel msgLabel = new JLabel("Message:");
panCenter.add(msgLabel);
JTextArea msgArea = new JTextArea(5, 15);
panCenter.add(msgArea);
add(panCenter, BorderLayout.CENTER);
panSouth = new JPanel();
panSouth.setLayout(new FlowLayout());
JButton send = new JButton("Send");
panSouth.add(send);
add(panSouth, BorderLayout.SOUTH);
send.addActionListener (new sendAction());
}
private class sendAction implements ActionListener {
public void actionPerformed (ActionEvent event) {
try {
PrintWriter outfile = new PrintWriter("email.txt");
outfile.print("To: ");
outfile.println(toField.getText());
outfile.print("CC: ");
outfile.println(ccField.getText());
outfile.print("Bcc: ");
outfile.println(bccField.getText());
outfile.print("Subject: ");
outfile.println(subField.getText());
outfile.print("Message: ");
outfile.println(msgArea.getText());
JOptionPane.showMessageDialog(this, "Saved");
}
catch(FileNotFoundException e) {
System.out.println("File not found.");
}
}
}
public static void main(String[] args) {
emailProg win = new emailProg();
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.pack();
win.setVisible(true);
}
}
I appreciate any help you can offer.
JOptionPane.showMessageDialog(...)expects a Component as its first parameter. In your case you’re calling it from a class that extends an ActionListener and as such this does not refer to a component. You can consider passing a null for this parameter. Something like this:Also as a sidenote, consider reading about Java Naming Convention. Class names ideally starts with a capital letter.
Edit: If you look closely in your code, in your constructor you’re creating local variables of the same name as your global variables and adding them to your panel. For example, you have a global
private JTextField toField;, however in your constructor you’re doing something like this:And so your global variable still remains null. When you try to perform any operation in your
actionPerformed()code using this variable, you would experience a NullPointerException.Here’s the updated code for your reference. Note that I’ve made certain changes, especially to the class names and added
SwingUtilities.invokeLater(....)to execute your code. To know why this is necessary, read about “The Event Dispatch Thread” and “Concurrency in Swing”