2

I'm trying to make a frame with a panel consisting of two buttons which reside at the bottom of the frame.

public class ControlledBall extends JPanel {

    public static void main(String[] args) {
        JFrame Frame = new Viewer();

        Frame.setSize(1000, 500);
        Frame.setTitle("Bouncing Ball");
        Frame.setDefaultCloseOperation((JFrame.EXIT_ON_CLOSE));
        Frame.setVisible(true);
    }

    public class Viewer extends JFrame {

        JButton buttonGo = new JButton("GO");
        JButton buttonStop = new JButton("STOP");
        JPanel aPanel = new JPanel();

        public Viewer() {
            aPanel.add(buttonGo);
            aPanel.add(buttonStop);
            this.add(aPanel, BorderLayout.SOUTH);
        }
    }
}

The problem here is this:

JFrame Frame = new Viewer();

It is telling me

ControlledBall.this cannot be referenced from a static context

How do I fix it?

Tanmay Patil
  • 6,882
  • 2
  • 25
  • 45
  • You really shouldn't start variable names with capital letters, it's confusing to read and it can confuse the compiler too. – Harry Blargle Apr 21 '14 at 21:37
  • 1
    @HarryBlargle I'm OK that it's confusing to read, but I hope there's no Java compiler out there that is confused with that ^^ – xav Apr 21 '14 at 21:38
  • @xav It could think you are using java.awt.Frame in a static context – Harry Blargle Apr 21 '14 at 21:40
  • @HarryBlargle +1, didn't notice that :) The IDE might indeed auto-import AWT classes (though the compiler will not be confused) – xav Apr 21 '14 at 21:42
  • possible duplicate of [non-static variable cannot be referenced from a static context](http://stackoverflow.com/questions/2559527/non-static-variable-cannot-be-referenced-from-a-static-context) –  Apr 21 '14 at 21:42

5 Answers5

0

You could do something like:

JFrame Frame = new ControlledBall().new Viewer();

instead of:

JFrame Frame = new Viewer();

But I'm not sure this is really what you want since ControlledBall is a JPanel...

xav
  • 5,452
  • 7
  • 48
  • 57
0

Instances of non static inner classes hold a pointer to their enclosing object to be able to reference its members. See for example Java inner class and static nested class One side effect is that they cannot be instatiated from static methods, which have no relation to an actual instance of the enclosing class except by instatiating an intermediate object of your ControlledBall class.

PS: Another side effect to keep in mind (not so relevant for your use case) of this implicit this pointer is that it may cause resource leaks because it keeps the outer instance alive as long as the inner one lives.

Community
  • 1
  • 1
Drunix
  • 3,313
  • 8
  • 28
  • 50
0

You've created an public inner class inside the ControlledBall class, which is why you can't access it, as you don't have an instance of the ControlledBall class.

Guessing from the indentation and your code though, what you probably meant to do was create two seperate classes and instantiate the Viewer class from the main method of ControlledBall. To do that, move the Viewer class to its own file named Viewer.java and it should work.

jedyobidan
  • 876
  • 1
  • 8
  • 14
0

The "main" method is static and when executed, its "containing" class might not yet been instantiated and so class Viewer might not yet exist. Since this example is apparently the program's entry point, "Viewer" most certainly does not yet exist.

There are many ways to resolve this, such as creating an instance of ControlledBall and then use that instance to create "Viewer".

It is my personal style to "get out of static" ASAP in a Java program by instantiating an instance of "main"s container and then running from there. I was taught that "main" is static so it exists to be called by the parent system and not much more use than that, I'm sure there are other opinions. Here is a brief example, which lacks many details:

public static void main(String[] args) {
    // Pass 'args' to which ever method you prefer
    ControlledBall app = new ControlledBall(args);
    app.run(args);
}

private void run(String[] args) {
    JFrame Frame = new Viewer();
}

I use 'run' because of Thread. I know many darts can be thrown at this, its just an example.

user3481644
  • 398
  • 2
  • 12
-1

Make the inner class (Viewer) static public static class Viewer extends JFrame you can not acces non-static things from static methods

Selim
  • 1,064
  • 11
  • 23