Reputation: 1931
I am attempting a very simple form designed to take user input into a JTextField and show that same input via a pop up dialog.
I can hardcode the JTextField to have a preset number using setText(). If I do this, my program works flawlessly.
However, when I leave the field blank and try getText() to show the text in the pop up dialog, I either get an empty pop up frame, or I get an 'empty string' exception (I am attempting to parse String to Double.)
package buttontest;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import javax.swing.*;
import java.awt.event.ActionEvent;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class ButtonTest
{
public static void main(String[] args)
{
ButtonFrame frame = new ButtonFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class ButtonFrame extends JFrame
{
@SuppressWarnings("LeakingThisInConstructor")
public ButtonFrame()
{
setTitle("SunStream Loan Calculator v2.0");
setSize(900,900);
ButtonPanel panel = new ButtonPanel();
panel.add(new JLabel("Enter your loan amount:"));
loanAmt = new JTextField(40);
panel.add(loanAmt);
add(panel,BorderLayout.CENTER);
}
public JTextField loanAmt;
class ButtonPanel extends JPanel implements ActionListener
{
private Component frame;
public ButtonPanel()
{
final JButton b2 = new JButton("Calculate");
add(b2, BorderLayout.SOUTH);
b2.setActionCommand("calculate");
b2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
ButtonFrame bf = new ButtonFrame();
if("calculate".equals(e.getActionCommand()))
{
JOptionPane.showMessageDialog(frame, bf.loanAmt.getText());
}
}
});
}
@Override
public void actionPerformed(ActionEvent ae) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
Any help would be greatly appreciated. I am researching using a KeyListener or KeyEvent but I don't quite understand it well enough.
Upvotes: 3
Views: 25037
Reputation: 1120
The only way you can access your loanAmt is through ButtonPanel itself. Because you add loanAmt to this button right ?
So, if you want access loanAmt. You must get all component on this button panel. This is my psudeo code howto accessing your loanAmt from ButtonPanel class.
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ButtonFrame bf = new ButtonFrame();
if("calculate".equals(e.getActionCommand())) {
// Get all component
java.awt.Component[] componentList = this.getComponents();
JTextField txtField;
String value;
for (int i = 0; i < componentList.length; i++) {
if (componentList[i].getClass().getName().equals("javax.swing.JTextField")) {
txtField = (JTextField) componentList[i];
value = textField.getText();
}
}
if (value != null) JOptionPane.showMessageDialog(frame, value);
}
}
});
Upvotes: 2
Reputation: 285405
You're creating a "shadow" ButtonFrame variable inside of the b2's ActionListener. Yes the bf variable refers to a ButtonFrame object which is of the same class as the displayed ButtonFrame object, but it refers to a completely distinct and non-visualized object. The key to a solution is to get the text from the ButtonFrame object that is actually displayed, and this can be obtained from within an inner class via the ButtonFrame.this
construct:
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//!! ButtonFrame bf = new ButtonFrame();
if ("calculate".equals(e.getActionCommand())) {
//!! note use of ButtonFrame.this:
JOptionPane.showMessageDialog(frame, ButtonFrame.this.loanAmt.getText());
}
}
});
Next consider using public getters rather than accessing fields such as the JTextField directly. This reduces the chances of the code causing side effects, such as changing the properties of the JTextField object inadvertently.
For instance (changes denoted by //!! comment):
import java.awt.*;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.awt.event.ActionEvent;
public class ButtonTest {
public static void main(String[] args) {
ButtonFrame frame = new ButtonFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class ButtonFrame extends JFrame {
private JTextField loanAmt; // !! Make field private
@SuppressWarnings("LeakingThisInConstructor")
public ButtonFrame() {
setTitle("SunStream Loan Calculator v2.0");
setSize(900, 900);
ButtonPanel panel = new ButtonPanel();
panel.add(new JLabel("Enter your loan amount:"));
loanAmt = new JTextField(40);
panel.add(loanAmt);
add(panel, BorderLayout.CENTER);
}
// !! create a public method to get JTextField's text
// !! without exposing the JTextField itself.
public String getLoanAmtText() {
return loanAmt.getText();
}
class ButtonPanel extends JPanel implements ActionListener {
private Component frame;
public ButtonPanel() {
final JButton b2 = new JButton("Calculate");
add(b2, BorderLayout.SOUTH);
b2.setActionCommand("calculate");
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// !! ButtonFrame bf = new ButtonFrame();
if ("calculate".equals(e.getActionCommand())) {
//!! call public method on ButtonFrame object
JOptionPane.showMessageDialog(frame,
ButtonFrame.this.getLoanAmtText());
}
}
});
}
@Override
public void actionPerformed(ActionEvent ae) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
Upvotes: 8