I would like to know if there is any method to know when the Spinner is increased.
The ideal would be to know the moment in which the Spinner increases
You can add a ChangeListener to the value property of the Spinner which will be notified of changes. Since the old and the new values are both passed to the changed method, it allows you to find out, if the value was increased or decreased:
Spinner<Integer> spinner = new Spinner<>(0, 100, 0);
spinner.valueProperty().addListener((observable, oldValue, newValue) -> {
if (oldValue < newValue) {
System.out.println("value increased");
}
});
In the handler you could also retrieve the time, e.g. by using System.currentTimeMillis if this is necessary.
Related
I'm new to JavaFX and am trying to monitor the resize events on a window so that I can trigger a recalculation of the layout.
If I create a stage and set the scene like in the example below I only get each resize event to be fired once. No matter how many times I resize the window.
Stage stage = new Stage();
stage.setScene(someScene);
stage.setTitle("Some Title");
stage.initModality(Modality.APPLICATION_MODAL);
stage.show();
stage.widthProperty().addListener(observable -> {
System.out.println("Width changed");
});
stage.heightProperty().addListener(observable -> {
System.out.println("Height changed");
});
First note:
I'm trying to monitor the resize events on a window so that I can
trigger a recalculation of the layout.
This is almost certainly the wrong approach. Layout recalculations will be triggered automatically when the stage and scene change size. If you use standard layout panes, there is no need to register listeners. If you really need a custom layout (which is highly unlikely), you should subclass Pane and override layoutChildren() (and other appropriate methods) to hook into the same layout system.
However, in the interests of explaining what you're observing:
You're registering an InvalidationListener with each property, which gets notified when the property goes from a valid state to an invalid state.
The invalid state only becomes valid again if you actually request the value of the property (e.g. stage.getWidth()). Since you never do that, the property never becomes valid, and hence never goes from valid to invalid again.
Instead, register a ChangeListener with each property:
stage.widthProperty().addListener((observable, oldWidth, newWidth) -> {
System.out.println("Width changed");
});
stage.heightProperty().addListener((observable, oldHeight, newHeight) -> {
System.out.println("Height changed");
});
Alternatively, you can force validation by requesting the value (though I think the change listener above actually gets to the point of what you are trying to do):
stage.widthProperty().addListener(observable -> {
System.out.println("Width changed: "+stage.getWidth());
});
etc.
I'm trying to create a media player in javafx8, and for that I created a button and set it onAction to add a change listener to the stage fullscreen property and make the stage full screen if it's not and exit the full screen if it's already.
public void setFullScreen(ActionEven event) {
Stage stage = ((Stage) containerBorderPane.getScene().getWindow());
stage.fullScreenProperty().addListener((observable, oldValue, newValue) ->
setUpMenuBar(stage.isFullScreen())
);
stage.setFullScreen(!stage.isFullScreen());
}
this method is called every time I click the button, so is this "Change Listener" added to fullScreenProperty multiple times or just once?
Every time setFullScreen is invoked you create a new ChangeListener and register it with the property. So you aren't adding "this" ChangeListener each time but a different ChangeListener each time.
Even if you did pass the same ChangeListener to addListener each time it would still be added multiple times. From the documentation of ObservableValue.addListener(ChangeListener) (emphasis mine):
Adds a ChangeListener which will be notified whenever the value of the ObservableValue changes. If the same listener is added more than once, then it will be notified more than once. That is, no check is made to ensure uniqueness.
Essentially, what I'm trying to do is something like to a text-based RPG using JavaFX. Right now, to display some text, I've got this:
final IntegerProperty i = new SimpleIntegerProperty(0);
Timeline timeline = new Timeline();
KeyFrame keyFrame = new KeyFrame(
Duration.millis(70),
event -> {
if (i.get() > info.getText().length()) {
timeline.stop();
} else {
text.setText(info.getText().substring(0, i.get()));
i.set(i.get() + 1);
}
});
timeline.getKeyFrames().add(keyFrame);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
timeline.setOnFinished(a -> {
hb_start.getChildren().clear();
hb_start.getChildren().addAll(start_left,start_right);
hb_start.setAlignment(Pos.CENTER);
});
Because the length of the animation depends on the size of the text, the cyclecount is set to indefinite. Unless there's some other way I'm missing to make the animation play once and then stop, I'd like it so that when you press enter (or some other key that I decide on later) for it to call timeline.stop(); but I can't figure out how to add any sort of listener. Trying to implement keyListenerseems to come with all sorts of stuff that I don't need, and it also doesn't work with a TextField, and instead wants a JTextField, which might be fine, except that I don't have a clue how to do anything with Swing.
Currently, the text is being displayed in aTextFlow from the text of Text. I'm assuming the listener would be added to the TextFlow, or even the scene itself, honestly, I'm at a loss for what to do. It sounds simple, but I can't seem to figure it out.
KeyListener is a AWT class, not a JavaFX class. Unless you're embedding a Swing component in your JavaFX application or a JavaFX node in a Swing application, you should use JavaFX's equivalent EventHandler<KeyEvent> instead. Furthermore there is no need to include a TextField (or Swing's JTextField) in your application just for the sake of receiving key events. You could add the listener directly to the Scene:
final KeyCode stopKey = KeyCode.ENTER;
EventHandler<KeyEvent> handler = event -> {
if (event.getCode() == stopKey) {
timeline.stop();
}
};
scene.setOnKeyPressed(handler);
Note that events can be consumed by nodes before they reach the scene, e.g. by a TextField that has the focus. In this case you could make sure you get the event by registering a the listener as a event filter instead:
// scene.setOnKeyPressed(handler);
scene.addEventFilter(KeyEvent.KEY_PRESSED, handler);
I'm trying to build a calculator, and I have looked all over internet and the examples don't help me, so I have buttons created and everything, I'm trying to display on:
TextField Result = new TextField();
Result.setEditable(false);
Result.setAlignment(Pos.CENTER_RIGHT);
Result.setMinSize(210, 30);
Result.textProperty().bind(Bindings.format("%.0f" , value));
pane.getChildren().add(Result);
the number of the button pressed, how do I do that? Let's say the button was:
Button uno = new Button("1");
uno.setMinSize(40, 40);
pane.getChildren().add(uno);
How do I make the text field Result show number 1?
BIG Thanks!
The simplest way is to add a listener for each your button and change your TextField dynamically:
uno.pressedProperty().addListener((o, old, newValue) -> Result.setText("1"));
dos.pressedProperty().addListener((o, old, newValue) -> Result.setText("2"));
Note, when the user pressed and unpressed a button your listener will react twice with newValue = true/false. Do the additional checking if needed:
uno.pressedProperty().addListener((o, old, newValue) -> {
if (newValue) {
Result.setText("1")
}
});
UPDATE:
Don't forget to remove this line as wrong solution:
Result.textProperty().bind(Bindings.format("%.0f" , value));
I have a PopOver ControlsFX and I want to create an event every time disappears. You searched information and I think it is done with the method onHiddenProperty but I cannot apply it correctly.
You can check if it has lost the focus which means that the popover disappears:
popOver.focusedProperty().addListener((observable, oldValue, newValue) -> {
if (oldValue){
// oldValue is true -> current value is false-> no focus
// TODO your code here
}
});