2

Basically I have got a game with main class.

    public static void main(String[] args) throws InterruptedException {
    JFrame frame = new JFrame("Mini Tennis");
    Game game = new Game();
    frame.add(game);
    frame.setSize(300, 400);
    frame.setResizable(false);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    while (true) {
        game.move();
        game.repaint();
        Thread.sleep(10);
    }
}

When I am loading a class directly it working fine.

enter image description here

But when I am calling it from another class, it does not paint anything.

    private void btnGameActionPerformed(java.awt.event.ActionEvent evt) {                                        
  try {
      String[] args = null;
      Game.main(args);
    } catch (InterruptedException ex) {
        Logger.getLogger(DrawerMain.class.getName()).log(Level.SEVERE, null, ex);
    }

}  

enter image description here

And after a few seconds it paints that I have lost a game. So basically game is running but I can't do anything and I don't see anything.

enter image description here

Antoshjke
  • 462
  • 4
  • 22

4 Answers4

1

You need to move your main code into a Constructor, main should be only on the 1st class or the "main" class you're going to run.

The main method is the entry point for your application to run, you shouldn't be calling it as if it were any other method.

public Game () {
    JFrame frame = new JFrame("Mini Tennis");
    Game game = new Game();
    frame.add(game);
    frame.setSize(300, 400);
    frame.setResizable(false);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    while (true) {
        game.move();
        game.repaint();
        Thread.sleep(10);
    }
}

Then you call it as:

private void btnGameActionPerformed(java.awt.event.ActionEvent evt) {                                        
  try {
      String[] args = null;
      Game game = new Game();
    } catch (InterruptedException ex) {
        Logger.getLogger(DrawerMain.class.getName()).log(Level.SEVERE, null, ex);
    }

}  

You should read more about Constructors and Classes and Objects

Also as mentioned in other answers, Thread.sleep() will cause your application to freeze, you should use a Swing Timer instead to handle it in another thread, so your application won't freeze.

With Thread.sleep() your application will wait the time inside it before repainting it.

Frakcool
  • 10,915
  • 9
  • 50
  • 89
1

The reason for this is that in the 2nd case, where you are calling the main method from an ActionListener, you are running your main method on the UI thread. And since you have your active wait block in this code, the UI is never able to draw anything. You should check out javax.swing.Timer and replace the loop I've copied over below with an implementation that uses Timer

while (true) {
        game.move();
        game.repaint();
        Thread.sleep(10);
    }
ControlAltDel
  • 33,923
  • 10
  • 53
  • 80
0

First, you should not run everything from your main thread. And the main method is not for you to call, it's supposed to be the entry point of your application.

In your main method, do this:

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        createAndShowGUI(); // in this method, you create your frame and other UI components and show them
    }
});

This Runnable will run in the event dispatch thread and will make the UI ready before any actions related to the UI.

Once you have your UI ready, say, you created the frame and linked it to a game. Then use a class which acts like a controller of the frame and the game to listen to events it's interested in and update the UI when it needs to.

If you need to create a window running this game each time when some event happens, then you should define this window as a class. You just need to create an instance of this class and make the window visible. Or if you just need to restart the game, then use a single instance of the class across your application, and only restart the game in it. The controller class is always useful to notify the game to restart and as well as update the UI.

lkq
  • 2,326
  • 1
  • 12
  • 22
0

Asothers have said, you shouldn't call main() yourself. That said, you cannot have a Thread.sleep() in your loop - if it is run on the EventDispatchThread (which it must be) that will block the thread and you will never get repaints. You need to use a SwingWorker to do the looping.

FredK
  • 4,094
  • 1
  • 9
  • 11