Java change Label image - java

I have two different StackPanes with HBoxes I want to change the image of a label in the second StackPane with a Label(MouseListener) in the first StackPane I think the problem is that the Label doesn't gets repainted or reloaded
First StackPane:
Label label= new Label("",new ImageView(ClearSpace));
label.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent event) -> {
HotBar hb = new HotBar();
if(hb.getX1() == 0){
hb.setImageX1(5);
}
event.consume();
});
Second StackPane(HotBar):
public Label x1;
Image image= new Image(getClass().getResourceAsStream("/resources/images/Test.png"));
...
Label x1 = new Label("",new ImageView(image));
...
public void setImage(int i){
if(i == 5){
x1.setGraphic(new ImageView(image2));
}
}
I think these are the importantst parts of hte code
setImage() is definetly working if you use it below Label x1 = ... it works

In your EventHandler you create a new instance of HotBar on which you do changes, but this instance is not linked to the scene.
Instead you should pass the instance of HotBar into the other class and use that in your event handler.

package helloworld;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
/**
* Created by matt on 3/22/16.
*/
public class SwapLabel extends Application {
int i = 0;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
Pane root = new Pane();
Image img1 = new Image("http://www.logotemplater.com/freelogostemplates/voope-free-logo-template.png", true);
Image img2 = new Image("http://www.logotemplater.com/freelogostemplates/zoozz-vector-logo-template-sample.png", true);
Label l = new Label("", new ImageView(img1));
l.addEventHandler(MouseEvent.MOUSE_CLICKED, e->{
i = (i+1)%2;
if(i==0){
l.setGraphic(new ImageView(img1));
}else{
l.setGraphic(new ImageView(img2));
}
});
root.getChildren().add(l);
primaryStage.setScene(new Scene(root, 200, 200));
primaryStage.show();
}
}
This appears to be what you are trying to do, but this works. So most likely something else is happening.

Related

How to set minimum diameter in jfxtras CircularPane?

How to set minimum diameter to jfxtras circularpane. For example take a look at following code,
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import jfxtras.scene.layout.*;
/**
* AssistiveBall
*/
public class AssistiveBall extends Application
{
#Override
public void start(Stage pStage) throws Exception
{
StackPane root = new StackPane();
CircularPane pane = new CircularPane();
Scene scene = new Scene(root, 800, 600);
Button btn = new Button("Center");
Button[] buttons = new Button[13];
for (int i = 0; i < buttons.length; i++)
{
buttons[i] = new Button("" + i);
}
pane.getChildren().addAll(buttons);
btn.setOnAction(e -> {
if(pane.isVisible())
{
pane.setVisible(false);
}
else
{
pane.setVisible(true);
}
});
root.getChildren().add(pane);
root.getChildren().add(btn);
pStage.setScene(scene);
pStage.setTitle("Assistive Ball");
pStage.show();
}
public static void main( String[] args )
{
AssistiveBall.launch(args);
}
}
Here here code if fine, but if i use just 3 buttons it starts appear one on another, So how to set minimum diameter or there is any another way to do this ?
Thanks.
Version 11-r3-SNAPSHOT has changed certain methods like computeChainDiameter and determineBeadDiameter to protected, so you can override them and tune the output.

How to change the keyvalue's target value constantly in a javafx Timeline?

