0

In essence, I want to have my class Game initializing and interacting with classes with the Player Interface implemented.

Now to the issue: When my Game class calls the method getMove from this GUI (code below), the GUI (me) most certainly won't have decided on it's move yet. The Game class will happily wait for the decision, that's not the problem.

I searched for a possibility to kind of stall the function but I haven't found anything nice for that.

What I sort of need is where the function waits until an action from the JFrame occured or likewise a variable has been set to a right amount. The GUI has to work properly during this waiting time.

I found similiar questions like

Java : Wait for user input on swing window

Java Swing: Waiting for Mouse Clicked event before returning an Int

Swing GUI doesn't wait for user input

but I was either not satisfied with the answer or couldn't extract the for me valuable information because the answer was very specific as was the asker. I'm trying to understand as much as I can about Java and OOP but I'm quietly said, still a newbie.

public class GUI extends javax.swing.JFrame implements Player{
    /**
     * Creates new form GUI
     */
    public GUI() {
        initComponents();
    }


    private void initComponents() {...} //not relevant

    // Variables declaration - do not modify   - not relevant either                  
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jErrorLabel;
    private javax.swing.JTable jTable1;
    // End of variables declaration                   

    @Override
    public int getMove() {
        throw new UnsupportedOperationException("Not supported yet."); 
    }
}

EDIT: I want to know how Java handles interfaces with non-java applications, so I imagine a language barrier between the player and the Game which only has the Player as interface, so to say.

I know that his implicates unusual and inefficient code because there is effectively no language barrier. The knowledge is more important than the product for me here.

