Is there a way to disable all buttons with a method? - java

This is a lab for school that I'm struggling with, the code is making a game of hangman, and when the "brain" program says the game is over, all of the letter buttons are supposed to be disabled.
relevant code sections:
the buttons:
class ActionButton extends JButton implements ActionListener{
private String name;
private char t;
public ActionButton(String s){
super(s);
name = s;
t = name.charAt(0);
}
#Override
public void actionPerformed(ActionEvent e) {
ido.newLetter(t);
this.setEnabled(false);
LovesMePanel.this.update();
}
}
the update method:
public void update(){
answers = ido.getAnswer();
flower.setTriesLeft(ido.getTriesLeft());
progress.setText(answers);
if(ido.gameOver()){
// This is where I need to deactivate the buttons
if(ido.hasWon()){
}
}
else if(triesLeft == 0){
}
}
the buttons are all created in a loop in the LoveMePanel that holds all of the other panels. Is there a way to reference them all or disable them all when the game is over?
If not, how should I change my code so that it would be possible to do that?

If you put your buttons in a Collection, you can iterate through them and disable them all that way. I.e.,
for (JButton b : myButtons) {
b.setEnabled(false)
}
If not, you have 26 disable statements to write.

See the setEnabled() method for JButton. You can:
Add your Buttons to an ArrayList while creating them and then iterate over it and disable one by one
Get children of a JPanel, iterate over them, check if it's a button and disable it
Put a Glass Pane on top of your Burrons to intercept the incoming events
Feel free to choose the one you like best.

how about getting the children of the root panel by calling getComponents and iterating over them recursively and finding JButtons and disabling them as you find them?

Related

Is it possible to create a custom version of jbutton to restrict access to certain methods?

Is it possible to create a custom version of a swing component, say jbutton, that restricts access to certain methods of jbutton?
I want to have a jbutton (or various swing elements) where I define certain elements that can't be changed and certain that can. Using jbutton as an example, I'd like to allow a user of the class to add a text, or image to the button, set it enabled or disabled or set the size etc, but I want to define the look of the button and not have that modified.
If I extend jbutton using my custom class, I can only override each method I don't want modified with an unsupported exception. If I extend J component, I will have to rewrite basically all of jbutton. Is there a better way?
I'm asking because we are making a set of custom J components that clients can use to build hmi screens. We want to limit elements based on our look and feel and hmi standards.
You can extend a JPanel or wrap your button (or even both of them).
First variant
public class MyButton extends JPanel {
private JButton button = new JButton();
public MyButton() {
init();
}
// probably some another constructors.
private void init() {
setLayout(new GridLayout()); // button take the entire place of the panel
add(button);
}
public void setText(String text) {
button.setText(text);
}
}
Second variant:
public class MyButton {
private JButton button = new JButton();
public MyButton() {
}
// probably some another constructors.
public JComponent getComponent() {
return button;
}
public void setText(String text) {
button.setText(text);
}
}
Both of these variants allow you to hide the restricted functionality without to reimplement JButton or throw exceptions in overriden methods. You can also combine these two variants or each of these variants with throwing exception for restricted methods (it could be interesting, because some experienced developers can access JButton object, by casting to JButton the result of the method getComponent()).

JComboBox get item

I have a quick question. I don't get it...
I've got a JFrame where I add a JComboBox:
JComboBox<String> Team_ComboBox = new JComboBox<>();
Team_ComboBox_Handler ComboBox_Listener = new Team_ComboBox_Handler();
Team_ComboBox.addActionListener(ComboBox_Listener);
Team_ComboBox.addItem("Test 1");
Team_ComboBox.addItem("Test 2");
On this Frame I have a button which opens another JFrame.
Play = new JButton();
Play.setText("Play");
Play.setPreferredSize(dimension);
Play.addActionListener(menuhandler);
private class main_menuhandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==Play){
teams Team = new teams();
Team.teams();
disposeMainMenue();
}
if(e.getSource()==Close) {
System.exit(DO_NOTHING_ON_CLOSE);
}
}
}
Anyway, I would like to transfer the Selected value of the Combobox to a method of the other class. I know how I can get the itemvalue of the combobox in the method itself (with getselecteditem) But how can I do that in the ActionPerformed Method as I can't access the combobox in the ActionPerformed method.... I created another ActionListener (comboBox_Listener) but I haven't put any code into it...
Any idea? Thanks a lot in advance
Several issues appear to me:
Your main question:
But how can I do that in the ActionPerformed Method as I can't access the combobox in the ActionPerformed method
Your likely best solution is to change your code and variable declaration placement so that you can access the JComboBox fromt he actionPerformed method. If you're declaring the combobox from within a method or constructor, change this so that it is a proper instance field of the class.
Other problems:
You should not be creating multiple JFrames. If you need a dependent window, then one should be a JDialog. If not, then consider swapping views with a CardLayout.
Learn and follow Java naming conventnions so others can better understand your code. Class names begin with capital letters and methods and variable names don't for instance.
I am not sure why you're doing this: System.exit(DO_NOTHING_ON_CLOSE);. Why pass that constant into the exit method?
Use a constructor for your action listener class:
private class main_menuhandler implements ActionListener {
private JComboBox<String> Team_ComboBox;
public main_menuhandler(JComboBox<String> Team_ComboBox){
this.Team_ComboBox = Team_ComboBox;
}
}
Now you can create the class main_menuhandlervia the constructor and add the combobox to it.
In your Overriden action you have access to it.
Try playing around with this as your code snippet isn't broad enough to actually provide proper code. But this should answer your question

ActionListener reset variable's current value to default