Instead of giving a fixed value as a target is there any way to continuously change the keyvalues's target value while the animation is running.
To achieve this goal I have bound the target value with a node's width property which changes continuously.But bind is not working at all when the animation starts the target value doesn't update and stuck.
This is the code for the animation
public void setGlowAnimation(){
System.out.println("WIDTH "+width.getValue());
KeyValue value = new KeyValue(glowshape.centerXProperty(),width.getValue(),Interpolator.EASE_OUT);
KeyFrame keyframe1 = new KeyFrame(Duration.millis(2000),value);
glow_timeline = new Timeline();
glow_timeline.setCycleCount(Timeline.INDEFINITE);
glow_timeline.setAutoReverse(true);
glow_timeline.getKeyFrames().add(keyframe1);
}
public void init(){
indetermination();
setStartAnimation();
createEllipse();
width = new SimpleDoubleProperty();
width.bind(this.widthProperty());
setGlowAnimation();
}
I don't think you can modify a Timeline while it is active like that. Consider using a Transition instead:
import javafx.animation.Animation;
import javafx.animation.Interpolator;
import javafx.animation.Transition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class AdaptiveAnimation extends Application {
#Override
public void start(Stage primaryStage) {
Circle circle = new Circle(0, 100, 25, Color.CORNFLOWERBLUE);
Pane pane = new Pane(circle);
Interpolator interp = Interpolator.EASE_BOTH ;
Transition transition = new Transition() {
{
setCycleDuration(Duration.millis(2000));
}
#Override
protected void interpolate(double frac) {
double x = interp.interpolate(0, pane.getWidth(), frac);
circle.setCenterX(x);
}
};
transition.setCycleCount(Animation.INDEFINITE);
transition.setAutoReverse(true);
Scene scene = new Scene(pane, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
transition.play();
}
public static void main(String[] args) {
launch(args);
}
}
This is a little jumpy while you're resizing the window, but it provides the basic idea.

java - images in javafx

I am still pretty new to java and i am still learning. I have never used images before so it is possible if I can have help add a image. I am not that sure what needs to be done in order to add one. Thank you
enter image description here
here is the code:
import javafx.application.Application;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
class User {
private StringProperty order = new SimpleStringProperty();
public String getOrder() {
return order.get();
}
public void setOrder(String order) {
this.order.set(order);
}
public StringProperty orderProperty() {
return order;
}
}
public class pizza extends Application {
private User user = new User();
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("Pizza System");
Button btn = new Button();
btn.setText("place order");
BorderPane pane = new BorderPane();
pane.setBottom(btn);
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
btn.setText("Order has been placed. Please wait at least 30 minutes.");
}
});
RadioButton tomatoButton = new RadioButton("Tomato");
RadioButton pepperButton = new RadioButton("Pepper");
RadioButton mushroomButton = new RadioButton("Mushrooms");
ChoiceBox<String> pizzaType = new ChoiceBox<String>();
pizzaType.getItems().addAll("", "Small", "Medium", "Large");
pizzaType.getSelectionModel().selectFirst();
HBox topHBox = new HBox(15.0, tomatoButton, pepperButton, mushroomButton, pizzaType);
// create custom Binding that binds selection of radio buttons and choice box
StringBinding orderBinding = createOrderBinding(tomatoButton.selectedProperty(), pepperButton.selectedProperty(), mushroomButton.selectedProperty(), pizzaType.getSelectionModel().selectedItemProperty());
// bind orderBinding to orderProperty of User
user.orderProperty().bind(orderBinding);
TextArea orderArea = new TextArea();
// bind orderProperty of User to textProperty of TextArea
orderArea.textProperty().bindBidirectional(user.orderProperty());
BorderPane root = new BorderPane();
root.setTop(topHBox);
root.setCenter(orderArea);
root.setBottom(btn);
Scene scene = new Scene(root, 400, 300);
stage.setScene(scene);
stage.show();
}
public StringBinding createOrderBinding(BooleanProperty tomato, BooleanProperty pepper, BooleanProperty mushroom, ReadOnlyObjectProperty<String> selectedPizzaType) {
StringBinding binding = new StringBinding() {
{
// bind 4 provided properties.
super.bind(tomato, pepper, mushroom, selectedPizzaType);
}
#Override
protected String computeValue() {
StringBuilder sb = new StringBuilder("Pizza content:\n");
if (tomato.get())
sb.append("\tTomato\n");
if (pepper.get())
sb.append("\tPepper\n");
if (mushroom.get())
sb.append("\tMushroom\n");
sb.append("Pizza type:\n").append("\t" + selectedPizzaType.get());
return sb.toString();
}
};
return binding;
}
public static void main(String[] args) {
Application.launch(args);
}
}
JavaFX uses an Image to load the image file and it has a node called ImageView to place that image on the screen graph.
Considering that the image is present at the same location as your class file, you can use this:
// Load Image
Image image = new Image(getClass().getResource("image.jpg").toExternalForm());
// Set the Image on the ImageView
ImageView imageView = new ImageView(image);
// specify a size
imageView.setFitWidth(200);
imageView.setFitHeight(200);
// Place ImageView in a container
root.setRight(imageView);

Animate images from array in javafx pane to scroll seamless in clip window

