DESCRIPTION: I created a javafx 8 application with the StageStyle.Undecorated window styling. I currently have a minimize, maximize and fullscreen button, as well as a key combination listener for maximizing the window.
QUESTION: Is there a way to attach a listener to the taskbar icon, so in turn I can minimize the application window by left-clicking on the icon?
Add an OnMousePressed event handler to the node containing your icon, then add the method you wish to execute to the handler!
Example of a taskbar!!
public static HBox createButtons(String id, int amount, int width, int height) {
Rectangle[] button = new Rectangle[3];
DropShadow glow = new DropShadow();
HBox buttonBox = new HBox(10);
glow.setSpread(.6);
glow.setRadius(10);
buttonBox.getStylesheets().add(Styles.styledToolBarCss);
buttonBox.setId(id);
buttonBox.setAlignment(Pos.TOP_RIGHT);
button[0] = new Rectangle();
button[0].setFill(new ImagePattern(ImagesAndIcons.minimize));
button[0].setWidth(width);
button[0].setHeight(height);
button[0].setOnMouseEntered(e ->{
glow.setColor(Color.DODGERBLUE);
button[0].setEffect(glow);
});
button[0].setOnMouseExited(e ->{
button[0].setEffect(null);
});
button[0].setOnMouseReleased(e ->{
TileMapEditor.minimize();
});
button[1] = new Rectangle();
button[1].setFill(new ImagePattern(ImagesAndIcons.maximize));
button[1].setWidth(width);
button[1].setHeight(height);
button[1].setOnMouseEntered(e ->{
glow.setColor(Color.DODGERBLUE);
button[1].setEffect(glow);
});
button[1].setOnMouseExited(e ->{
button[1].setEffect(null);
});
button[1].setOnMouseReleased(e ->{
TileMapEditor.maximize();
});
button[2] = new Rectangle();
button[2].setFill(new ImagePattern(ImagesAndIcons.exit));
button[2].setWidth(width*1.5);
button[2].setHeight(height);
button[2].setOnMouseEntered(e ->{
glow.setColor(Color.RED);
button[2].setEffect(glow);
});
button[2].setOnMouseExited(e ->{
button[2].setEffect(null);
});
button[2].setOnMouseReleased(e ->{
TileMapEditor.exit();
});
buttonBox.getChildren().setAll(button);
return buttonBox;
}
Related
public Node dialog(){
Pane root = new Pane();
root.setPrefWidth(200);
root.setPrefHeight(200);
Button button = new Button("Dialog");
button.setOnAction(event -> {
Dialog dialog = new Dialog();
TextArea textArea = new TextArea();
dialog.getDialogPane().setContent(textArea);
ButtonType ok = new ButtonType("OK", ButtonBar.ButtonData.OK_DONE);
ButtonType cancel = new ButtonType("Cancel", ButtonBar.ButtonData.CANCEL_CLOSE);
DialogPane dialogPane = dialog.getDialogPane();
dialogPane.getButtonTypes().addAll(ok, cancel);
textArea.requestFocus();
dialog.showAndWait();
});
root.getChildren().add(button);
return root;
}
I try use textArea.requestFocus(); before dialog.showAndWait(); but when dialog open it always
focus OK Button. How to foucs textArea when dialog first open?
This should do the trick:
dialog.setOnShown(event -> {
Platform.runLater(textArea::requestFocus);
event.consume();
});
dialog.showAndWait();
This question already has answers here:
Get the height of a node in JavaFX (generate a layout pass)
(2 answers)
Closed 3 years ago.
So I'm not sure how to calculate the height of the node during the .setOnAction event I have tried .requestLayout()/.applyCss() not sure what else to try I am trying to find the height of the vBox after adding a node but it is only printing the height of the node before the new one was added
public class Main extends Application {
#Override
public void start(Stage stage) {
VBox vBoxContainer = new VBox();
vBoxContainer.setAlignment(Pos.CENTER);
vBoxContainer.setPrefSize(200,200);
VBox vBox = new VBox();
vBox.setAlignment(Pos.CENTER);
for (int i = 0; i < 5; i++)
vBox.getChildren().add(new Label("newLabel"));
vBoxContainer.getChildren().add(vBox);
Button button = new Button("Add Label");
button.setOnAction(event -> {
System.out.println("Height Before new Label:"+vBox.getHeight());
vBox.getChildren().add(new Label("newLabel"));
//here is where I was adding code to produce expected result
System.out.println("Height After new Label:"+vBox.getHeight());
});
Button checkButton = new Button("Print VBox Height");
checkButton.setOnAction(event -> System.out.println("VBox Height:"+vBox.getHeight()));
vBoxContainer.getChildren().addAll(button, checkButton);
stage.setScene(new Scene(vBoxContainer));
stage.show();
}
}
Run the example and Click the button that adds a Label to the vBox and it outputs
Actual Result:
Height Before new Label:85.0
Height After new Label:85.0
Expected Result:
Height Before new Label:85.0
Height After new Label:102.0
But if you then click the Print VBox Height Button it will show the correct height of:
VBox Height:102.0
You can try adding a listener to the VBox's height property.
VBox vBoxContainer = new VBox();
vBoxContainer.setAlignment(Pos.CENTER);
vBoxContainer.setPrefSize(200, 200);
VBox vBox = new VBox();
vBox.setAlignment(Pos.CENTER);
vBoxContainer.getChildren().add(vBox);
vBox.heightProperty().addListener((observable, oldValue, newValue) -> {
System.out.println("Height changed to: " + newValue.doubleValue());
if(newValue.doubleValue() > 100)
{
//do something!
}
});
for (int i = 0; i < 5; i++) {
vBox.getChildren().add(new Label("newLabel"));
}
Button button = new Button("Add Label");
button.setOnAction(event -> {
vBox.getChildren().add(new Label("newLabel"));
});
Button checkButton = new Button("Print VBox Height");
checkButton.setOnAction(event -> System.out.println("VBox Height:" + vBox.getHeight()));
vBoxContainer.getChildren().addAll(button, checkButton);
stage.setScene(new Scene(vBoxContainer));
stage.show();
requestLayout does not actually do a layout pass. It simply tells JavaFX, that a layout pass is required which will result in JavaFX doing the layout pass some time after your method returns. To do the layout yourself, you need to call layout yourself, i.e. change the logic in the event handler like this:
button.setOnAction(event -> {
System.out.println("Height Before new Label:"+vBox.getHeight());
vBox.getChildren().add(new Label("newLabel"));
// manually doing layout on the root here
vBoxContainer.applyCss();
vBoxContainer.layout();
System.out.println("Height After new Label:"+vBox.getHeight());
});
Note that I do the layout pass for the root, since the ancestor layouts can also be involved in determining the actual size of a Node...
We created a Custom Dialog without an FXML file. We are using JavaFX 8.
The dialog loads and functions as expected but we can not move the Buttons and the TextField to enhance the styling.
We have tried to use tf.setLayoutY(50) this has no effect.
We used this tf.setPromptText("This Works ?") and it works.
We would rather not use css to accomplish this styling.
And we will consider a FXML file if we can keep the two event handlers that force data to be entered in the TextField.
So the question is: How to style this Custom Dialog?
The code is a mess as it includes some concepts we tried:
public void CustomDialog() {
Dialog dialog = new Dialog<>();
dialog.setResizable(false);
final Window window = dialog.getDialogPane().getScene().getWindow();
stage = (Stage) window;
stage.setMinHeight(600);
stage.setMinWidth(400);
TextField tf = new TextField();
tf.setLayoutX(10);
tf.setLayoutY(50);
dialog.getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
dialog.getDialogPane().getChildren().add(tf);
dialog.getDialogPane().setContent(tf);
// Create an event filter that consumes the action if the text is empty
EventHandler<ActionEvent> filter = event -> {
if (tf.getText().isEmpty()) {
event.consume();
}
};
// lookup the buttons
ButtonBase okButton = (Button) dialog.getDialogPane().lookupButton(ButtonType.OK);
Button cancelButton = (Button) dialog.getDialogPane().lookupButton(ButtonType.CANCEL);
// add the event-filter
okButton.addEventFilter(ActionEvent.ACTION, filter);
cancelButton.addEventFilter(ActionEvent.ACTION, filter);
stage.setOnCloseRequest(event -> {
if (tf.getText().isEmpty()) {
event.consume();
}
}
//Scene scene = new Scene(root);
//dialogStage.setScene(scene);
dialog.initModality(Modality.APPLICATION_MODAL);
//dialogStage.setAlwaysOnTop(true);
//dialogStage.setResizable(false);
tf.setPromptText("This Works ?");
tf.requestFocus();// This does not work
dialog.showAndWait();
}
Grendel we enhanced your answer so anyone who comes by and sees the code you posted in your question will understand as you said it was a mess
Your posted answer was real old school but less work perhaps than building a FXML file
Besides it is good to know some old school tricks
public void NewDialog(){
Label lblAmt = new Label("Enter Amount");
Button btnOK = new Button("OK");
TextField txtAmt = new TextField();
AnchorPane secondaryLayout = new AnchorPane();
secondaryLayout.setStyle("-fx-border-color:red;-fx-border-width:10px; -fx-background-color: lightblue;");
secondaryLayout.getChildren().addAll(lblAmt,btnOK,txtAmt);
lblAmt.setLayoutX(30);
lblAmt.setLayoutY(30);
txtAmt.setLayoutX(164);
txtAmt.setLayoutY(25);
txtAmt.setMaxWidth(116);
btnOK.setLayoutX(190);
btnOK.setLayoutY(100);
btnOK.setStyle("-fx-font-size: 18px;-fx-font-weight: bold;");
lblAmt.setStyle("-fx-font-size: 18px;-fx-font-weight: bold;");
txtAmt.setStyle("-fx-font-size: 18px;-fx-font-weight: bold;");
Scene secondScene = new Scene(secondaryLayout, 300, 180);
EventHandler<ActionEvent> filter = event -> {
if(txtAmt.getText().isEmpty()) {
event.consume();
}
};
// New window (Stage)
Stage newWindow = new Stage();
newWindow.initStyle(StageStyle.UNDECORATED);
//newWindow.initModality(Modality.APPLICATION_MODAL);
newWindow.setResizable(false);
newWindow.setTitle("Second Stage");
newWindow.setScene(secondScene);
btnOK.addEventHandler(ActionEvent.ACTION,filter);
btnOK.setOnAction(evt -> {
String str = txtAmt.getText();
System.out.println("################ str "+str);
if(txtAmt.getText().equals("")) {
evt.consume();
txtAmt.requestFocus();
}else{
newWindow.close();
}
});
newWindow.setOnCloseRequest(event -> {
if(txtAmt.getText().isEmpty()) {
event.consume();
}
});
txtAmt.requestFocus();
newWindow.showAndWait();
}
Button btn=new Button("Click Me");
Button btn2=new Button("Click");
btn2.setOnAction(e->System.exit(0));
btn.setOnAction(new EventHandler<ActionEvent>(){
public void handle(ActionEvent action){
System.out.println(5);
}
});
btn2.relocate(0, 0);
StackPane root=new StackPane();
root.getChildren().add(btn);
root.getChildren().add(btn2);
Scene sene=new Scene(root,500,265);
primaryStage.setScene(sene);
primaryStage.show();
I want to move button and using above code but I am unable to move my button?
What is the problem in code and is their any other way to do it???
The answer is :
http://docs.oracle.com/javafx/2/animations/jfxpub-animations.htm
JavaFX has ready libraries for animations.
An example (the rectangle will be faded):
final Rectangle rect1 = new Rectangle(10, 10, 100, 100);
rect1.setArcHeight(20);
rect1.setArcWidth(20);
rect1.setFill(Color.RED);
...
FadeTransition ft = new FadeTransition(Duration.millis(3000), rect1);
ft.setFromValue(1.0); ft.setToValue(0.1);
ft.setCycleCount(Timeline.INDEFINITE);
ft.setAutoReverse(true);
ft.play();
In your code you maybe need TranslateTranstition or just use translateX and translateY methods
I'm a beginner in JavaFX. I'm trying to create my own Button subclass that would have its on animations for mouse enter and mouse exit. The animation I'm trying to achieve is a simple "darken" or "dim" transition that would darken the color of the button background when user hovers over the button , and would animate back to normal state when the mouse exits the button.
First I thought I can achieve this with FillTransition, but for that I would need the specific darker color of the button, that depends on the button color.
So now I'm trying to basically fade in and fade out a low-opacity black rectangle on top of the button, but the rectangle doesn't seem to appear at all.
Here's the code of my button:
public class FlatButton extends Button {
private Rectangle dimRectangle;
private Duration dimDuration = Duration.millis(250);
private Color dimColor = new Color(0,0,0,0.11);
public FlatButton(String text) {
super(text);
getStyleClass().addAll("flat-button-style");
createEffect();
}
private void createEffect()
{
dimRectangle = new Rectangle(this.getWidth(), this.getHeight(), dimColor);
dimRectangle.setOpacity(1.0);
dimRectangle.setX(this.get);
FadeTransition enterTransition = new FadeTransition(dimDuration, this);
enterTransition.setInterpolator(Interpolator.EASE_OUT);
enterTransition.setFromValue(0.0);
enterTransition.setToValue(1.0);
FadeTransition exitTransition = new FadeTransition(dimDuration, this);
exitTransition.setInterpolator(Interpolator.EASE_OUT);
exitTransition.setFromValue(1.0);
exitTransition.setToValue(0.0);
this.setOnMouseEntered(new EventHandler<MouseEvent>(){
public void handle(MouseEvent mouseEvent){
enterTransition.play();
}
});
this.setOnMouseExited(new EventHandler<MouseEvent>(){
public void handle(MouseEvent mouseEvent){
exitTransition.play();
}
});
}
}
EDIT: The part in the code "new FadeTransition(dimDuration, this);" should be "new FadeTransition(dimDuration, dimRectangle);". It's just something I was testing.
EDIT2: I figured that "dimRectangle = new Rectangle(this.getWidth(), this.getHeight(), dimColor);" is not really working , but I havent found a way yet how to make the rectangle fill the button dimensions.
You could use a ColorAdjust effect and change it's brightness property using a Timeline.
public class ButtonFadeDemo extends Application {
#Override
public void start(Stage primaryStage) {
try {
Pane root = new Pane();
Button button = new Button("Click me!");
ColorAdjust colorAdjust = new ColorAdjust();
colorAdjust.setBrightness(0.0);
button.setEffect(colorAdjust);
button.setOnMouseEntered(e -> {
Timeline fadeInTimeline = new Timeline(
new KeyFrame(Duration.seconds(0),
new KeyValue(colorAdjust.brightnessProperty(), colorAdjust.brightnessProperty().getValue(), Interpolator.LINEAR)),
new KeyFrame(Duration.seconds(1), new KeyValue(colorAdjust.brightnessProperty(), -1, Interpolator.LINEAR)
));
fadeInTimeline.setCycleCount(1);
fadeInTimeline.setAutoReverse(false);
fadeInTimeline.play();
});
button.setOnMouseExited(e -> {
Timeline fadeOutTimeline = new Timeline(
new KeyFrame(Duration.seconds(0),
new KeyValue(colorAdjust.brightnessProperty(), colorAdjust.brightnessProperty().getValue(), Interpolator.LINEAR)),
new KeyFrame(Duration.seconds(1), new KeyValue(colorAdjust.brightnessProperty(), 0, Interpolator.LINEAR)
));
fadeOutTimeline.setCycleCount(1);
fadeOutTimeline.setAutoReverse(false);
fadeOutTimeline.play();
});
root.getChildren().addAll(button);
Scene scene = new Scene(root, 800, 400);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}