Label not showing on mouse event JavaFx - java

I have a pie chart where i have added a mouse listener using this guide:
Oracle guide to pie chart
However when i run my program and click on the chart it doesnt do anything.
I have tried to System.out.println(caption.getText()); and the text of the label is correct however the label is just not showing up.
My code is as following:
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Imported Fruits");
stage.setWidth(500);
stage.setHeight(500);
ObservableList<PieChart.Data> pieChartData =
FXCollections.observableArrayList(
new PieChart.Data("Grapefruit", 13),
new PieChart.Data("Oranges", 25),
new PieChart.Data("Plums", 10),
new PieChart.Data("Pears", 22),
new PieChart.Data("Apples", 30));
final PieChart chart = new PieChart(pieChartData);
chart.setTitle("Imported Fruits");
((Group) scene.getRoot()).getChildren().add(chart);
final Label caption = new Label("");
caption.setTextFill(Color.DARKORANGE);
caption.setStyle("-fx-font: 24 arial;");
for (final PieChart.Data data : chart.getData()) {
data.getNode().addEventHandler(MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent e) {
caption.setTranslateX(e.getSceneX());
caption.setTranslateY(e.getSceneY());
caption.setText(String.valueOf(data.getPieValue()) + "%");
caption.setVisible(true);
}
});
}
stage.setScene(scene);
stage.show();
}
}
Can anyone tell me what i did wrong?

You forgot to add the label 'caption' to the list of children in your root node :-)
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Imported Fruits");
stage.setWidth(500);
stage.setHeight(500);
ObservableList<PieChart.Data> pieChartData =
FXCollections.observableArrayList(
new PieChart.Data("Grapefruit", 13),
new PieChart.Data("Oranges", 25),
new PieChart.Data("Plums", 10),
new PieChart.Data("Pears", 22),
new PieChart.Data("Apples", 30));
final PieChart chart = new PieChart(pieChartData);
chart.setTitle("Imported Fruits");
final ObservableList<Node> children = ((Group) scene.getRoot()).getChildren();
children.add(chart);
final Label caption = new Label("");
caption.setTextFill(Color.DARKORANGE);
caption.setStyle("-fx-font: 24 arial;");
children.add(caption);
for (final PieChart.Data data : chart.getData()) {
data.getNode().addEventHandler(MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent e) {
caption.setTranslateX(e.getSceneX());
caption.setTranslateY(e.getSceneY());
caption.setText(String.valueOf(data.getPieValue()) + "%");
caption.setVisible(true);
}
});
}
stage.setScene(scene);
stage.show();
}
I have made the above change and can verify that it works (as depicted by the image below)

no need for that, you just have to add caption, here:
Change this line :((Group) scene.getRoot()).getChildren().addAll(chart);
to :((Group) scene.getRoot()).getChildren().addAll(chart,caption);

Related

Javafx Combo box, cannot find symbol getValue()

