I stumbled across this trick for getting a value from an anonymous inner class to a variable which is declared in the outer class. It works, but it feels like a dirty hack:
private int showDialog()
{
final int[] myValue = new int[1];
JPanel panel = new JPanel();
final JDialog dialog = new JDialog(mainWindow, "Hit the button", true);
dialog.setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE );
JButton button = new JButton("Hit me!");
button.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
myValue[0] = 42;
dialog.setVisible(false);
}
});
panel.add(button);
dialog.add(panel);
dialog.pack();
dialog.setVisible(true);
return myValue[0];
}
(Yes, I realize this example could be replaced with a simple JOptionPane
, but my actual dialogs are much more complicated.) The inner function insists that all variables it interacts with be final
, but I can't declare the myValue
as final because the inner function needs to assign it a value. Declaring it as a 1-element array gets around this problem, but seems like it might be a Bad ThingTM somehow. I'm wondering if a.) this is common practice or b.) there's any serious problems that could result from doing this.
1. Which is true about an anonymous inner class? A. It can extend exactly one class and implement exactly one interface.
Object = new Example() { public void display() { System. out. println("Anonymous class overrides the method display()."); } }; Here, an object of the anonymous class is created dynamically when we need to override the display() method.
We cannot create more than one object of the anonymous inner class in Java. Since an anonymous inner class has no name. Therefore, we cannot declare a constructor for it within the class body.
If the code is legible, which it is, I wouldn't say doing it that way is terrible.
An alternative is to have the JButton call a function in the class that has showDialog (which is allowed). The function could set an instance variable that will be returned. But that seems less legible to me, so I'd actually prefer your method.
Unless you are making a deeply hierarchical UI framework, sometimes these little hacks are exactly the sort of thing you should do.
If you are concerned, you can do basically the same thing with a private inner class:
private class DialogReturnValue {
public int value;
}
private int showDialog()
{
final DialogReturnValue myValue = new DialogReturnValue();
JPanel panel = new JPanel();
final JDialog dialog = new JDialog(mainWindow, "Hit the button", true);
dialog.setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE );
JButton button = new JButton("Hit me!");
button.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
myValue.value = 42;
dialog.setVisible(false);
}
});
panel.add(button);
dialog.add(panel);
dialog.pack();
dialog.setVisible(true);
return myValue.value;
}
And there's also ActionListeners to look at (which may well be the "right" approach).
Using AtomicInteger or AtomicReference can make it little better. It is actually a common practice, but you can make it cleaner by introducing the actual class that implements ActionListener and provides the value through a getter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With