How to create MouseClick event to detect which node is clicked? - javafx - java

I want to do global MouseClick event to detect which node is clicked in JavaFX. I mean when someone will click a button then event.getSource will return me reference to this button.
Any ideas, how can i do this?

One way to go about this would be to have a static variable somewhere that was of type Node, and then in the listener of the button, just assign a reference to the button in the handler to that button. ex:
public Class test {
public static Node whichClick;
myButton.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent e){
whichClick = myButton;
}
});
}
And then you could access that variable from wherever.

Related

Waiting for a click input after a button press Java Fx

Im having some issues trying to wait for an input after clicking a button.
With my team, we are making a card game, in which cards attack one another, the problem is that i don't know how to, after a button is clicked, make the event handler wait for the user to click another button.
The code looks like this:
private Button attackingButton(){
Button b1 = new Button();
b1.setOnAction(new EventHandler<ActionEvent>()
{
public void handle(ActionEvent event){
//Here i want the user to press another button and, depending which one he
//pressed, asing a variable
Card aCard = //The card that the button pressed has inside
}
}
That's just it, you don't make the handler wait. Instead you change the behavior of the handler depending on the state of the object. If the object is in the "user has not pressed the first button yet" state, the handler does one thing. If the object is in the "user has previously pressed the first button", then the handler does something else. Your handler should query the state of the object's instance fields to determine this state.
e.g.,
b1.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event){
// may need to use boolean fields or .equals(...) method......
if (someStateField == someValue) {
doBehavior1();
} else {
doBehavior2();
}
}
}

Adapter pattern with Buttons, adaptor class has to know which button was pressed

This is an actionPerformed in a Swing panel with custom buttons from a framework which scrambles their classes so all methods are a():String or b():void and there is no way to make out what it actually is.
I got a compiler error becaus when I inherit this button class the compiler find a():void an a():String which is not allowed in Java. My solution was to use the adapter pattern like this:
public abstract class FactoryButton {
private CustomButton button;
public FactoryButton(int width, int height) {
button = new DynButton();
button.setSize(width, height);
}
public DynButton getButton() {
return button;
}
}
So my FactoryButton has the CustomButton class as a private member. The FactoryButton is the parent of another Button class named FactorySelectionButton
which has an action performed where I used to be able to get the source of the event:
#Override
public void actionPerformed(ActionEvent arg0) {
if (arg0.getSource() instanceof FactorySelectionButton) {
// User selected a factory
selectedItem = ((FactorySelectionButton) arg0.getSource()).getFactory();
// Close the screen, so control returns back to the parent window
cancel();
} else {
// other buttons implementation
}
}
But now since I solved one problem with the adapter pattern I have another the arg0.getSource() no longer gives me the FactorySelectionButton but it now gives a CustomButton which gives me no way to know which custom button is pressed.
The reason for not throwing away the custom button is that I am bound to the framework, I have to use it and the amount of factories can grow so I don't want hardcoded buttons.
So anyone have an idea on how I can fix this?
I found a way around it by looping over all my components and checking whether they have the button I need and they double checking whether it's really an instance of the class I want.
#Override
public void actionPerformed(ActionEvent arg0) {
for (FactoryButton component : components) {
if(component.getButton().equals(arg0.getSource()) && component instanceof FactorySelectionButton)
selectedItem = ((FactorySelectionButton) component).getFactory();
return;
}
//other buttons implementation
}

JavaFX subclassed Button - How to make Label update work?

