JavaFX button not responding on first click - java

public void handle(){
submit.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
LoginConnection login = new LoginConnection();
boolean pass = login.login(usernameField.getText(), passwordField.getText());
if(pass)
flip(SceneNames.Main);
else
invalLoginMessage.setOpacity(1.00);
}
});
register.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
flip(SceneNames.Register);
}
});
}
When i click on submit or register, it takes two click for it to do anything. How do i fix this?

What happens is that on first click it adds the handlers specified in the method and on second and consecutive clicks, it uses the handlers. To fix it just create separate methods to add through fxml or scene builder.

Related

JavaFX mouse click event for Labels

I am trying to build a simple planner app using JavaFX. My current goal is to be able to:
click on a panel of the calendar (already implemented)
type in a task, hit enter and have it show up as a Label (already implemented)
click on the currently placed labels and remove them from the calendar. (issue)
Step 3 is where I am having most trouble. I am confident that I am setting up my mouse event for the label correctly but when I click on one of the labels it runs the mouse event for the panel. I need a way to override the pane's mouse event so I can use the labels mouse event, but I'm not too sure how to go about that. Any feedback would be great!
this.setOnMouseClicked(e ->
{
TextField field = new TextField();
this.getChildren().add(field);
//sets field as a label
field.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent key) {
KeyCode k = key.getCode();
if ((k.equals(KeyCode.ENTER))) {
Label lab = new Label(field.getText());
getChildren().add(lab);
getChildren().remove(field);
}
}
});
//removes textfield and label
field.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent ke) {
KeyCode kc = ke.getCode();
if ((kc.equals(KeyCode.ESCAPE))) {
getChildren().remove(field);
}
}
});
});
if(lab != null)
{
lab.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
setStyle("-fx-background-color: #00FF00;");
}
});
}

JavaFX KeyEvents during Drag & Drop operation

I need to know whether a certain key is down while performing a drag & drop operation.
So I tried to use setOnKeyPressed / setOnKeyReleased of a Scene with a combination of HashMap, but I have a problem with this approach:
Imagine a scenario that one drags & drops a TableView item to somewhere while holding Control down. Now if I display a dialog at the end of the drop, while still holding Control down, the setOnKeyReleased is never called with this approach... as the Dialog is the one receiving the key released event.
How could I fix this?
Hope I understand your question here is a possible solution(work with any key):
public class Main extends Application {
SimpleBooleanProperty isKeyPress = new SimpleBooleanProperty(false);
#Override
public void start(Stage primaryStage) throws Exception{
Parent window = new VBox();
((VBox) window).getChildren().add(new Label("example of small window:"));
primaryStage.setTitle("example");
Scene scene=new Scene(window);
primaryStage.setScene(scene);
primaryStage.show();
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
System.out.println("Press");
isKeyPress.set(true);
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Information Dialog");
alert.setHeaderText(null);
alert.setContentText("I have a great message for you!");
Scene alertScene = alert.getDialogPane().getScene();
alertScene.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
System.out.println("Released on dialog");
isKeyPress.set(false);
}
});
alert.showAndWait();
}
});
scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
System.out.println("Released");
isKeyPress.set(false);
}
});
}
public static void main(String[] args) {
launch(args);
}
}
output exmple:
Press
Released on dialog
From your comment the goal is to change the behavior of the drag and drop depending on whether or not Ctrl is down. When it is do a copy operation, otherwise do a move operation. You do not need to deal with KeyEvents to implement this behavior. Instead, you would determine whether to copy or move in the onDragDetected handler. The onDragDetected handler uses a MouseEvent which has methods for querying the status of modifier keys—such as isControlDown(). Using this, we can specify what transfer modes are allowed based on the modifier keys.
Node node = ...;
node.setOnDragDetected(event -> {
Dragboard board;
if (event.isControlDown()) {
board = node.startDragAndDrop(TransferMode.COPY);
} else {
board = node.startDragAndDrop(TransferMode.MOVE);
}
// add contents to Dragboard
});
Note it may be more cross-platform to use isShortcutDown().

