1

I have a JFrame, one of the buttons has to pass the frame it self as a parent, i would have used the this keyword, but it's returning the actionlistener, instead of the JFrame. Is there a workaround or am I writing badly?

The code:

start.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
            kMeans=new KMeans(mainWindow.table, Integer.parseInt(centroids.getText()),this);
        }
    });
Roman C
  • 49,761
  • 33
  • 66
  • 176
MustSeeMelons
  • 737
  • 1
  • 10
  • 24
  • What is your class name that contain that code? – Iswanto San Mar 11 '13 at 16:34
  • Else you could do `JFrame that = this` and then pass `that` instead of `this`. – 11684 Mar 11 '13 at 16:35
  • @11684: that would have to be a `final JFrame that = this`; while that works, it clutters your scope, and it's simpler just to do `ClassName.this` – wchargin Mar 11 '13 at 17:15
  • Forgot to try that, thanks, solved everything ;) – MustSeeMelons Mar 11 '13 at 17:15
  • @WChargin Of course you are right, but I remember I once couldn't get `ClassName.this` to work (probably because I messed up), so I just wanted to supply the OP with an alternative. – 11684 Mar 11 '13 at 17:22
  • One of the cases when you can't use `ClassName.this` is when you have an unnamed parent class. Imagine that your code is not inside `AFrame`, but inside another unnamed parent class (just like your listener). In this case, you have to use `that` approach suggested by WChargin. – ATrubka Mar 11 '13 at 18:09

5 Answers5

2

Because this code:

new ActionListener()
{
    public void actionPerformed(ActionEvent e)
    {
        kMeans=new KMeans(mainWindow.table, Integer.parseInt(centroids.getText()),this);
    }
}

has actually created a new object. When you use keyword this in a method of this ActionListener implementation it literally uses this object, which is an ActionListener.

If you use this outside the above block, it will refer to JFrame instance.

If you want to refer to this instance of AFrame inside ActionListener you can do AFrame.this as mentioned in comments. Where AFrame is the name of your frame class, not sure which name you have in your code.

ATrubka
  • 3,982
  • 5
  • 33
  • 52
2

There is a workaround. To use the this keyword in reference to an outer class, you can use ClassName.this. For example:

class MyFrame extends JFrame {
    public void someMethod () {
        someButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                ActionListener thisListener = this; // obviously
                MyFrame outerThis = MyFrame.this; // here's the trick
            }
        });
    }
}
wchargin
  • 15,589
  • 12
  • 71
  • 110
1

You are trying to pass the reference of outer class to anonymous inner class. To do so you should use OuterClassName.this. See the example given below.

import javax.swing.*;
import java.awt.event.*;
class FrameExample extends JFrame
{
    private void createAndShowGUI()
    {
        JButton button = new JButton("Click");
        getContentPane().add(button);
        button.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent evt)
            {
                JOptionPane.showMessageDialog(FrameExample.this,"This is the message","Message",JOptionPane.OK_OPTION);//Passing the reference of outer class object using FrameExample.this
            }
        });
        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater( new Runnable()
        {
            @Override
            public void run()
            {
                FrameExample fe = new FrameExample();
                fe.createAndShowGUI();
            }
        });
    }
}
Vishal K
  • 12,976
  • 2
  • 27
  • 38
0

You should use JFrameClassName.this. So if the name of the JFrame is MainWindow, your code would be:

new ActionListener()
{
    public void actionPerformed(ActionEvent e)
    {
        kMeans=new KMeans(mainWindow.table, Integer.parseInt(centroids.getText()), MainWindow.this);
    }
}
ugo
  • 2,705
  • 2
  • 30
  • 34
0

Use the getSource() method in the ActionEvent to acces the object where the event occured. Example : JMenuItem menuItem = (JMenuItem) e.getSource();

javadev
  • 1,639
  • 2
  • 17
  • 35