I want to have several JavaFX Buttons that update one Label in my Application with text. For testing purposes it's just Button Text.
What I did at first worked fine and looked like this:
String Text = "...";
public void kons() {
System.out.println("Works...");
System.out.println(Text);
Tekst.setText(Text);
Button G4 = new Button("Spadantes");
G4.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Text = G4.getText();
kons();
}
});
Then I decided to stylize my buttons with CSS and because I wanted to have several groups of buttons stylized in different way I subclassed JavaFX Button class in this way:
public class Buttons extends Button {
public Buttons(String text) {
super(text);
getStylesheets().clear();
getStylesheets().add("./Buttons.css");
Which still worked. But now I want my event handler to be moved to Button subclass (to avoid copy-pasting exactly same code into each and every button of mine). What I did looks like this:
public class Buttons extends Button {
public Buttons(String text) {
super(text);
getStylesheets().clear();
getStylesheets().add("./Buttons.css");
setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Main.Text = getText();
Main.kons();
}
});
}
}
Main is my extend Application class
Tekst is my label.
And sadly it throws me exception about calling non-stathic method and variable from static context. From what I understand instances are static and definitions are non-static. I tried to change everything "in the way" to static but it gives me red wall of errors after clicking button (nothing in compilation process). I also tried to call instance of my Application somehow but I have no idea how (from what I understand extend Application class intantiates itself on it's own while starting program so there's no "name" by which I can call it's Label.
What I'm looking for is "quick and dirty solution" to be able to use subclassed buttons (or other sliders, text-fields, etc.) that can call a method that updates something "on screen".
[EDIT] I'm using newest Java there is of course. In case it matters.
Instead of subclassing, why not just write a utility method that creates the buttons for you? I would also not recommend making the text variable an instance variable: just reference the Label directly.
public class SomeClass {
private Label tekst ;
// ...
private Button createButton(String buttonText) {
Button button = new Button(buttonText);
button.getStylesheets().add("Buttons.css") ;
button.setOnAction(e -> tekst.setText(buttonText));
return button ;
}
}
Then, from within the same class, when you need one of those buttons you just do
Button button = createButton("Text");
If you really want to subclass (which just seems unnecessary to me), you need to pass a reference to the label to the subclass:
public class LabelUpdatingButton extends Button {
public LabelUpdatingButton(String text, Label labelToUpdate) {
super(text);
getStylesheets().add("Buttons.css");
setOnAction(e -> labelToUpdate.setText(getText()) );
}
}
Then from your class that assembles the UI you can do
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
Label tekst = new Label();
Button someButton = new LabelUpdatingButton("Button text", tekst);
// etc...
}
}
But again, creating a subclass that does nothing other than define a constructor that calls public API methods is redundant, imo.
Also, it's a bit unusual to create an entire stylesheet just for your buttons. Typically you would set a style class on the Button:
button.getStyleClass().add("my-button-class");
and then in the stylesheet you add to the Scene do
.my-button-class {
/* styles for this type of button */
}

Can I call ActionPerformed method from an Event Handler class for JButton?

I have a JButton titled "select"
In the class that creates that JButton and other classes, I want to use an if condition with ActionPerformed method.
Something like(pseudo-code)
if(_selectListener.actionPerformed(ActionEvent)) { //i.e., if select Button is clicked,
//do something
}
Is this possible?
I want to call this method because I have to handle a situation in which a player should be able to choose something by clicking "select" button, or another "scroll" button, and I want to control it using something similar to a bunch of if statements like the one above.
If it is possible, what is the syntax for it? What is the argument ActionEvent?
Thank you!
The easiest and cleanest way is to add a dedicated, specific action listener to each button. That way, when the actionPerformed() method is called, you're sure that the associated button has been clicked, and don't need to test which button has been clicked:
selectButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// handle click on select button
}
});
scrollButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// handle click on scroll button
}
});
Another way is to use a common ActionListener, and use the getSource() method of ActionEvent to know which component triggered the event. Compare the result with each potential button to determine which is the one that has been clicked:
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == selectButton) {
// handle click on select button
}
else if (e.getSource() == scrollButton) {
// handle click on scroll button
}
}
What is the argument ActionEvent?
The answer is in the documentation. Read it.
no you cant call, if needs boolean expression/value, but this method returns void.

Change button title issue

Hi I use GWT and I have a com.smartgwt.client.widgets.Button that has the following eventHandler:
Button viewCommentsButton = new Button("View ");
viewCommentsButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
if (!childrenVisible) {
addChildren();
getParent().setTitle("Close");
} else {
removeChildren();
getParent().setTitle("View");
}
}
});
As you can see I tried getParent().setTitle() method but with no effect. The if works fine so I guess I can't get the reference to my button object but the code compiles and getParent returns a widget so most likely my button.
However, the addChildren and removeChildren methods are working properly but my button has the initial title all the time. Any ideas why? Hope this makes sense.
Any suggestions are welcomed. Thanks.
If you are trying to set the title on viewCommentsButton, call viewCommentsButton.setTitle().
If you are trying to set the text in the button, call viewCommentsButton.setText().
For either of these you'll have to mark the button as final - declare it with final Button viewCommentsButton = ...
The context of getParent() is confusing. getParent(), the way you're using it, will return the parent of the widget in which you're defining all of this, NOT the parent of viewCommentsButton and definitely not viewCommentsButton itself.
Make your button a class variable, rather than a method variable and than you would be able to use it (refer it) inside the click handler.
For example:
viewCommentsButton = new Button("View "); //viewCommentButton is the private member.
viewCommentsButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
if (!childrenVisible) {
addChildren();
viewCommentButton.setTitle("Close");
viewCommentButton.setText("Close");
} else {
removeChildren();
viewCommentButton.setTitle("View");
viewCommentButton.setText("View");
}
}
});
You should use setText
setTitle is the "tooltip"

Categories

Resources