Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using final 1-element array for anonymous inner class

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.

like image 902
Darrel Hoffman Avatar asked Oct 23 '13 23:10

Darrel Hoffman


People also ask

Which is true about an anonymous inner class 1 point?

1. Which is true about an anonymous inner class? A. It can extend exactly one class and implement exactly one interface.

How do you declare an anonymous class in Java?

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.

How many objects can an anonymous inner class make?

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.


2 Answers

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).

like image 87
Chill Avatar answered Sep 28 '22 09:09

Chill


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.

like image 33
TheWonderBird Avatar answered Sep 28 '22 09:09

TheWonderBird