I'm working on a project for a simple game where you can go to different rooms by using buttons (north, east, west, south). Within the makeFrame() method of my gui I'm creating the panel, buttons etc. I then set the default room to "hall" for example and the actionlistener calls the method goRoom and passing the direction and currentRoom to that method. The goRoom method change the currentRoom to another room depending on the currentRoom. I included print statements to see if it works and so far it works fine.
Everytime the game starts the default room is the hall.
So when you click a button to go for example "North", the northButton is called in which then we call the goRoom method passing the direction (north) and the default room "hall" (as the game just starts and uses the default room).
Then the room changes from hall to state room (within the method goRoom). When I try to press another button the currentRoom reset to the default value (hall).
I think the action listener get the value from the makeFrame() method instead of the updated value from the goRoom method. The code is below:
public class StoreGUI extends JFrame
{
public String currentRoom;
public StoreGUI()
{
makeFrame();
}
private void makeFrame()
{
currentRoom = "hall";
....
northButton = new JButton("Go North");
northButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
direction = "north";
goRoom(direction, currentRoom); }
});
toolbar.add(northButton);
westButton ....
southButton ....
eastButton ....
picture.setIcon(new ImageIcon("image/hall.png"));
frame.getContentPane().add(picture);
frame.pack();
frame.setVisible(true);
}
private void goRoom(String direction, String currentRoom)
{
// get current room and check which direction button the user has pressed
if (direction == "north"){
if(currentRoom == "hall"){
// Inserts the image icon and change currentRoom
imgageTitle = "image/stateRoom.png";
currentRoom = "stateRoom";
}
....
}
What the problem could be? How can I fix that? I'm pretty sure it's something really simple but I'm stack.
String comparison in Java is done with String#equals not ==. This will compare the actual text of the String and not its memory reference...
For example, instead of
if (direction == "north") {....
Use
if ("north".equals(direction)) {...
If you don't care about the case, you could use...
if ("north".equalsIgnoreCase(direction)) {...
Having said all that, you could actually use a enum to represent the directions, which restricts what values you can actually pass to the goRoom.
You could also use a Action to define each button's actions, which also means you could use them Key Bindings or menus without having to duplicate any code...but that's just me...
Updated
You're also shadowing your values...
private void goRoom(String direction, String currentRoom)
{
//...
currentRoom = "stateRoom";
Changing the value of currentRoom will have no effect beyond the scope of the method. This is because you're not actually changing the content of the String object, but changing it's memory reference.
Instead, either change the name of the parameter or, simply don't bother passing, as you already have access to the instance field of the same name...
private void goRoom(String direction)
{
//...
currentRoom = "stateRoom";

Finding and retrieving a component from its container

In my swing-based UI, I have a JMenuBar which contains a a series of JMenu and JMenuItem objects. One of the menu-item objects also happens to be a JCheckBoxMenuItem.
Now, while the user can click on this JCheckBoxMenuItem in order to toggle the state of an application level setting, the user (in my application) also has access to a command line API to change the application setting. The details of this command line API are not relevant.
My question is this: When the user goes through the command line API and toggles the state of the setting (a static property / setting that applies to all open instances of my application), I would like to update the "checked / unchecked" property on the JCheckBoxMenuItem. To do this, I can either:
Store a reference to the checkboxmenuitem.
Traverse the JMenu container hierarchy to find the checkboxmenuitem.
I don't want to use method 1 because in the future, if I have more of these checkboxmenuitems, then i'll have to hang on to a reference to each one.
Method 2 seems cumbersome because I need to do:
Component[] childComponents = menu.getComponents();
for(Component c:childComponents)
{
if(c.getName().equals("nameOfTheCheckBoxMenuItem"))
{
componentFound = c;
}
}
Is there a better / more efficient way to find a component in a component hierarchy? Is there maybe a better way to solve this problem in general (changing the state of the jcheckboxmenuitem when the value of a property in my application changes), using say, a PropertyChangeListener (Although my understanding is that these only work on "beans").
1) I'd suggest to use CardLayout for nicest and easiest workaround for multi_JPanel application
2) then you can imlements
add Action / ActionListener
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (myCheckBox.isSelected()) {
// something
} else {
// something
}
}
};
add ItemListener
ItemListener itemListener = new ItemListener() {
public void itemStateChanged(ItemEvent itemEvent) {
if (Whatever) {
// something
}
}
};

Keeping tracks of what object triggers a common event

I have a common event handler for a set of submenus, say something like 4 menus, and 4 submenus in each. What I want is to keep track of how many times each submenu is clicked and for that I'm using an integer array as a counter for each submenu(declared with application scope), in the main class. I need to write the values in this array to a file after the GUI exits. How (and more importantly where in the code) do I do this? My array is obviously of size 16 and needs to be initialised to zero(again where do I do this?)
I'm new to Java but I'm guessing I need to do something with this,
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
First, in the class that initializes the menu items, you need to declare an array of integers. Those will be initialized to 0 automatically:
private int[] counters = new int[16];
Then, each time you initialize a menu item, you must add a listener to the item that increments the appropriate counters element:
private class CounterIncrementActionListener implements ActionListener {
private int index;
private CounterIncrementActionListener(int index) {
this.index = index;
}
#Override
public void actionPerformed(ActionEvent e) {
counters[index] = counters[index] + 1;
}
}
...
firstItem.addActionListener(new CounterIncrementActionListener(0));
secondItem.addActionListener(new CounterIncrementActionListener(1));
...
Now, to be able to save the counters array to a file when the frame is closed, you need to add a window listener to the frame:
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
saveCounters();
System.exit(0);
}
}
Pass it in to the event. Many GUIs have an ActionCommand type property that you can tag with whatever string you want. You can use that to pass the information into your event.
Mostly from Oracle - How to Write Window Listeners
You need to use setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE)
you need to add a windowListener
You need to override the windowClosing() method of the windowListener
e.g:
this.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
//Save your Array here
}
});

Categories