Waiting for player to push button JavaFX - java

Hi so I'm making a Simongame and I need to wait for the player to push a series of button (sending integers to a list) and compare it to another list, but I didn't find any wait for event type of function. So how can I make my game loop wait for the player to push a certain number of button before trying to compare it?
start.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Game = 1;
While(Game == 1)
//Game adding random values to a list
//4 Buttons Action event adding values to another list with 4 different values and a button to validate the values put into the list
//HERE I need the loop to wait for buttons to be pushed and validated by another button before trying to compare the two list
//Comparing the two lists , printing a message if they are not the same or returning in the loop and add a new value to the randomly generated list
}
}
});

You don't. I'm serious, JavaFX is built around event handling.
What you're trying to do is poll for data, but you don't need to. You can add a Click event handler using
myButton.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
//TODO all your events and stuff here
}
});
Inside of the handler for the ActionEvent, you can use code to do something. There is another way of handling events for buttons as well, if you want to differentiate between right-clicks and left-clicks, dragging the mouse over or out, etc. This is through the myButton.addEventHandler(EventType.EVENT), myEventHandler);.

Related

Java if two buttons have the same icons increase score and if not display "wrong match"

Creating a really basic Memory game using Java Swing. I created my GUI with a list of blank buttons where I set the icon property to none.
My code for some of the buttons is:
private void tbtnCard3ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card3Logo.png")));
if(tbtnCard5.isSelected()){
score++;
lblScore.setText(""+score);
}
}
private void tbtnCard4ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card7EWaste.png")));
if(tbtnCard7.isSelected()){
score++;
lblScore.setText(""+score);
}
}
private void tbtnCard5ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard5.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card3Logo.png")));
if(tbtnCard3.isSelected()){
score++;
lblScore.setText(""+score);
}
}
I have about 20 toggle buttons and for example the code above works and the scores go up by 1 when a match is found. So for tbtnCard3, if tbtnCard5 is selected the score goes up by 1. Now my question is how would I make it so that if tbtnCard3 is selected but tbtnCard 5 is not selected, display "Wrong Match". Since im using if Selected I'm not too sure how to display "wrong match" when the case is false. It doesn't make sense to say else ifSelected as no parameters can be put either....
In my opinion, the OPs suggestion is not a good approach. You do not want the listener of one button to be "aware" of some other component unnecessarily. Suppose you have an 8-by-8 grid with toggle buttons. You don't want each toggle button listener to be aware of the other 63 toggle buttons.
I believe there is a much simpler (and cleaner) approach. What you want is for the toggle button listener to register and deregister the toggle when the state of the button changes. Let say, you add the toggle button to or remove from a list (most likely a custom class) where you can trigger some logic when the list size reaches two. Then, depending on the outcome of the comparison, it will count a match (and disable these two toggle buttons in the current state), or will display some message like "Try again" and then toggle the buttons to hide the image.
In pseudocode, this will look something like this:
public class ToggleListener implements ItemListener {
public void actionPerformed (ItemEvent event) {
JToggleButton button = (JToggleButton) event.getSource();
if (event.getStateChange()==ItemEvent.SELECTED) {
// TODO Add the button to your list..
} else {
// remove button
}
}
}
In your Swing application, you can create a single instance of the above listener and add it to every single toggle button. And, as you can see, this listener is only responsible to register and unregister the component associated with the triggered event.
The "List Listener" on the other hand, is responsible to trigger the comparison logic when the size of the list reaches two. So, if you click on the same toggle button over and over again, the only thing the button listener will do is add or remove the button from the list depending on the button's current state. However, once a second button is toggled to reveal its image, the list listener will trigger the comparison logic. I am not 100% sure, but I think you could use JavaFX ObservableList interface or one of its implementing classes to do this. If the ListChangeListener.Change class is not suitable to figure out the size of the list to trigger the logic, you will have to implement this on your own. Regardless, in pseudocode, you need to do something like this:
public void onListChange(Event event) {
if (list.size() == 2 && btn1.getIconName().equals(btn2.getIconName())) {
displayMatchMessage();
btn1.setEnabled(false);
btn2.setEnabled(false);
list.clear(); // you should remove matched items from list manually
} else {
displayMismatchMessage();
btn1.setSelected(false); // flip the card
btn2.setSelected(false); // flip the card
// list.clear(); // you should not need this because the setSelected should trigger the Item Listener which should remove item from list.
}
}
Doing something like this is a much cleaner implementation where the button listener have a single job to do and the "list listener" has another job to do. Neither one encroaches on the other's job.

JLabel keeps speeding up on each List Selection

