Domanda

I'm making a level editor for my java game using Java swing.

One of the features is that there is a a togglable button to turn the game on and off to test the level out. The game runs inside a jpanel, then you click the button again to untoggle it, and it turns the game off.

I only want the user to be able to change stuff or push buttons in the swing application when the game is NOT running, when it is running I set the focus to the game component. The only button in the swing application that they should be able push is the toggle button to turn the game back off.

The problem is, I can't think of a good way to do this. Using a recursive function I could easily loop through and find all components and do setEnabled(false), but when the game is turned back off it has no way to know what the previous enabled state was (along other issues, like other components responding to setEnabled being called on other components)

What I think I really need is just some kind of way to just outright "kill" user input into the swing application when the game is running.. But preferablly with a way to click the toggle button again to return the application's state, and the game which is running inside a Jpanel needs to be able to have focus...

Is there any way to do this sort of thing at all without massive amounts of "organizational" code to manage the components in the swing application?

È stato utile?

Soluzione 3

Another option is to use a GlassPane and "grey out" an area of components. You would also have to capture and ignore clicks in the pane for the area you don't want a users clicking.

See more with an example in the Java Tutorial here: http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html

This write up could also be helpful: https://weblogs.java.net/blog/alexfromsun/archive/2006/09/a_wellbehaved_g.html

Altri suggerimenti

You can place everything in a map, like this.

class ComponentState { 
 private JComponent component;
 private bool on;
 // Getters & Setters
}

private Map<String, ComponentState> components = new HashMap<>();

in order to add a new component to your game:

components.add("startbutton", new ComponentState(new JButton, true));

then to add all components to your screen:

for(String key : components.KeySet()) {
 ComponentState comp = components.get(key);
 if(comp.isOn()) { this.add(comp.getComponent()) };
}

and to disable/activate a component:

components.get("myActivatedComponent").disable(); // disable is a self defined method

You want a disableAll() method that sets every component to a disabled state, and a resetAll() method that will reset every component state back to its previous state. You need to save the status of every component when you disable it, in order to be able to restore it after. That will take O(n) space.

private final Map<JComponent, Boolean> components = new HashMap<JComponent, Boolean>();

public void disableAll(JComponent root) {
    components.put(root, root.isEnabled());
    root.setEnabled(false);

    for (int i=0, n=root.getComponentCount(); i<n; i++) {
        JComponent child = (JComponent) root.getComponentAt(i);
        disableAll(child);
    }
}

public void resetAll(JComponent root) {
    boolean status = components.get(root);
    root.setEnabled(status);

    for (int i=0, n=root.getComponentCount(); i<n; i++) {
        JComponent child = (JComponent) root.getComponentAt(i);
        resetAll(child);
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top