Mike
  • 1
  • 2
  • traditionally, if you want to wait on an event from another thread, use can use wait and notify. Left me know if this other answer solves your problem? https://stackoverflow.com/questions/886722/how-to-use-wait-and-notify-in-java-without-illegalmonitorstateexception – ControlAltDel Oct 11 '18 at 15:36
  • 1
    A GUI spends most of its life waiting. I think what you are missing is that you work in an event framework. So the GUI is there, then an action occurs on the screen (e.g., a button press), that generates an event, you process the event, and then return. The GUI will still be there until the program exits. You can do things like button press->change mouse cursor->show result->make decision->change mouse cursor. You don't want to methods that "wait" -- the event framework handles the dispatching. In short, you don't call `getMove()`, but allow the GUI to pass an event that invokes a `move`. – KevinO Oct 11 '18 at 15:38
  • @KevinO I use Java User Interfaces for like 4 years but I have just come to understand the basics of it and things like event framework are new to me. But I'm kind of firm on the decision that the GUI is "just a player" and can be called as such from the main class that handles the game. – Mike Oct 11 '18 at 15:43
  • Mike... a few things to know about Swing. It is event based. Its non-blocking. If a user clicks a button or a key, and event is sent and you create a handler. All UI on Swing happens on its own thread. And its super important to decouple your game code from the UI thread (the end result is that the UI won't update/respond properly if you don't). Swing has a function called invokeLater. You might want to build your event handlers to call this to drive your game code. https://www.javamex.com/tutorials/threads/swing_ui.shtml https://www.javamex.com/tutorials/threads/invokelater.shtml – Micromuncher Oct 11 '18 at 15:45
  • @Micromuncher I thought the same way about many things you said. Your link looks very promising and was an initial solution approach of mine, but it's complete new land for me and will probably take considerable time to fully understand and use. – Mike Oct 11 '18 at 15:58
  • 1
    When you implements any class, it represent an is-a relationship. So as per your design a Frame is a player that doesn't seems correct. I feel that you need to rethink about your design and read about how to use swing framework efficiently. – Shahid Oct 11 '18 at 16:00
  • @Shahid My frame is a human interface and counts as player in my design. I'm not discussing that at the moment. – Mike Oct 11 '18 at 16:10
  • Swing is just a UI library. Your statement about "if Swing can't provide" doesn't make sense, since it just like any UI can provide as long as you code it to provide. The issue here is not with the library but with understanding of how to code event-driven and state-dependent programs, nothing more, nothing less. – Hovercraft Full Of Eels Oct 11 '18 at 16:12
  • @HovercraftFullOfEels I edited it out before I read your comment, I'm used to reread my answers a couple of minutes after I posted them . You might have called my out there. And yes I agree with what you call the issue. – Mike Oct 11 '18 at 16:14
  • Now I see that [one of the questions linked to in your question above](https://stackoverflow.com/a/10167801/522444) was answered by me and in a similar fashion. I will make my answer a community wiki and close this as a duplicate, because yes, it truly is a duplicate. – Hovercraft Full Of Eels Oct 11 '18 at 16:15
  • The answers all already answer this for you, and I'm not sure what confusion you still have. – Hovercraft Full Of Eels Oct 11 '18 at 16:16
  • @HovercraftFullOfEels The "how-to" is completely missing for me. I stated that I'm still a newbie in this regard and without code examples or any direct references I have nothing practically to work with. I'm looking into programming with threads with Micromuncher's advise hoping to find a solution within there. – Mike Oct 11 '18 at 16:25
  • @Mike: The how-to is addressed in the duplicates, and I suggest that you study them again. If still stuck, then please be as specific as possible about what you don't understand in the duplicates, and post your [mcve] code (please check the link) that would allow us to experience your confusion for ourselves. Again, in your situation, your GUI would call it's method when its state has been changed to one where the method is needed, and again, that usually means a change in a key field somewhere (here the GUI's model, most likely). – Hovercraft Full Of Eels Oct 11 '18 at 16:37

1 Answers1

1

There are two key concepts to know and understand in this situation (there are more, but let's stick with the two most important):

  1. event-driven programming and
  2. (what I think is missing in your concepts) state machine

How the GUI responds to events will depend critically on the program's state, usually depending on the values held by key fields, and this is how you usually "wait for input". So for instance if you're coding a card game, and the user presses a button to get another card, but it's not his turn, the GUI will know whose turn it is (the key state here) and respond to the user an error message and not a card, because the "give-me-a-card" button was pressed at the wrong time (when the GUI was in the wrong state).

So the GUI is never put to sleep waiting for input, but rather changes state as the program progresses. If the userTurn field is set to be the user's and he presses the "give-me-a-card" button, the game gives a card, and then changes its state to the next player's turn (if this is what the program logic says it should do).

Note that these concepts are not Swing specific and would work the same with pretty much any GUI library


Also note that this logic is in error:

When my Game class calls the method getMove from this GUI (code below)

No, the Game shouldn't in fact even call getMove(), but rather

  • The Game should notify the player and the GUI that it is OK for them to move, that there current turn state is for this current player
  • The user then makes his move -- interacts with the GUI's components in a way that represents a move
  • The GUI (the view) notifies the control that this move is being made
  • The control then tells the model that the player is requesting to make a move. The model can reply back that the move is valid or not,
  • The model can then change its state accordingly: the same player's turn if the move was invalid, or if the move was valid, change the player's state within the model, and change the turn field/state to point to the next player (or to the computer AI if its the computer's turn).
  • The program must allow for two-way communication between the model and the view.
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • I feel like there is a misunderstanding with my concept. Should I post all my classes and interfaces for reference? The GUI receives all it's information about the _state_ of the game from another class called _Game_. For a start I firmly intend that this class _Game_ also calls for all the necessary variables during the game, including the moves of the players. I don't want the players to call _the Game_ that they made their move, which might be easy to implement, but not what I am looking for. – Mike Oct 11 '18 at 16:51
  • @Mike: `"Should I post all of my..."` -- no. Again if you are still confused, you should create and post a [mcve] (please read the link), a new small program that compiles, and runs and serves to illustrate your problem. I promise you that if you create and post a valid one, one that clearly shows us your problem, I will re-open this question. – Hovercraft Full Of Eels Oct 11 '18 at 16:56
  • @Mike: Your program set up looks to be a M-V-C or something close to that. You will need to allow listeners to be added to the model, to listen to and respond to changes in its state, such as by giving the model SwingPropertyChangeSupport and allowing addition of PropertyChangeListeners to this class. The key concept for this is one of use of *call-backs*. – Hovercraft Full Of Eels Oct 11 '18 at 16:57
  • I usually don't know the names of what I'm doing, but I have a class that entirely _controls_ the game, and a class that acts as a player. If the player is defined to be human, it is a human interface, so it serves as _view_. I will try to look into the keywords you noted. Will it be ok to eventually follow up on this in a few days? – Mike Oct 11 '18 at 17:10
  • @Mike: I don't see why not – Hovercraft Full Of Eels Oct 11 '18 at 17:14
  • @Mike: see update for a logical error in your question. The model does not call `getMove()` as that has it all backwards. You need to allow communication in both directions. – Hovercraft Full Of Eels Oct 11 '18 at 17:51
  • Do you mean with "having it all backwards" that it's impossible to do it that way? – Mike Oct 24 '18 at 11:23
  • Is there a reason you can't return to the eventQueue during a method execution, or return to method execution as an event. As the goTo topic in java, I see that it's highly discouraged and why, but you still have options to jump in code. So is there any solution or alternative to my question without changing the design? – Mike Oct 24 '18 at 11:30
  • Swing architecture is based on event response, a *listener* model. What you're suggesting sounds like state polling, and while this can be done requires use of a busy loop and is very inefficient and wasteful of time and resources. – Hovercraft Full Of Eels Oct 24 '18 at 20:25
  • Indeed it is and it might be exactly the answer I am looking for. Can you tell me how to create a busy loop in swing? – Mike Dec 10 '18 at 14:18