Handling nested events

I have a game that displays an archer and I am trying to set it up so that when my button is pressed, the user is then allowed to click anywhere on the screen and then a new archer would be set to where the click happen. My code currently allows me to click the screen and set a new archer regardless of whether the button was pressed or not. Could someone explain what is wrong becuase I though MouseEvent would occur on the scene once the button was pressed.
myButton.setOnMouseClicked(
new EventHandler<MouseEvent>()
{
public void handle(MouseEvent e)
{
gc.setFill(color);
gc.fillRect(0,0,width,height);
scene.setOnMouseClicked(new EventHandler<MouseEvent>()
{
public void handle(MouseEvent e)
{
archer.setX((int)e.getSceneX());
archer.setY((int)e.getSceneY());
archer.drawCharStand(gc);
}
});
}
});
You could use a ToggleButton, so that you only place the archer when the toggle button is selected:
private ToggleButton myButton = new ToggleButton("Place Archer");
// ...
scene.setOnMouseClicked(e -> {
if (myButton.isSelected()) {
archer.setX((int)e.getSceneX());
archer.setY((int)e.getSceneY());
archer.drawCharStand(gc);
myButton.setSelected(false);
}
});
The last line will unselect the toggle button "automatically" after placing the archer. If you want the user to be able to place multiple archers easily (and have to manually switch off that mode), omit that line.
You will need to change your code slightly. Perhaps try with a variable that tracks if the button was clicked:
boolean archerPlacementMode = false;
....
myButton.setOnMouseClicked(new EventHandler<MouseEvent>(){
public void handle(MouseEvent e)
{
if(!archerPlacementMode) {
archerPlacementMode = true;
gc.setFill(color);
gc.fillRect(0,0,width,height);
archerPlacementMode = true;
return;
}
}
});
scene.setOnMouseClicked(new EventHandler<MouseEvent>() {
public void handle(MouseEvent e)
{
if(archerPlacementMode) {
archer.setX((int)e.getSceneX());
archer.setY((int)e.getSceneY());
archer.drawCharStand(gc);
archerPlacementMode = false;
}
}
});

Can not catch event in the second click

Hj. I have a combobox in Javafx.
Initially, I am in AVAILABLE. Then I press the combobox to choose 'AUXUALY' state, it will pop up a dialog to confirm 'AUXUALY' or not. The issue happens when I cancel the pop-up, I can not catch event click to 'AUXUALY' in the next click.
Looking to the attached image, it seems we are still in 'AUXUALY' state because I can see a rectangle covering the 'AUXUALY' button. I can catch event only if I select the LOGOUT state.
Is there anyone here suggest me to overcome this problem?
class MyCombobox extends Combox{
this.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) { // can not catch event here after canceling the dialog
if change = 'AVAILABLE' then
if change = 'AUXUALY' then PopUp.getinstance().showDialog();
if change = 'LOGOUT' then
}
}
class PopUp extends Window{
btOk.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
...
}
btCancel.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
hide();
}
public void showDialog(){
this.show();
}
}

Update GUI upon button Click: JavaFX

Looking to update GUI first thing upon click of a button however Platform.runLater executes at a later stage and am looking for the piece of code which updates the GUI to happen first thing upon click of a button.
Platform.runLater(new Runnable() {
#Override
public void run() {
//Update GUI here
}
});
Would highly appreciate if anyone can provide any inputs or recommendations.
Although the API specifies that Platform.runLater "runs the specified Runnable on the JavaFX Application Thread at some unspecified time in the future", it usually takes little to no time for the specified thread to be executed. Instead, you can just add an EventHandler to the button to listen for mouse clicks.
Assuming the controller implements Initializable
#FXML Button button;
#Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
button.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
updateGUI();
}
});
}
private void updateGUI() {
// code
}

Categories