How can I block JDialogs from appearing until a previous JDialog is closed?

38 Views Asked by At

I'm making a game in Java Swing and my level-up menu is a JDialog. On rare occasions it's possible for the player to level up twice in a short period of time, leading to level n's then level n+1's dialog to open but they will be in the wrong order.

How can I ensure this doesn't happen?

Edit:
I posted this a little too eagerly when running into this issue as I found a solution on my own. I guess I might as well explain what I did should others run into this problem.

My code is a bit convoluted and all over the place, but here's a the jist of it:

class Logic implements ActionListener {
    
    private JDialog dialog;

    public void logic(){
    //...
        while( someCondition ){
            if ( playerLevelUpCondition() ){
                player.increaseCurrentLevel();
                displayLevelUpDialog();
            }
        }
    //...
    }

    public void displayLevelUpDialog(){
        dialog = LevelUpDialogFactory.makeLevelUpDialog( player.getCurrentLevel() );
    }

    //...

    public void actionPerformed (ActionEvent e) {
        switch (e.getActionCommand()){
            case "optionChosen" -> {
                dialog.dispose();
            }
        }
    }


}

class LevelUpDialogFactory{
    // return a non-modal JDialog that has a JButton that Logic handles
}

The problem arose when playerLevelUpCondition() was fulfilled multiple times during the loop as even if I stopped my Timers calling the loops, I had no way to stop a loop that was already executing (without some significant rewrites). So instead here's what I did:

//added 2 booleans
class Logic implements ActionListener {
    
    private JDialog dialog;
    private boolean canNewDialogBeShown = true;
    private boolean doesLevelUpNeedDisplaying = false;

    public void logic(){
    //...
        while( someCondition ){
            if ( playerLevelUpCondition() ){
                player.increaseCurrentLevel();
                displayLevelUpDialog();
            }
        }
    //...
    }

    public void displayLevelUpDialog(){
        if ( canNewDialogBeShown ){
        canNewDialogBeShown = false;
        dialog = LevelUpDialogFactory.makeLevelUpDialog( player.getCurrentLevel() );
         } else { 
            doesLevelUpNeedDisplaying = true;
         }
    }

    //...

    public void actionPerformed (ActionEvent e) {
        switch (e.getActionCommand()){
            case "optionChosen" -> {
                dialog.dispose();
                canNewDialogBeShown = true;
                if ( levelUpNeedsDisplaying ){
                    displayLevelUpDialog();
                }
            }
        }
    }


}

class LevelUpDialogFactory{
    // return a non-modal JDialog that has a JButton that Logic handles
}

Best solution is probably using a modal JDialog, which I should have been using from the get-go, and I probably just ended up re-implementing logic that it already would have.

0

There are 0 best solutions below