I've been trying to code this Javafx gui program, however when ever Try to use the getValue() method it ends up saying "it can't find that symbol". Even if I try demos of using the method. How can i get this method to work, is there any other way I can get code to run when the user chooses a choice from the combobox?
not showing my imports, as they are a lot.
public class LogoMaster3000 extends Application {
BorderPane border;
HBox hbox;
Canvas can;
AnchorPane ap;
Scene scene;
Button shapesComboBox;
// Desktop desktop = Desktop.getDesktop();
TextField tx;
#Override
public void start(Stage primaryStage) {
border = new BorderPane();
hbox = addHBox();
border.setTop(hbox);
border.setLeft(addVBox());
addStackPane(hbox); // Add stack to HBox in top region
can = new Canvas();
can.setStyle("-fx-background-color: #E8EACD");
AnchorPane wrapperPane = new AnchorPane();
border.setCenter(wrapperPane);
scene = new Scene(border, 1000, 600);
primaryStage.setTitle("LogoMaker 3000");
primaryStage.setScene(scene);
primaryStage.show();
shapesComboBox.setOnAction(
new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if (shapesComboBox.getValue == "Square"){
Rectangle square = new Rectangle(50, 50);
square.setFill(Color.BLACK);
DragResizeMod.makeResizable(square, null);
wrapperPane.getChildren().add(square);
}
if (shapesComboBox.getValue == "Rectangle"){
Rectangle rectangle = new Rectangle(50, 50);
rectangle.setFill(Color.BLACK);
DragResizeMod.makeResizable(rectangle, null);
wrapperPane.getChildren().add(rectangle);
}
if (shapesComboBox.getValue == "Triangle"){
Polygon polygon = new Polygon();
polygon.getPoints().addAll(new Double[]{
75, 0,
50, 50,
100, 100
})
polygon.setFill(Color.BLACK);
DragResizeMod.makeResizable(polygon, null);
wrapperPane.getChildren().add(polygon);
}
if (shapesComboBox.getValue == "Circle"){
Circle circle = new Circle(100,100,50);
circle.setFill(Color.BLACK);
DragResizeMod.makeResizable(circle, null)
wrapperPane.getChildren().add(circle);
}
}
}
);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
public void addStackPane(HBox hb) {
StackPane stack = new StackPane();
Rectangle helpIcon = new Rectangle(30.0, 25.0);
helpIcon.setFill(new LinearGradient(0,0,0,1, true, CycleMethod.NO_CYCLE,
new Stop[]{
new Stop(0,Color.web("#4977A3")),
new Stop(0.5, Color.web("#B0C6DA")),
new Stop(1,Color.web("#9CB6CF")),}));
helpIcon.setStroke(Color.web("#D0E6FA"));
helpIcon.setArcHeight(3.5);
helpIcon.setArcWidth(3.5);
Text helpText = new Text("?");
helpText.setFont(Font.font("Verdana", FontWeight.BOLD, 18));
helpText.setFill(Color.WHITE);
helpText.setStroke(Color.web("#7080A0"));
stack.getChildren().addAll(helpIcon, helpText);
stack.setAlignment(Pos.CENTER_RIGHT); // Right-justify nodes in stack
StackPane.setMargin(helpText, new Insets(0, 10, 0, 0)); // Center "?"
hb.getChildren().add(stack); // Add to HBox from Example 1-2
HBox.setHgrow(stack, Priority.ALWAYS); // Give stack any extra space
}
public VBox addVBox() {
VBox vbox = new VBox();
vbox.setPadding(new Insets(10));
vbox.setSpacing(8);
Text title = new Text("Logo Maker");
title.setFont(Font.font("Arial", FontWeight.BOLD, 14));
vbox.getChildren().add(title);
final ComboBox shapesComboBox = new ComboBox();
shapesComboBox.getItems().addAll(
"Square",
"Rectangle",
"Triangle",
"Circle",
"Pyramid",
"Cube",
"Sphere"
);
shapesComboBox.setPromptText("Shapes");
shapesComboBox.setMaxWidth(Double.MAX_VALUE);
vbox.getChildren().add(shapesComboBox);
return vbox;
}
}

Background color transition on a JavaFX 8 Node/Region/Pane