list.getSelectionModel().addListSelectionListener(e -> {
timer = new Timer( DELAY, new ActionListener()
{
#Override
public void actionPerformed(ActionEvent arg0) {
StockItem p = list.getSelectedValue();
label.setText(p.toString2());
label.setLocation(label.getLocation().x+1, label.getLocation().y);
if(label.getLocation().x >= frame.getWidth()) {
label.setLocation(0-label.getWidth(),label.getLocation().y);
}
}
});
timer.start();
});
I created a list selection listener to check which current items are being selected inside of a JList, and whatever item is being selected will call a toString() method in another class and set this as the text for a JLabel. However, I just implemented moving text on my JLabel and every time an item in the JList is selected, the speed of the JLabel will increase. I would like it so the speed stays constant but i'm not sure how to do that.
The part of the code that controls the speed is
label.setLocation(label.getLocation().x+1, label.getLocation().y);
Any explanations would be very appreciated thank you
every time an item in the JList is selected, the speed of the JLabel will increase.
Because your code starts another Timer with each selection.
A Timer will keep running until you stop it. Since you never stop it you will have multiple Timers running at the same time.
You want to define your Timer outside of the ListSelectionListener.
Then the logic inside the listener becomes something like:
(if !timer.isRunning())
timer.start();
Or the question is do you even need the ListSelectionListener?
You could just start the Timer automatically when you class is created. Each time it fires the logic will get the selected value.
Of course with this approach you need to make sure the getSelectedValue() method doesn't return null (as no item will be selected when the GUI is first displayed).

java Create different event from within an event handler [duplicate]

This question already has an answer here:
How would I programmatically click a button in JavaFX from another method?
(1 answer)
Closed 5 years ago.
I have a data entry form with 3 buttons: "Save/Next", "Clear" and "Exit". I want the Save/Next button to perform its own function, then finish by setting the focus to the Clear button and causing it to execute, reset all the text fields to be ready for the next set of data. I was hoping to avoid copying all the clearing code lines into the event handler for the Save button.
Is there an easy way to programmatically create the event that the Clear button eventHandler recognizes (ENTER key in this case), thus executing without user input?
btnClear.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
barcodeText1.clear();
barcodeText2.clear();
//
// more clearing statements here...
//
statusContent.setText(stStatusTextScan1);
barcodeText1.requestFocus(); //return focus to first field
}// end handle
});//end btnClear
// Save Button Event Handler ..............................................
btnSave.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
//
// Do some Saving stuff...
//
// Record saved. Now reset the form for the next record...
btnClear.requestFocus();
// Put something here that will mimick pressing ENTER key...
Event e = new Event(<KeyEvent>);
}// end handle
});// end btnSave
Berger: Good find. btnClear.fire() in your link worked like a charm for me. There is an art to finding the best search term combinations which I have not yet mastered. Thanks.

how to identify a button in a group of loop generated buttons?

I have a group of loop generated buttons made with this code
this.panelCuerpo.setLayout(new GridLayout(4,5));
for(int i = 1; i<=20; i++){
final JToggleButton b = new JToggleButton(new ImageIcon("/images/available.png"));
panelCuerpo.add(b);
b.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/available1.png")));
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt){
if(b.isSelected()){
b.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/busy1.png")));
cantidadBoletas++;
}else{
b.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/available1.png")));
cantidadBoletas--;
}
System.out.println(cantidadBoletas);
}
});
}
The problem here is that I can't use setText() to compare later cause there's no property to hide that text. How can I compare it later?
PS. Each button has a consecutive number, it's easy to assign that number. The real problem lies in where to put it.
You could:
Use the Action API, which lets you trigger the selected state of the associated button. This allows you to de-couple the button from the underlying "action" it should take. Take a look at How to Use ActionsHow to Use Actions for more details
Use the actionCommand property of the JButton. This allows you to have some kind of "identifier" associated with the button which is independent of the text
Use an array or List to maintain a reference to the buttons
You can maintain a List<JToggleButton> of JToggleButton and fetch element later by the index. Apart from that instead of adding ActionListener in loop you can implement ActionListener which can be used for all buttons and you just need to write b.addActionListener(this); in loop.
NOTE : better to start from i = 0 instead of 1

How to control a loop using a button?

I am a beginner in java, I want to know is there any possible way to control a loop by clicking a button? I am creating a GUI, and it's supposed to run 10 times in the loop. Is there a way that I could have a button on the screen so that when the user presses, then it goes to the next iteration? Because currently everything just runs and executes once.
In your java class, you should define an attribute and each time you click on the button you add 1 to this attribute and do the action.
define an attribute in your class;
public int i = 0;
and create a button to be clicked on:
private void clickMeButtonActionPerformed(java.awt.event.ActionEvent evt) {
// code your action here:
this.i++;
}
You could have the loop wait for the button click, and then once it loops 10 times break the loop.
You can use javaFX it's gonna replace javaswing very soon anyways plus it's cooler.
import javafx.scene.control.button
Button button = new Button("control");
int i = 0;
button.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
i++;
label.setText("i increased");
}
});

Categories

Resources