in attachments i have put an image of my project , in essence I want to draw in a canvas different kind of shape like a line,circle,rectangle ,triangle ecc when i click the relative button, I'm new on the javafx programming , and for now what i have understand it is that the canvas can only modify in the main Thread of the GUI ,and this is the problem , because when i handle the button event "SetonAction" i need a reference of the main canvas to draw line or cirlce ecc. I have try with a new Thread but without success.
If anyone Know a way to do this , i really appricieted.Thanks in adviceenter image description here
For me it was difficult resolve this issue, so I have done a little simplyfy code to understand how the things works , take a look to this:
public class TE1 extends Application {
private Pane root;
private Pane left;
private StackPane right;
private StackPane drawcontainer;
private CustomizedButton btn;
private CustomizedButton btn1;
private Canvas Drawtable;
private SplitPane divisor;
private double x;
private double y;
private double to_x = 0;
private double to_y = 0;
private int line_no = 1;
#Override
public void start(Stage primaryStage) {
root = new StackPane();
Drawtable = new Canvas(400,400);
Drawtable.setWidth(400);
Drawtable.setHeight(400);
GraphicsContext gc = Drawtable.getGraphicsContext2D();
gc.setFill(Color.CADETBLUE);
gc.fillRect(0, 0, 800, 850);
left = new Pane();
left.setMinSize(400,400);
left.setStyle("-fx-background-color:#d7d6d5;");
right= new StackPane();
right.setAlignment(Pos.CENTER);
// right.setStyle("-fx-background-color: #FFFFFF;");
right.setMinSize(400, 400);
divisor = new SplitPane();
//root.addEventFilter(DrawEvent.DRAW_TYPE,new DrawEventHandler());
//root.addEventHandler(DrawEvent.DRAW_TYPE,new DrawEventHandler());
Drawtable.addEventFilter(DrawEvent.DRAW_TYPE,new DrawEventHandler());
// right.getChildren().add(Drawtable);
btn = new CustomizedButton();
btn1= new CustomizedButton();
btn.Set_identity("linea");
btn1.setMinSize(50,50);
btn.setMinSize(50,50);
btn.setMaxSize(50, 50);
btn.setLayoutX(100);
btn.setLayoutY(100);
btn1.setLayoutX(100);
btn1.setLayoutY(180);
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
this.fireEvent();
}
public void fireEvent()
{
Runnable task = ()-> runTask();
Thread background = new Thread(task);
background.setDaemon(true);
background.start();
}
public void runTask()
{
while(btn.isFocused()){
System.out.println("SONO ATTIVO ");
Drawtable.setOnMousePressed((event) ->setFromPos(event));
System.out.println("x vale :"+x+"y vale: "+y);
Drawtable.setOnMouseDragged((event)->
{
right.getChildren().remove(0);
Canvas temp_canvas = new Canvas(400, 400);
GraphicsContext gc = temp_canvas.getGraphicsContext2D();
gc.setFill(Color.BLUEVIOLET);
// setToPos(event);
// drawLine(gc);
right.getChildren().add(0,temp_canvas);
});
Drawtable.setOnMouseReleased((event) -> {
final Canvas new_line = new Canvas(400, 400);
final GraphicsContext gc = new_line.getGraphicsContext2D();
setToPos(event);
drawLine(gc);
//final new stright line
right.getChildren().add(line_no++,new_line);
});
}
}
});
right.getChildren().addAll( new Canvas(), Drawtable);
left.getChildren().add(btn);
left.getChildren().add(btn1);
divisor.getItems().addAll(left,right);
root.getChildren().addAll(divisor);
Scene scene = new Scene(root, 800, 850);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
private void setFromPos(MouseEvent event) {
this.x = event.getX();
this.y = event.getY();
}
private void setToPos(MouseEvent event) {
this.to_x = event.getX();
this.to_y = event.getY();
}
private void drawLine(GraphicsContext gc) {
gc.setFill(Color.RED);
gc.setStroke(Color.BLACK);
gc.setLineWidth(1);
gc.strokeLine(x, y, to_x, to_y);
}
}
Thanks in advice
Using multi-threading here is not necessary and not a good idea either.
Registering event handlers is not a long-running operation and reassigning anonymus classes with the same logic over and over again won't change a thing. Furthermore those modifications need to happen from the JavaFX application thread.
Another issue that should be mentioned is that you're recreating the Canvas during the mouse gesture. You should avoid doing this and instead reuse the existing Canvas. Stacking one Canvas per line should also be avoided. If you need a canvas for the currently drawn line and one for the completed lines that's 2 Canvases. Using Lines would be simpler to implement btw.
Also I recommend ToggleButton for this kind of task. This allows you to access a state independend of the focus. Instead of querying the state repeatedly you should listen to the property (whether you're using selected or focused to add/remove listeners):
private Pane root;
private Pane left;
private StackPane right;
private Button btn1;
private Canvas Drawtable;
private Canvas drawingCanvas;
private GraphicsContext drawingContext;
private SplitPane divisor;
#Override
public void start(Stage primaryStage) {
root = new StackPane();
Drawtable = new Canvas(400, 400);
Drawtable.setWidth(400);
Drawtable.setHeight(400);
// second Canvas for drawing stacked on top of the other canvas
drawingCanvas = new Canvas(Drawtable.getWidth(), Drawtable.getHeight());
drawingContext = drawingCanvas.getGraphicsContext2D();
left = new Pane();
left.setMinSize(400, 400);
left.setStyle("-fx-background-color:#d7d6d5;");
right = new StackPane(Drawtable, drawingCanvas);
right.setAlignment(Pos.CENTER);
right.setStyle("-fx-background-color: #FFFFFF;");
right.setMinSize(400, 400);
divisor = new SplitPane();
ToggleButton btn = new ToggleButton();
btn1 = new Button();
btn.setText("linea");
btn1.setMinSize(50, 50);
btn.setMinSize(50, 50);
btn.setMaxSize(50, 50);
btn.setLayoutX(100);
btn.setLayoutY(100);
btn1.setLayoutX(100);
btn1.setLayoutY(180);
btn.selectedProperty().addListener(new ChangeListener<Boolean>() {
private double x;
private double y;
private void drawLine(GraphicsContext gc, double endX, double endY) {
gc.setStroke(Color.BLACK);
gc.setLineWidth(1);
gc.strokeLine(x, y, endX, endY);
}
private final EventHandler<MouseEvent> pressedHandler = (event) -> {
x = event.getX();
y = event.getY();
};
private final EventHandler<MouseEvent> draggedHandler = (event) -> {
// remove old content & draw new content
drawingContext.clearRect(0, 0, drawingCanvas.getWidth(), drawingCanvas.getHeight());
drawLine(drawingContext, event.getX(), event.getY());
};
private final EventHandler<MouseEvent> releasedHandler = (event) -> {
// clear canvas for line drawing
drawingContext.clearRect(0, 0, drawingCanvas.getWidth(), drawingCanvas.getHeight());
// draw line on background canvas
final GraphicsContext gc = Drawtable.getGraphicsContext2D();
drawLine(gc, event.getX(), event.getY());
};
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
// add/remove event handlers based on toggle state of the button
if (newValue) {
drawingCanvas.addEventHandler(MouseEvent.MOUSE_PRESSED, pressedHandler);
drawingCanvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, draggedHandler);
drawingCanvas.addEventHandler(MouseEvent.MOUSE_RELEASED, releasedHandler);
} else {
drawingCanvas.removeEventHandler(MouseEvent.MOUSE_PRESSED, pressedHandler);
drawingCanvas.removeEventHandler(MouseEvent.MOUSE_DRAGGED, draggedHandler);
drawingCanvas.removeEventHandler(MouseEvent.MOUSE_RELEASED, releasedHandler);
}
}
});
left.getChildren().add(btn);
left.getChildren().add(btn1);
divisor.getItems().addAll(left, right);
root.getChildren().addAll(divisor);
Scene scene = new Scene(root, 800, 850);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
i have succesfully in some way , i have modify the code like this:
public class TE1 extends Application {
private Pane root;
private Pane left;
private StackPane right;
private StackPane drawcontainer;
private CustomizedButton btn;
private CustomizedButton btn1;
private Canvas Drawtable;
private SplitPane divisor;
private double x;
private double y;
private double to_x = 0;
private double to_y = 0;
private int line_no = 1;
private Thread background;
#Override
public void start(Stage primaryStage) {
root = new StackPane();
Drawtable = new Canvas(400,400);
Drawtable.setWidth(400);
Drawtable.setHeight(400);
GraphicsContext gc = Drawtable.getGraphicsContext2D();
left = new Pane();
left.setMinSize(400,400);
left.setStyle("-fx-background-color:#d7d6d5;");
right= new StackPane();
right.setAlignment(Pos.CENTER);
right.setStyle("-fx-background-color: #FFFFFF;");
right.setMinSize(400, 400);
divisor = new SplitPane();
btn = new CustomizedButton();
btn1= new CustomizedButton();
btn.Set_identity("linea");
btn1.setMinSize(50,50);
btn.setMinSize(50,50);
btn.setMaxSize(50, 50);
btn.setLayoutX(100);
btn.setLayoutY(100);
btn1.setLayoutX(100);
btn1.setLayoutY(180);
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
this.fireEvent();
}
public void fireEvent()
{
Runnable task = ()-> runTask();
Thread background = new Thread(task);
background.setDaemon(true);
background.start();
}
public void runTask()
{
while(btn.isFocused()){
System.out.println("SONO ATTIVO ");
Drawtable.setOnMousePressed((event) ->setFromPos(event));
System.out.println("x vale :"+x+"y vale: "+y);
Drawtable.setOnMouseDragged((event)->
{
right.getChildren().remove(0);
Canvas temp_canvas = new Canvas(400, 400);
GraphicsContext gc = temp_canvas.getGraphicsContext2D();
setToPos(event);
drawLine(gc);
right.getChildren().add(0,temp_canvas);
});
Drawtable.setOnMouseReleased((event) -> {
final Canvas new_line = new Canvas(400, 400);
final GraphicsContext gc = new_line.getGraphicsContext2D();
setToPos(event);
drawLine(gc);
//final new stright line
right.getChildren().add(line_no++,new_line);
});
}
System.out.println("Focused btn state :"+btn.isFocused());
background.interrupt();
}
});
right.getChildren().addAll( new Canvas(), Drawtable);
left.getChildren().add(btn);
left.getChildren().add(btn1);
divisor.getItems().addAll(left,right);
root.getChildren().addAll(divisor);
Scene scene = new Scene(root, 800, 850);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
private void setFromPos(MouseEvent event) {
this.x = event.getX();
this.y = event.getY();
}
private void setToPos(MouseEvent event) {
this.to_x = event.getX();
this.to_y = event.getY();
}
private void drawLine(GraphicsContext gc) {
gc.setFill(Color.RED);
gc.setStroke(Color.BLACK);
gc.setLineWidth(1);
gc.strokeLine(x, y, to_x, to_y);
}
}
but now i can't understand the reason that when the button isn't focused dosen't stop
draw line on the canvas..any suggestion??
Related
I've been trying to create a program that displays a ball in the center of a window, with 4 buttons titled Up, Down, Left and Right at the bottom. When you press the buttons the ball moves in the corresponding direction. I've got that part figured out, but I also need to figure out how to make it so if making the ball go in a certain direction obscures it from view, it stops it from going in that direction. I need to find a way to detect the boundaries of the window, and stopping the ball from being able to go outside of the boundary. Here's what I have so far:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class Ball extends Application {
private BallControl circle = new BallControl();
#Override
public void start(Stage primaryStage) {
HBox pane = new HBox();
pane.setSpacing(10);
pane.setAlignment(Pos.CENTER);
Button btUp = new Button("UP");
Button btDown = new Button("DOWN");
Button btLeft = new Button("LEFT");
Button btRight = new Button("RIGHT");
pane.getChildren().add(btLeft);
pane.getChildren().add(btRight);
pane.getChildren().add(btUp);
pane.getChildren().add(btDown);
BorderPane borderPane = new BorderPane();
borderPane.setCenter(circle);
borderPane.setBottom(pane);
BorderPane.setAlignment(pane, Pos.CENTER);
btUp.setOnAction(new UpHandler());
btDown.setOnAction(new DownHandler());
btLeft.setOnAction(new LeftHandler());
btRight.setOnAction(new RightHandler());
Scene scene = new Scene(borderPane, 250, 250);
primaryStage.setTitle("Ball"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show();
}
class UpHandler implements EventHandler<ActionEvent> {
public void handle(ActionEvent e) {
circle.up();
System.out.println("Up Button Pressed");
}
}
class DownHandler implements EventHandler<ActionEvent> {
public void handle(ActionEvent e) {
circle.down();
System.out.println("Down Button Pressed");
}
}
class LeftHandler implements EventHandler<ActionEvent> {
public void handle(ActionEvent e) {
circle.left();
System.out.println("Left Button Pressed");
}
}
class RightHandler implements EventHandler<ActionEvent> {
public void handle(ActionEvent e) {
circle.right();
System.out.println("Right Button Pressed");
}
}
public static void main(String[] args) {
launch(args);
}
}
class BallControl extends Pane {
public final double radius = 20;
private double x = radius, y = radius;
private double dx = 1, dy = 1;
private Circle circle = new Circle();
public BallControl() {
getChildren().add(circle);
circle.setCenterX(125.0f);
circle.setCenterY(115.0f);
circle.setRadius(25.0f);
circle.setStroke(Color.BLACK);
circle.setFill(Color.WHITE);
}
protected void moveBall() {
// Check boundaries
if (x < radius || x > getWidth() - radius) {
dx = 0; // Change ball move direction
}
if (y < radius || y > getHeight() - radius) {
dy = 0; // Change ball move direction
}
// Adjust ball position
x += dx;
y += dy;
circle.setCenterX(x);
circle.setCenterY(y);
}
public void up() {
circle.setCenterY(circle.getCenterY() - 10);
}
public void down() {
circle.setCenterY(circle.getCenterY() + 10);
}
public void left() {
circle.setCenterX(circle.getCenterX() - 10);
}
public void right() {
circle.setCenterX(circle.getCenterX() + 10);
}
}
Here is the part that I was hoping would make the program check for boundaries, but it doesn't seem to work:
protected void moveBall() {
// Check boundaries
if (x < radius || x > getWidth() - radius) {
dx = 0; // Change ball move direction
}
if (y < radius || y > getHeight() - radius) {
dy = 0; // Change ball move direction
}
// Adjust ball position
x += dx;
y += dy;
circle.setCenterX(x);
circle.setCenterY(y);
Someone else already asked a very similar question How to make the ball bounce off the walls in JavaFX?
Nevertheless, all you were missing was a check method before making the next move. I added moveAcceptable() and deleted BallControl for simplicity.
public class Ball extends Application
{
Circle circle = new Circle();
Pane bc = new Pane();
public BorderPane borderPane;
#Override
public void start(Stage primaryStage)
{
bc.getChildren().add(circle);
circle.setCenterX(125.0f);
circle.setCenterY(115.0f);
circle.setRadius(25.0f);
circle.setStroke(Color.BLACK);
circle.setFill(Color.WHITE);
HBox pane = new HBox();
pane.setSpacing(10);
pane.setAlignment(Pos.CENTER);
Button btUp = new Button("UP");
Button btDown = new Button("DOWN");
Button btLeft = new Button("LEFT");
Button btRight = new Button("RIGHT");
pane.getChildren().add(btLeft);
pane.getChildren().add(btRight);
pane.getChildren().add(btUp);
pane.getChildren().add(btDown);
borderPane = new BorderPane();
borderPane.setCenter(bc);
borderPane.setBottom(pane);
BorderPane.setAlignment(pane, Pos.CENTER);
btUp.setOnAction(new UpHandler());
btDown.setOnAction(new DownHandler());
btLeft.setOnAction(new LeftHandler());
btRight.setOnAction(new RightHandler());
Scene scene = new Scene(borderPane, 250, 250);
primaryStage.setTitle("Ball"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show();
}
class UpHandler implements EventHandler<ActionEvent>
{
public void handle(ActionEvent e)
{
if (moveAcceptable("up"))
circle.setCenterY(circle.getCenterY() - 10);
System.out.println("Up Button Pressed");
}
}
class DownHandler implements EventHandler<ActionEvent>
{
public void handle(ActionEvent e)
{
if (moveAcceptable("Down"))
circle.setCenterY(circle.getCenterY() + 10);
System.out.println("Down Button Pressed");
}
}
class LeftHandler implements EventHandler<ActionEvent>
{
public void handle(ActionEvent e)
{
if (moveAcceptable("Left"))
circle.setCenterX(circle.getCenterX() - 10);
System.out.println("Left Button Pressed");
}
}
class RightHandler implements EventHandler<ActionEvent>
{
public void handle(ActionEvent e)
{
if (moveAcceptable("Right"))
circle.setCenterX(circle.getCenterX() + 10);
System.out.println("Right Button Pressed");
}
}
public boolean moveAcceptable(String direction)
{
final Bounds bounds = borderPane.getLayoutBounds();
if (direction.equalsIgnoreCase("up"))
{
return (circle.getCenterY() > (bounds.getMinY() + circle.getRadius()));
} else if (direction.equalsIgnoreCase("down"))
{
return circle.getCenterY() < (bounds.getMaxY() - circle.getRadius());
} else if (direction.equalsIgnoreCase("right"))
{
return circle.getCenterX() < (bounds.getMaxX() - circle.getRadius());
} else //left
{
return circle.getCenterX() > (bounds.getMinX() + circle.getRadius());
}
}
public static void main(String[] args)
{
launch(args);
}
}
i have some problem with this method. it works fine, but with one little problem. there is too little time among i call this method. so only the last String is printed on a label. but i want that the next String starting printed, only after previous String is finished.
Sorry for my English((
public void some(final String s) {
final Animation animation = new Transition() {
{
setCycleDuration(Duration.millis(2000));
}
protected void interpolate(double frac) {
final int length = s.length();
final int n = Math.round(length * (float) frac);
javafx.application.Platform.runLater(new Runnable() {
#Override
public void run() {
status.setValue(s.substring(0, n));
}
}
);
}
};
animation.play();
}
Use the following code to get a typewriting effect.
public void AnimateText(Label lbl, String descImp) {
String content = descImp;
final Animation animation = new Transition() {
{
setCycleDuration(Duration.millis(2000));
}
protected void interpolate(double frac) {
final int length = content.length();
final int n = Math.round(length * (float) frac);
lbl.setText(content.substring(0, n));
}
};
animation.play();
}
I don't know if it is an effect that you are trying to achieve, but I have created (ugly) demo how you can do this with TimeLine
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
IntegerProperty letters= new SimpleIntegerProperty(0);
Label label = new Label();
Button animate = new Button("animate");
letters.addListener((a, b, c) -> {
label.setText("animate".substring(0, c.intValue()));
});
animate.setOnAction((e)->{
Timeline timeline = new Timeline();
KeyValue kv = new KeyValue(letters, "animate".length());
KeyFrame kf = new KeyFrame(Duration.seconds(3), kv);
timeline.getKeyFrames().add(kf);
timeline.play();
});
BorderPane pane = new BorderPane(label, null, null, animate, null);
primaryStage.setScene(new Scene(pane, 300,300));
primaryStage.show();
}
}
I am working on a basic Java FX task exercise. It counts from 1 to 150 on a thread. The current value is presented on a label and updates a progress bar.
There is a button to start the task, to cancel it and to view canceled status of the task.
The thing that puzzles me is as to why I cannot re run the task after having canceled the thread once(same thing happens if I let the task finnish).
I want to be able to rerun the task . Then I need to make it so that it will resume(though that shouldn't be that hard after figuring out how to rerun the task)
Source ;
public class JavaFX_Task extends Application {
#Override
public void start(Stage primaryStage) {
final Task task;
task = new Task<Void>() {
#Override
protected Void call() throws Exception {
int max = 150;
for (int i = 1; i <= max; i++) {
if (isCancelled()) {
break;
}
updateProgress(i, max);
updateMessage(String.valueOf(i));
Thread.sleep(100);
}
return null;
}
};
ProgressBar progressBar = new ProgressBar();
progressBar.setProgress(0);
progressBar.progressProperty().bind(task.progressProperty());
Label labelCount = new Label();
labelCount.textProperty().bind(task.messageProperty());
final Label labelState = new Label();
Button btnStart = new Button("Start Task");
btnStart.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
new Thread(task).start();
}
});
Button btnCancel = new Button("Cancel Task");
btnCancel.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
task.cancel();
}
});
Button btnReadTaskState = new Button("Read Task State");
btnReadTaskState.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
labelState.setText(task.getState().toString());
}
});
VBox vBox = new VBox();
vBox.setPadding(new Insets(5, 5, 5, 5));
vBox.setSpacing(5);
vBox.getChildren().addAll(
progressBar,
labelCount,
btnStart,
btnCancel,
btnReadTaskState,
labelState);
StackPane root = new StackPane();
root.getChildren().add(vBox);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("java-buddy.blogspot.com");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The Task documentation is pretty clear on this.
As with FutureTask, a Task is a one-shot class and cannot be reused. See Service for a reusable Worker.
There is an example of restartable concurrent services in the Service documentation.
I am using a progressbar in a tableview, where I'm using bind on his property so that when the value is changed, progressbar is started:
private SimpleDoubleProperty progressBar;
public Tabela(Double progressBar) {
this.progressBar = new SimpleDoubleProperty(progressBar);
}
public Double getProgressBar() {
return progressBar.get();
}
public DoubleProperty getProgressBarProperty() {
return progressBar;
}
public void setProgressBar(Double progressBar) {
this.progressBar.set(progressBar);
}
public void setProgressBar(SimpleDoubleProperty progressBar) {
this.progressBar = progressBar;
}
And in my Hbox am using progressbar as follows:
final ProgressBar progress = new ProgressBar();
progress.setMinWidth(324.0);
progress.progressProperty().bind(tabela.getProgressBarProperty());
So I'm using a so that after a certain time the value is changed, ie I will control the progressbar. The value is changed, but in my tableview nothing happens, but when I change the column position to another, the progressbar is running.
The same happens with "label", i changed for "text" and it work, but if the progressbar I have to use.
have a way to force the 'tableview' refresh?
You need to follow the JavaFX naming standard to get TableViews and other widgets to properly refresh when an observable object changes. For instance, you should rename getProgressBarProperty() to progressBarProperty().
See: How to update TableView Row using javaFx
There would be something wrong in this source?
class table
...
public Tabela(String nome, Double progressBar, String etapa) {
this.nome = nome;
this.progressBar = new SimpleDoubleProperty(progressBar);
this.etapa = new SimpleStringProperty(etapa);
}
....
Add new line.
private void preencheListaNomeTabelas() {
getLista().add(new Tabela("Test", 0.0, "Test Text"));
Add hbox in table.
columTabela.setCellValueFactory(new PropertyValueFactory<Tabela, String>("nome"));
columSituacao.setCellFactory(new Callback<TableColumn<Tabela, Double>, TableCell<Tabela, Double>>() {
public TableCell<Tabela, Double> call(TableColumn<Tabela, Double> p) {
final HBox box = new HBox();
box.setPrefHeight(25.0);
final ProgressBar progressBar = new ProgressBar(-1);
final Text text = new Text();
**text.textProperty().bind(..); //I would use here the**
BorderPane border = new BorderPane();
border.setTop(text);
border.setBottom(progressBar);
BorderPane.setAlignment(text, Pos.CENTER);
box.getChildren().add(border);
final TableCell cell = new TableCell<Tabela, Double>() {
#Override
protected void updateItem(Double t, boolean bln) {
super.updateItem(t, bln);
if (bln) {
setText(null);
setGraphic(null);
} else {
progressBar.setProgress(t);
progressBar.prefWidthProperty().bind(this.widthProperty());
setGraphic(box);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
};
cell.setAlignment(Pos.CENTER);
return cell;
}
});
columSituacao.setCellValueFactory(new PropertyValueFactory<Tabela, Double>("progress"));
columSituacao.setText("Progresso");
tableView.getItems().addAll(lista);
tableView.getSelectionModel().selectFirst();
task
Task t = new Task() {
#Override
protected Object call() throws Exception {
Thread.sleep(10000);
getLista().get(0).setEtapa("Lendo PostgreSQL");
getLista().get(0).setProgressBar(-1.0);
return null;
}
};
new Thread(t).start();
I am trying to display three images in sequence with some scale transformation to each of them(images of 1,2,3). I am using ScaleTransition on single instance of imageview, after each successive transformation the imageView height get scaled which is not resetting
My Code is
public void start(Stage primaryStage) {
final IntegerProperty intProperty = new SimpleIntegerProperty(0);
final Image[] array = {
(new Image(WaitEffect.class.getResource("1.png")
.toExternalForm())),
(new Image(WaitEffect.class.getResource("2.png")
.toExternalForm())),
(new Image(WaitEffect.class.getResource("3.png")
.toExternalForm())) };
Group root = new Group();
Scene scene = new Scene(root, 400, 400, Color.BLACK);
StackPane pane = StackPaneBuilder.create()
.layoutX(scene.getWidth() / 2).layoutY(scene.getHeight() / 2)
.build();
final ImageView imageView = new ImageView();
pane.getChildren().add(imageView);
Timeline timeline = new Timeline();
int count = 0;
KeyValue value = new KeyValue(intProperty, count++);
KeyFrame frame = new KeyFrame(Duration.millis(2000),
new EventHandler<ActionEvent>() {
int co = 0;
#Override
public void handle(ActionEvent paramT) {
imageView.setImage(array[co]);
ScaleTransition st = ScaleTransitionBuilder.create()
.byX(2).byY(2).node(imageView)
.duration(Duration.millis(500)).build();
st.play();
imageView.setFitHeight(150);
imageView.setFitWidth(150);
imageView.resize(150, 150);
co++;
}
}, value);
timeline.getKeyFrames().add(frame);
timeline.setCycleCount(3);
timeline.play();
root.getChildren().addAll(pane);
primaryStage.setScene(scene);
primaryStage.show();
}`
ImageView doesn't reset it's properties after setting new Image. You need to reset it yourself, e.g. by setting from properties of ScaleTransition:
ScaleTransition st = ScaleTransitionBuilder.create()
.fromX(1).fromY(1)
.byX(2).byY(2).node(imageView)
.duration(Duration.millis(500)).build();