Is it possible to do a simple background "flash" effect with a gradual fade on an arbitrary Node/Region/Pane?
I just want to show a subtle/brief red/white "flash" effect on a VBox (containing a label) to draw attention to it when the label's value changes.
Edit: All examples of this nature I've found so far seem to use a "Shape" (which is a Node), but of course a VBox or a Pane aren't a Shape - so that doesn't help me too much. Calling getShape() on the VBox just returns a null, so that's no help (I guess layout code hasn't been executed yet).
Edit 2:
This ALMOST works, but this dang effect seems to be completely overwriting (I think) everything in the VBox, including the text Label.
ColorInput effect = new ColorInput(0, 0, 900, 25, Paint.valueOf("#FFDDDD"));
Timeline flash = new Timeline(
new KeyFrame(Duration.seconds(0.4), new KeyValue(effect.paintProperty(), Paint.valueOf("#EED9D9"))),
new KeyFrame(Duration.seconds(0.8), new KeyValue(effect.paintProperty(), Paint.valueOf("#E0DDDD"))),
new KeyFrame(Duration.seconds(1.0), new KeyValue(effect.paintProperty(), Paint.valueOf("#DDDDDD"))));
vbox.setEffect(effect);
flash.setOnFinished(e -> vbox.setEffect(null));
flash.play();
Best way would be to provide a custom animation, like this (elaborating on fabian's answer):
#Override
public void start(Stage primaryStage) {
Label label = new Label("Bla bla bla bla");
Button btn = new Button("flash");
VBox box = new VBox(10, label, btn);
box.setPadding(new Insets(10));
btn.setOnAction((ActionEvent event) -> {
//**************************
//this animation changes the background color
//of the VBox from red with opacity=1
//to red with opacity=0
//**************************
final Animation animation = new Transition() {
{
setCycleDuration(Duration.millis(1000));
setInterpolator(Interpolator.EASE_OUT);
}
#Override
protected void interpolate(double frac) {
Color vColor = new Color(1, 0, 0, 1 - frac);
box.setBackground(new Background(new BackgroundFill(vColor, CornerRadii.EMPTY, Insets.EMPTY)));
}
};
animation.play();
});
Scene scene = new Scene(box, 100, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
You could animate a effect, e.g. DropShadow:
#Override
public void start(Stage primaryStage) {
Label label = new Label("Bla bla bla bla");
DropShadow shadow = new DropShadow();
shadow.setColor(Color.RED);
shadow.setSpread(0.75);
Timeline shadowAnimation = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(shadow.radiusProperty(), 0d)),
new KeyFrame(Duration.seconds(0.15), new KeyValue(shadow.radiusProperty(), 20d)));
shadowAnimation.setAutoReverse(true);
shadowAnimation.setCycleCount(2);
Button btn = new Button("flash");
btn.setOnAction((ActionEvent event) -> {
Node target = label;
target.setEffect(shadow);
shadowAnimation.setOnFinished(evt -> target.setEffect(null));
shadowAnimation.play();
});
VBox box = new VBox(10, label, btn);
box.setPadding(new Insets(10));
Scene scene = new Scene(box, 100, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
You can create a fake shape and use the FillTransition Interpolator to apply the shape's fill to the control background.
public static void AnimateBackgroundColor(Control control, Color fromColor,Color toColor,int duration)
{
Rectangle rect = new Rectangle();
rect.setFill(fromColor);
FillTransition tr = new FillTransition();
tr.setShape(rect);
tr.setDuration(Duration.millis(duration));
tr.setFromValue(fromColor);
tr.setToValue(toColor);
tr.setInterpolator(new Interpolator() {
#Override
protected double curve(double t) {
control.setBackground(new Background(new BackgroundFill(rect.getFill(), CornerRadii.EMPTY, Insets.EMPTY)));
return t;
}
});
tr.play();
}

How do I display a popup while I'm on the primary stage

I tried using this method to print show a popup with label "THAT'S IT" and I don't want to use the Popup class
public void showStage(Stage Owner){
HBox hBox = new HBox();
hBox.getChildren().add(new Label("THAT'S IT"));
Scene sc = new Scene(hBox);
Stage popup = new Stage();
popup.setScene(sc);
popup.setWidth(400);
popup.setHeight(100);
popup.initOwner(owner);
popup.initModality(Modality.WINDOW_MODAL);
popup.show();
}
and then I call the showStage() method from the start method
public void start(Stage primaryStage) {
Label lb = new Label();
btn.setText("Say 'Hello World'");
btn.setOnAction(e->{
lb.setText("hello everyone");showStage(primaryStage);
});
But the output of the code :
Why don't you use a dialog?
You can use it in your main controller class without creating an other stage for instance like this:
Dialog dialogQtPrescription = new Dialog();
dialogQtPrescription.setTitle("yourTitle");
dialogQtPrescription.setHeaderText("yourHeadertext");
dialogQtPrescription.initModality(Modality.WINDOW_MODAL);
dialogQtPrescription.initOwner(mainStage);
dialogQtPrescription.initStyle(StageStyle.UTILITY);
GridPane gridDialogPrescription = new GridPane();
gridDialogPrescription.setHgap(10);
gridDialogPrescription.setVgap(10);
gridDialogPrescription.add(new Label(bundle.getString("quantityPrescription.title")), 0, 0);
TextField txtQtPrescr = new TextField();
ButtonType buttonTypeNo = new ButtonType("no");
ButtonType buttonTypeYes = new ButtonType("yes");
ButtonType buttonTypeCancel = new ButtonType("Cancel", ButtonData.CANCEL_CLOSE);
dialogQtPrescription.getDialogPane().getButtonTypes().addAll(buttonTypeNo,buttonTypeYes, buttonTypeCancel);
txtQtPrescr.setPrefWidth(100);
gridDialogPrescription.add(txtQtPrescr, 1, 0);
dialogQtPrescription.getDialogPane().setContent(gridDialogPrescription);
Optional<ButtonType> result = dialogQtPrescription.showAndWait();
this is just a stack of code from a project but i hope it make you to understand my idea.
here's better explained: http://code.makery.ch/blog/javafx-dialogs-official/
You can use this in order to make a Popup on any Screen in JavaFX
public void popup() {
final Stage dialog = new Stage();
dialog.setTitle("Confirmation");
Button yes = new Button("Yes");
Button no = new Button("No");
Label displayLabel = new Label("What do you want to do ?");
displayLabel.setFont(Font.font(null, FontWeight.BOLD, 14));
dialog.initModality(Modality.NONE);
dialog.initOwner((Stage) tableview.getScene().getWindow());
HBox dialogHbox = new HBox(20);
dialogHbox.setAlignment(Pos.CENTER);
VBox dialogVbox1 = new VBox(20);
dialogVbox1.setAlignment(Pos.CENTER_LEFT);
VBox dialogVbox2 = new VBox(20);
dialogVbox2.setAlignment(Pos.CENTER_RIGHT);
dialogHbox.getChildren().add(displayLabel);
dialogVbox1.getChildren().add(yes);
dialogVbox2.getChildren().add(no);
yes.addEventHandler(MouseEvent.MOUSE_CLICKED,
new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
// inside here you can use the minimize or close the previous stage//
dialog.close();
}
});
no.addEventHandler(MouseEvent.MOUSE_CLICKED,
new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
dialog.close();
}
});
dialogHbox.getChildren().addAll(dialogVbox1, dialogVbox2);
Scene dialogScene = new Scene(dialogHbox, 500, 40);
dialogScene.getStylesheets().add("//style sheet of your choice");
dialog.setScene(dialogScene);
dialog.show();
}

JavaFX: why does my scene moving?

I am building a javaFX application.
The example program which is online working well: http://www.java2s.com/Tutorials/Java/JavaFX/1010__JavaFX_Timeline_Animation.htm
I changed it a bit:
I want to have these nice moving circles in the background. That's why I made these tricks:
Main.java:
#Override
public void start(Stage primaryStage) {
try {
// load the FXML resource
FXMLLoader loader = new FXMLLoader(getClass().getResource("Dashboard.fxml"));
// store the root element so that the controllers can use it
StackPane root = new StackPane();
Pane bgRoot = new Pane();
GridPane userRoot = (GridPane) loader.load();
// create and style a scene
Rectangle2D primaryScreenBounds = Screen.getPrimary().getBounds();
BackgroundScene bgScene = new BackgroundScene(root, bgRoot, primaryScreenBounds.getWidth(),
primaryScreenBounds.getHeight(), Color.BLACK);
// TODO CSS load:
// bgScene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
// create the stage with the given title and the previously created
// scene
primaryStage.setFullScreen(true);
primaryStage.setMaximized(true);
primaryStage.setResizable(false);
primaryStage.setMinWidth(primaryScreenBounds.getWidth());
primaryStage.setMinHeight(primaryScreenBounds.getHeight());
primaryStage.setScene(bgScene);
root.getChildren().add(bgRoot);
root.getChildren().add(userRoot);
// show the GUI
primaryStage.show();
userRoot.setPrefHeight(root.getHeight());
userRoot.setPrefWidth(root.getWidth());
} catch (Exception e) {
e.printStackTrace();
}
}
In the above code:
I have a stage with a stack pane.
There is a Pane on the StackPane with the Circles
On that there is a GridPane for controllers.
I made my own Scene as BackgroundScene:
public class BackgroundScene extends Scene {
private Pane bgRoot;
public BackgroundScene(Parent root, Pane bgRoot, double width, double height, Color color) {
super(root, width, height, color);
this.bgRoot = bgRoot;
makeGreenCircleAnimation();
}
public void makeGreenCircleAnimation() {
Group circles = new Group();
for (int i = 0; i < 30; i++) {
Circle circle = new Circle(Math.random() * this.getWidth(), Math.random() * this.getHeight(),
150, Color.web("white", 0.05));
circle.setStrokeType(StrokeType.OUTSIDE);
circle.setStroke(Color.web("white", 0.16));
circle.setStrokeWidth(4);
circles.getChildren().add(circle);
}
circles.setEffect(new BoxBlur(10, 10, 3));
Rectangle colors = new Rectangle(this.getWidth(), this.getHeight(),
new LinearGradient(0f, 1f, 1f, 0f, true, CycleMethod.NO_CYCLE,
new Stop[] { new Stop(0, Color.web("#00ff00")), new Stop(0.14, Color.web("#11ee11")),
new Stop(0.28, Color.web("#22dd22")), new Stop(0.43, Color.web("#33cc33")),
new Stop(0.57, Color.web("#44bb44")), new Stop(0.71, Color.web("#55aa55")),
new Stop(0.85, Color.web("#669966")), new Stop(1, Color.web("#778877")), }));
Group blendModeGroup = new Group(
new Group(new Rectangle(this.getWidth(), this.getHeight(), Color.DARKGREEN), circles), colors);
colors.setBlendMode(BlendMode.OVERLAY);
bgRoot.getChildren().add(blendModeGroup);
Timeline timeline = new Timeline();
makeAnimation(circles, timeline);
timeline.play();
timeline.setOnFinished(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
makeAnimation(circles, timeline);
timeline.play();
}
});
}
void makeAnimation(Group group, Timeline timeline) {
timeline.getKeyFrames().clear();
for (Node node : group.getChildren()) {
timeline.getKeyFrames()
.addAll(new KeyFrame(Duration.ZERO, // set start
// position at 0
new KeyValue(node.translateXProperty(), node.getLayoutX() + node.getTranslateX()),
new KeyValue(node.translateYProperty(), node.getLayoutY() + node.getTranslateY())),
new KeyFrame(new Duration(4000), // set end position at
// 40s
new KeyValue(node.translateXProperty(), Math.random() * this.getWidth()),
new KeyValue(node.translateYProperty(), Math.random() * this.getHeight())));
}
}
}
It contains the code from the tutorial (with minor changes).
I add the circles and everything to the Pane not to a Group (as in
the online example)
The problem is that it is seams to be moving:
The circles are moving to the right (always)
If I change something in the code:
Main.java (instantiating my scene):
BackgroundScene bgScene = new BackgroundScene(root, root, primaryScreenBounds.getWidth(),
primaryScreenBounds.getHeight(), Color.BLACK);
(so giving the circles to the StackPane)
This happens:
You can download the eclipse project:
https://www.dropbox.com/s/dovae0hxdtsnsdo/Test.7z?dl=0
Do you know what is the problem?
Or can you suggest something how I can put the circles nicely behind the button?

JAVAFX:Create stage and text area at runtime

I am new to JavaFX, here I want to create a new Stage and one TextArea inside it at the run-time and I want to pass a line to that text area and update it continuously.
Can anybody please give me the example of doing this?
Hyperlink link = new Hyperlink("TEST");
link.setOnAction(new EventHandler<ActionEvent>() {
#override public void handle(ActionEvent e) {
Stage stage = new Stage();
TextArea text = new TextArea():
VBox vbox = new VBox();
Button close = new Button();
close.setText("Close");
close.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
stage.close();
}
});
vbox.getChildren().addAll(text, close);
Scene scene = new Scene(vbox);
stage.setScene(scene);
stage.setMinWidth(100);
stage.setMinHeight(100);
stage.show();
// ...
text.setText("update");
}
});

Categories

Resources