I am creating slot machine application with javafx. Desired behavior: separated pictures have to appear in pane as real slot machine drum during animation (pictures of cherry, lemon, number sever and etc should look like one whole peace for user) like showing on picture.
slot machine
My problem is I can't put together separate images to scrolling in slot machine window seamless.
I have made a lot of search about this problem but didn't find any working solutions. I have tried to add all images in ArrayList and then set them as node to TranslateTransition reference during animation process. But initial image stack in windows.
import javafx.animation.Interpolator;
import javafx.animation.ParallelTransition;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class TestClass extends Application {
private BorderPane borderPane = new BorderPane();
private GridPane gridPane = new GridPane();
#Override
public void start(Stage primaryStage) throws Exception {
ImageView image1 = new ImageView(createImage(Color.RED));
ImageView image2 = new ImageView(createImage(Color.GREEN));
ImageView image3 = new ImageView(createImage(Color.BLUE));
gridPane.setLayoutX(50);
gridPane.setLayoutY(50);
gridPane.setPadding(new Insets(5, 5, 5, 5));
gridPane.setAlignment(Pos.CENTER);
gridPane.setVgap(5);
gridPane.add(image1, 0, 0);
gridPane.add(image2, 1, 0);
gridPane.add(image3, 2, 0);
gridPane.setMaxWidth(image1.getFitWidth() * 3);
gridPane.setMaxHeight(image1.getFitHeight());
Rectangle clip = new Rectangle(732, 230);
clip.setLayoutX(30);
clip.setLayoutY(10);
clip.setStroke(Color.BLACK);
// clip.setFill(null);
gridPane.setClip(clip);
borderPane.setCenter(gridPane);
Scene scene = new Scene(borderPane, 900, 500);
primaryStage.setScene(scene);
primaryStage.setTitle("SlotMachine");
primaryStage.show();
ImageView[] images = { image1, image2, image3 };
TranslateTransition t1 = new TranslateTransition();
for (ImageView i : images) {
t1.setDuration(Duration.millis(2000));
t1.setNode(i);
t1.setFromX(image1.getX());
t1.setFromY(image1.getY() - gridPane.getHeight());
t1.setToX(image1.getX());
t1.setToY(image1.getY() - image1.getFitHeight() / 2 + gridPane.getHeight());
t1.setCycleCount(2);
t1.setAutoReverse(false);
t1.setInterpolator(Interpolator.LINEAR);
}
TranslateTransition t2 = new TranslateTransition();
for (ImageView i : images) {
t2.setDuration(Duration.millis(2000));
t2.setNode(i);
t2.setFromX(image2.getX());
t2.setFromY(image2.getY() - gridPane.getHeight());
t2.setToX(image2.getX());
t2.setToY(image2.getY() - image2.getFitHeight() / 2 + gridPane.getHeight());
t2.setCycleCount(2);
t2.setAutoReverse(false);
t2.setInterpolator(Interpolator.LINEAR);
}
TranslateTransition t3 = new TranslateTransition();
for (ImageView i : images) {
t3.setDuration(Duration.millis(2000));
t3.setNode(i);
t3.setFromX(image3.getX());
t3.setFromY(image3.getY() - gridPane.getHeight());
t3.setToX(image3.getX());
t3.setToY(image3.getY() - image3.getFitHeight() / 2 + gridPane.getHeight());
t3.setCycleCount(2);
t3.setAutoReverse(false);
t3.setInterpolator(Interpolator.LINEAR);
}
ParallelTransition pt = new ParallelTransition(t2, t3, t1);
pt.play();
}
private final Image createImage(Color color) {
Rectangle rect = new Rectangle(32, 32);
rect.setFill(color);
return rect.snapshot(null, null);
}
public static void main(String[] args) {
launch(args);
}
}
Please help. Thank you in advance
From what I can tell, it doesn't look like you are using Model/View/Controller architecture; using this architecture is the easiest way (in my opinion) to implement a gui like this. In your case, you could model your logic from the following psuedo-code:
In Controller:
//changes x or y coordinate (depending on direction of movement) of top left corner
//the controller should change the values of x or y that are stored in your model
moveImageMethod(image);
In View:
//Number of ms between timer events, play with this number to make it smooth
private static final int TIMER_INTERVAL = 1000/30;
//constructor
public View(){
<your other stuff, event handlers, etc.>
this.timer = new Timer(TIMER_INTERVAL, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
handleTimerTick();
}
});
}
// Start the animation timer.
public void startTimer() {
timer.start();
}
protected void handleTimerTick(){
controller.moveImageMethod(image);
<other stuff you might need/want>
repaint();
}
<your graphics methods>

Javafx Listview Add and edit element

i want to add and edit directly an element to a listview :
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package javafx_test;
import java.util.Observable;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.TextFieldListCell;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;
/**
*
* #author karim
*/
public class Javafx_test extends Application {
#Override
public void start(Stage primaryStage) {
ObservableList<String> items = FXCollections.observableArrayList("test1", "test2");
ListView<String> list = new ListView<>(items);
list.setEditable(true);
list.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
#Override
public ListCell<String> call(ListView<String> param) {
return new TextFieldListCell<>(new StringConverter<String>() {
#Override
public String toString(String object) {
return object;
}
#Override
public String fromString(String string) {
return string;
}
});
}
});
Button btn = new Button();
btn.setText("Add String");
btn.setOnAction((ActionEvent event) -> {
String c = new String("test");
list.getItems().add(list.getItems().size(), c);
list.scrollTo(c);
list.edit(list.getItems().size() - 1);
});
VBox root = new VBox(list, btn);
Scene scene = new Scene(root);
primaryStage.setTitle("test!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Everything seems correct but that not working, it like its try to modify the first item not the newly added item in the last index, i don't know why
That's a bug.
There seems to be some truly horrible interplay between focus and editing. The basic problem seems to be that when a list cell loses focus, it cancels any editing. I think that by clicking on the button, you cause the focus to shift to that button, and then on the next rendering pulse the list cell sees it has lost focus and cancels editing. I can't quite explain why the first item in the list appears to go to an editing state, but I suspect it is due to some further interaction with the list's focusModel, which manages focus of individual items.
For a truly ugly hack, use an AnimationTimer to delay the call to ListView.edit(...) by an additional rendering frame. (In case you're not familiar with it, an AnimationTimer defines a handle(...) method that is invoked once on each rendering pulse; here I just count one frame and then call edit, and stop the timer.)
btn.setOnAction((ActionEvent event) -> {
String c = "test"+(list.getItems().size()+1);
list.getItems().add(list.getItems().size(), c);
list.scrollTo(list.getItems().size() - 1);
// list.edit(list.getItems().size() - 1);
new AnimationTimer() {
int frameCount = 0 ;
#Override
public void handle(long now) {
frameCount++ ;
if (frameCount > 1) {
list.edit(list.getItems().size() - 1);
stop();
}
}
}.start();
});
Calling scrollTo(...) with an index instead of an item seems more robust too (especially as you have items in there that are equal to each other :).)
Maybe someone else can come up with something a bit cleaner that this...
The issue seems to be the Cells not being updated before calling edit. Since updating the cells is done during layout, calling layout before starting the edit should fix the issue:
Example:
#Override
public void start(Stage primaryStage) {
ListView<String> listView = new ListView<>();
listView.setEditable(true);
listView.setCellFactory(TextFieldListCell.forListView());
Button editButton = new Button("Add & Edit");
editButton.setOnAction((ActionEvent event) -> {
listView.getItems().add("");
listView.scrollTo(listView.getItems().size() - 1);
listView.layout();
listView.edit(listView.getItems().size() - 1);
});
Scene scene = new Scene(new VBox(listView, editButton));
primaryStage.setScene(scene);
primaryStage.show();
}
What James_D already mentioned: It seems that the index for the edit method is calculated wrong. In the following example it should not grab the correct index, but it does.
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.TextFieldListCell;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ListEdit extends Application {
int i = 3;
#Override
public void start(Stage primaryStage) {
ObservableList<String> items = FXCollections.observableArrayList("test1", "test2");
ListView<String> list = new ListView<>(items);
list.setCellFactory(TextFieldListCell.forListView());
list.setEditable(true);
Button btn = new Button();
btn.setText("Add String");
btn.setOnAction((ActionEvent event) -> {
list.getItems().add(i - 1, "test" + i);
list.edit(i - 2);
i++;
});
VBox root = new VBox(list, btn);
Scene scene = new Scene(root);
primaryStage.setTitle("test!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Categories