Removing node at particular column of GridPane with mousepress - javafx

I am trying to remove multiple nodes, one at a time, from a GridPane by first getting the coordinates on mousepress, then using gridpane.getChildren().remove(column) using column as the index to remove. This works as expected if I start with an arbitrary index and then mousepress on a lesser valued index, however it does not work if I try to mousepress on a greater valued index, the mousepress value retains the previous value of the node.
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DominoMain extends Application {
GridPane humanHand = new GridPane();
ImageView imageView;
int column;
#Override
public void start(Stage primaryStage) throws Exception {
AnchorPane root = new AnchorPane();
List<ImageView> tiles = new ArrayList<>();
String[] imageResources = new String[] {
"00.jpg", "10.jpg", "11.jpg", "20.jpg", "21.jpg", "22.jpg",
"30.jpg", "31.jpg", "32.jpg", "33.jpg", "40.jpg", "41.jpg",
"42.jpg", "43.jpg", "44.jpg", "50.jpg", "51.jpg", "52.jpg",
"53.jpg", "54.jpg", "55.jpg", "60.jpg", "61.jpg", "62.jpg",
"63.jpg", "64.jpg", "65.jpg", "66.jpg"};
for(final String imageResource : imageResources) {
imageView = new ImageView(imageResource);
imageView.setFitWidth(50);
imageView.setFitHeight(26);
tiles.add(imageView);
}
//Assign mouse press handler.
for (ImageView imageView :
tiles) {
imageView.setOnMousePressed(this::onPress);
}
Collections.shuffle(tiles);
for (int i = 0; i < 7; i++) {
GridPane.setHalignment(tiles.get(0), HPos.CENTER);
humanHand.add(tiles.remove(0), i, 0);
}
humanHand.setOnMousePressed(event -> {
System.out.printf("Index to be removed %d \n", column);
humanHand.getChildren().remove(column);
});
humanHand.setAlignment(Pos.BOTTOM_CENTER);
AnchorPane.setBottomAnchor(humanHand, 25.0);
AnchorPane.setLeftAnchor(humanHand, 0.0);
AnchorPane.setRightAnchor(humanHand, 0.0);
root.getChildren().addAll(humanHand);
primaryStage.setScene(new Scene(root, 800, 350));
primaryStage.show();
}
//Handler for mouse press event.
private void onPress(MouseEvent event) {
column = GridPane.getColumnIndex((Node) event.getSource());
int row = GridPane.getRowIndex((Node) event.getSource());
System.out.printf("Node clicked at: column=%d, row=%d \n", column, row);
System.out.println(humanHand.getChildren().get(column));
}
}
Any help would be appreciated.

Just keep track of which ImageView is clicked on, instead of which column:
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DominoMain extends Application {
GridPane humanHand = new GridPane();
private ImageView clickedImage ;
#Override
public void start(Stage primaryStage) throws Exception {
AnchorPane root = new AnchorPane();
List<ImageView> tiles = new ArrayList<>();
String[] imageResources = new String[] {
"00.jpg", "10.jpg", "11.jpg", "20.jpg", "21.jpg", "22.jpg",
"30.jpg", "31.jpg", "32.jpg", "33.jpg", "40.jpg", "41.jpg",
"42.jpg", "43.jpg", "44.jpg", "50.jpg", "51.jpg", "52.jpg",
"53.jpg", "54.jpg", "55.jpg", "60.jpg", "61.jpg", "62.jpg",
"63.jpg", "64.jpg", "65.jpg", "66.jpg"};
for(final String imageResource : imageResources) {
ImageView imageView = new ImageView(imageResource);
imageView.setFitWidth(50);
imageView.setFitHeight(26);
tiles.add(imageView);
}
//Assign mouse press handler.
for (ImageView imageView :
tiles) {
imageView.setOnMousePressed(e -> clickedImage = imageView);
}
Collections.shuffle(tiles);
for (int i = 0; i < 7; i++) {
GridPane.setHalignment(tiles.get(0), HPos.CENTER);
humanHand.add(tiles.remove(0), i, 0);
}
humanHand.setOnMousePressed(event -> {
if (clickedImage != null) {
humanHand.getChildren().remove(clickedImage);
}
});
humanHand.setAlignment(Pos.BOTTOM_CENTER);
AnchorPane.setBottomAnchor(humanHand, 25.0);
AnchorPane.setLeftAnchor(humanHand, 0.0);
AnchorPane.setRightAnchor(humanHand, 0.0);
root.getChildren().addAll(humanHand);
primaryStage.setScene(new Scene(root, 800, 350));
primaryStage.show();
}
}

Related

why does while() loop not work on pathTransition?

I've been trying to make my pathTransition loop but it doesn't work. I have already tried with a while loop but nothing happens. "boom" runs the path once and then stops. I would like the "boom" to choose a new path each time.
int i = 1;
while(i < 5){
Path path = new Path();
double x = (new Random().ints(-100,400 + 1).iterator().next());
path.getElements().add (new MoveTo (x, -190));
path.getElements().add (new LineTo(x, 300));
PathTransition pathTransition = new PathTransition();
pathTransition.setDuration(Duration.millis(10000));
pathTransition.setNode(boom);
pathTransition.setPath(path);
pathTransition.setOrientation(OrientationType.NONE);
pathTransition.setAutoReverse(false);
pathTransition.play();
i++;
You want to add all your PathTransitions to a SequentialTransition like this:
import java.util.Random;
import javafx.animation.PathTransition;
import javafx.animation.SequentialTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.stage.Stage;
import javafx.util.Duration;
public class PathLoop extends Application {
Node boom;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
Button goButton = new Button("Go");
goButton.setOnAction(this::doAnimation);
boom = new Circle(20, Color.RED);
AnchorPane playfield = new AnchorPane(boom);
playfield.setPrefSize(600, 600);
AnchorPane.setLeftAnchor(boom, 100.0);
AnchorPane.setTopAnchor(boom, 300.0);
VBox root = new VBox(goButton, playfield);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("Sequential Transition");
primaryStage.show();
}
private void doAnimation(ActionEvent e) {
Random rng = new Random();
SequentialTransition seqTransition = new SequentialTransition(boom);
int i = 1;
while(i < 5){
Path path = new Path();
double x = (rng.ints(-100,400 + 1).iterator().next());
path.getElements().add (new MoveTo(x, -190));
path.getElements().add (new LineTo(x, 300));
PathTransition pathTransition = new PathTransition();
pathTransition.setDuration(Duration.millis(10000));
pathTransition.setNode(boom);
pathTransition.setPath(path);
pathTransition.setOrientation(PathTransition.OrientationType.NONE);
pathTransition.setAutoReverse(false);
seqTransition.getChildren().add(pathTransition);
i++;
}
seqTransition.play();
}
}

Add FreeHand functionality in JavaFX

Actually I am making an application which allows user to crop an image an then gives functionality of free-hand drawing and to also to draw different shapes. I have achieved functionality of cropping and drawing shapes like line etc. But I am facing some problems in free-hand drawing.
I have added my image on "HBox" and cropped that image through "Rectangle" in JavaFX class which is added on "Group". And all these are added on "Pane" class. Now for free-hand drawing, I am using "Canvas". Where to add canvas, whether on "HBox" or "Group" or "Pane" class. And Canvas is only initialized on clicking pencil button. I have added single functions for Mouse-Events and applied if-checks for different functionalities in those functions.
basically how to draw pencil on image or how to add lineTo on group.
Can someone please help me in solving my problem??
`
package application;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.imageio.ImageIO;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.scene.Cursor;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.Rectangle;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
public class Main extends Application {
int dragStatus = 0;
double startingPointX;
double startingPointY;
double currentEndingPointX;
double currentEndingPointY;
BufferedImage bufferedImage;
Robot robot;
ImageView imageView;
Button pencilBtn;
Image image;
Pane rootPane;
HBox pictureRegion;
Scene scene;
Rectangle croppedArea;
Canvas canvas;
GraphicsContext gc;
WritableImage writableImage;
Group group = new Group();
Line line;
LineTo lineTo;
String shape;
Boolean canvasAdded;
#Override
public void start(Stage primaryStage) {
try {
int sleepTime = 120;
Thread.sleep(sleepTime);
pencilBtn = createButton("save.png");
pictureRegion = new HBox();
rootPane = new Pane();
scene = new Scene(rootPane);
robot = new Robot();
java.awt.Rectangle capture = new java.awt.Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
bufferedImage = robot.createScreenCapture(capture);
image = ConvertBufferedToJavaFXImage.convertToFxImage(bufferedImage);
pencilBtn.setOnAction(e -> geometrySelection("pencil"));
croppedArea = new Rectangle();
if(canvas != null) {
canvas.setOnMousePressed(e -> onMousePressed(e));
canvas.setOnMousePressed(e -> onMouseDragged(e));
}
imageView = new ImageView(image);
scene.setOnMouseEntered(e -> onMouseEntered(e, "scene"));
scene.setOnMousePressed(e -> onMousePressed(e));
scene.setOnMouseReleased(e -> onMouseReleased(e));
scene.setOnMouseDragged(e -> onMouseDragged(e));
pictureRegion.getChildren().add(imageView);
rootPane.getChildren().add(pictureRegion);
rootPane.getChildren().add(group);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setMaximized(true);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public void onMouseEntered(MouseEvent ev, String nodeType) {
if (nodeType == "scene") {
scene.setCursor(Cursor.CROSSHAIR);
} else if (nodeType == "croppedArea") {
croppedArea.setCursor(Cursor.TEXT);
//croppedArea.setOnMousePressed(e -> onMousePressed(e));
} else if (nodeType == "btn") {
pencilBtn.setCursor(Cursor.HAND);
}
}
public void onMousePressed(MouseEvent event) {
if ((startingPointX < event.getX() && event.getX() < currentEndingPointX)
&& (startingPointY < event.getY() && event.getY() < currentEndingPointY)) {
if(shape == "pencil") {
lineTo = new LineTo();
System.out.println("lineTo1");
gc.beginPath();
gc.lineTo(event.getX(), event.getY());
gc.stroke();
}
} else {
shape = "croppedArea";
rootPane.getChildren().remove(canvas);
group.getChildren().clear();
startingPointX = event.getX();
startingPointY = event.getY();
group.getChildren().add(croppedArea);
}
}
public void onMouseDragged(MouseEvent event) {
dragStatus = 1;
if (dragStatus == 1) {
// if((startingPointX < event.getX() && event.getX() < currentEndingPointX)
// && (startingPointY < event.getY() && event.getY() < currentEndingPointY)) {
if(shape == "pencil") {
System.out.println("lineTo1");
gc.lineTo(event.getX(), event.getY());
gc.stroke();
}
else {
currentEndingPointX = event.getX();
currentEndingPointY = event.getY();
rootPane.getChildren().remove(pencilBtn);
croppedArea.setFill(Color.TRANSPARENT);
croppedArea.setStroke(Color.BLACK);
croppedArea.setOnMouseEntered(e -> onMouseEntered(e, "croppedArea"));
adjustRectangleProperties(startingPointX, startingPointY, currentEndingPointX, currentEndingPointY,
croppedArea);
}
}
}
public void geometrySelection(String tempShape) {
if(tempShape == "pencil") {
shape = "pencil";
canvas = new Canvas();
gc = canvas.getGraphicsContext2D();
//gc.setFill(Color.LIGHTGRAY);
gc.setStroke(Color.BLACK);
gc.setLineWidth(5);
canvas.setLayoutX(startingPointX);
canvas.setLayoutY(startingPointY);
canvas.setWidth(croppedArea.getWidth());
canvas.setHeight(croppedArea.getHeight());
System.out.println("canvasAdded");
group.getChildren().add(canvas);
}
}
public void onMouseReleased(MouseEvent event) {
if(dragStatus == 1) {
if(shape == "croppedArea") {
if (croppedArea.getHeight() > 0 && croppedArea.getWidth() > 0) {
pencilBtn.setLayoutX(Math.max(startingPointX, currentEndingPointX) + 5);
pencilBtn.setLayoutY(Math.max(startingPointY, currentEndingPointY) - 120);
rootPane.getChildren().add(pencilBtn);
dragStatus = 0;
}
}
bufferedImage = robot.createScreenCapture(new java.awt.Rectangle((int) startingPointX, (int) startingPointY,
(int) croppedArea.getWidth(), (int) croppedArea.getHeight()));
}
}
void adjustRectangleProperties(Double startingPointX, Double startingPointY, Double currentEndingPointX,
Double currentEndingPointY, Rectangle givenRectangle) {
givenRectangle.setX(startingPointX);
givenRectangle.setY(startingPointY);
givenRectangle.setWidth(currentEndingPointX - startingPointX);
givenRectangle.setHeight(currentEndingPointY - startingPointY);
if (givenRectangle.getWidth() < 0) {
givenRectangle.setWidth(-givenRectangle.getWidth());
givenRectangle.setX(givenRectangle.getX() - givenRectangle.getWidth());
}
if (givenRectangle.getHeight() < 0) {
givenRectangle.setHeight(-givenRectangle.getHeight());
givenRectangle.setY(givenRectangle.getY() - givenRectangle.getHeight());
}
}
public Button createButton(String imageName) throws FileNotFoundException {
FileInputStream iconFile = new FileInputStream(imageName);
Image iconImage = new Image(iconFile);
Button button = new Button();
button.setGraphic(new ImageView(iconImage));
button.setMaxSize(20, 20);
button.setPadding(Insets.EMPTY);
return button;
}
public static void main(String[] args) {
launch(args);
}
}
`

JavaFX, text won't display in TextArea

I have the majority of the program done, the only problem is getting the numbers to display in the TextArea. Write a program that lets the user enter numbers from a graphical user interface and displays them in a text area. Use a LinkedList to store the numbers. Don't duplicate numbers. Add sort, shuffle, reverse to sort the list.
package storedInLinkedList;
import java.util.Collections;
import java.util.LinkedList;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.control.ScrollPane;
public class StoredInLinkedList extends Application{
TextField txt = new TextField();
TextArea tArea = new TextArea();
Label message = new Label("Enter a Number: ");
Button sort = new Button("Sort");
Button shuffle = new Button("Shuffle");
Button reverse = new Button("Reverse");
private LinkedList<Integer> list = new LinkedList<>();
#Override
public void start(Stage primaryStage){
BorderPane bPane = new BorderPane();
txt.setAlignment(Pos.TOP_RIGHT);
bPane.setCenter(txt);
bPane.setBottom(tArea);
HBox hBox = new HBox(message, txt);
bPane.setTop(hBox);
HBox buttons = new HBox(10);
buttons.getChildren().addAll(sort, shuffle, reverse);
bPane.setBottom(buttons);
buttons.setAlignment(Pos.CENTER);
VBox vBox = new VBox();
vBox.getChildren().addAll(hBox, tArea, buttons);
bPane.setCenter(new ScrollPane(tArea));
Scene scene = new Scene(vBox, 300,250);
primaryStage.setTitle("20.2_DSemmes");
primaryStage.setScene(scene);
primaryStage.show();
txt.setOnAction(e -> {
if(! list.contains(new Integer(txt.getText()))){
tArea.appendText(txt.getText() + " ");
list.add(new Integer(txt.getText()));
}//end if
});//end action
sort.setOnAction(e -> {
Collections.sort(list);
display();
});//end action
shuffle.setOnAction(e -> {
Collections.shuffle(list);
display();
});//end action
reverse.setOnAction(e -> {
Collections.reverse(list);
display();
});//end action
}//end stage
private void display() {
for (Integer i: list){
tArea.setText(null);
tArea.appendText(i + " ");
}//end for
}//end display
public static void main(String[] args) {
// TODO Auto-generated method stub
launch(args);
}//end main
}//end class
Put the textarea clearing code outside of for loop. Otherwise you are clearing the previously appended text, so textarea having only the last element of list:
private void display() {
tArea.setText(""); // clear text area
for (Integer i: list){
tArea.appendText(i + " ");
}//end for
}/

Refresh label in JAVAFX

So i have this code in which i'm trying to do a scene for my game. I'm really a beginner in a Java and especially JAVAFX world and doing this as a school project (Once again..) and trying to figure out a way to refresh my label.
I've found one URL from stackoverflow, which was a similar issue but didn't work for my problem (or was i too stupid to make it work..) anyways, link is here
This is the part where the problem occurs - i have a text box, from which you have to enter player names. Every time a user inputs player name the label shows how many names have been entered, according to the nimedlist.size() which holds the names inside.
Label mängijate_arv = new Label("Mängijaid on sisestatud: "+nimedlist.size());
// if we press enter, program will read the name
nimiTekst.setOnKeyPressed(new EventHandler<KeyEvent>() {
public void handle(final KeyEvent keyEvent) {
if (keyEvent.getCode() == KeyCode.ENTER) {
if (nimiTekst.getText() != null) {
nimedlist.add(nimiTekst.getText());
nimiTekst.setText(null);
}
}
}
});
startBox.getChildren().addAll(sisestus_mängijad, nimiTekst, mängijate_arv,
startButton2);
This is the whole code:
package application;
import java.util.ArrayList;
import javafx.application.Application;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
public class Baila2 extends Application {
public static void main(String[] args) {
launch(args);
}
public void start(final Stage peaLava) {
final Group root = new Group();
final BorderPane piir = new BorderPane();
piir.setPrefSize(960, 540);
final Text tekst = new Text();
tekst.setText("JOOMISMÄNG");
tekst.setFont(Font.font("Verdana", 40));
VBox nupudAlam = new VBox();
Button startButton = new Button("Start");
nupudAlam.setSpacing(20);
Button reeglidButton = new Button("Reeglid");
nupudAlam.setAlignment(Pos.CENTER);
startButton.setId("btn3");
startButton.setMaxWidth(160);
reeglidButton.setMaxWidth(160);
reeglidButton.setId("btn3");
nupudAlam.getChildren().addAll(startButton, reeglidButton);
piir.setTop(tekst);
piir.setAlignment(tekst, Pos.CENTER);
piir.setCenter(nupudAlam);
root.getChildren().add(piir);
// START NUPP TÖÖ
startButton.setOnAction(new EventHandler<ActionEvent>() {
public void handle(final ActionEvent event) {
final ArrayList nimedlist = new ArrayList();
piir.setVisible(false);
final BorderPane startPiir = new BorderPane();
final VBox startBox = new VBox();
Button startButton2 = new Button("ALUSTA!");
startButton2.setId("btn2");
startButton2.setMaxWidth(160);
startPiir.setPrefSize(960, 540);
final Text startTekst = new Text();
startTekst.setText("JOOMISMÄNG");
startTekst.setFont(Font.font("Verdana", 40));
startPiir.setTop(startTekst);
startPiir.setAlignment(startTekst, Pos.CENTER);
final TextField nimiTekst = new TextField();
nimiTekst.setText(null);
nimiTekst.setMaxWidth(250);
Label sisestus_mängijad = new Label(
"Sisesta 3-9 mängija nimed:");
sisestus_mängijad.setFont(Font.font("Verdana", 30));
sisestus_mängijad.setTextFill(Color.ORANGE);
Label mängijate_arv = new Label("Mängijaid on sisestatud: "+nimedlist.size());
// kui vajutatakse ENTER,siis loeme nime
nimiTekst.setOnKeyPressed(new EventHandler<KeyEvent>() {
public void handle(final KeyEvent keyEvent) {
if (keyEvent.getCode() == KeyCode.ENTER) {
if (nimiTekst.getText() != null) {
nimedlist.add(nimiTekst.getText());
nimiTekst.setText(null);
}
}
}
});
startBox.getChildren().addAll(sisestus_mängijad, nimiTekst, mängijate_arv,
startButton2);
startBox.setSpacing(20);
startBox.setAlignment(Pos.CENTER);
startPiir.setCenter(startBox);
root.getChildren().add(startPiir);
}
});
// aknasündmuse lisamine
peaLava.setOnHiding(new EventHandler<WindowEvent>() {
public void handle(WindowEvent event) {
// luuakse teine lava
final Stage kusimus = new Stage();
// küsimuse ja kahe nupu loomine
Label label = new Label("Kas tõesti tahad kinni panna?");
Button okButton = new Button("Jah");
Button cancelButton = new Button("Ei");
// sündmuse lisamine nupule Jah
okButton.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
kusimus.hide();
}
});
// sündmuse lisamine nupule Ei
cancelButton.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
peaLava.show();
kusimus.hide();
}
});
// nuppude grupeerimine
FlowPane pane = new FlowPane(10, 10);
pane.setAlignment(Pos.CENTER);
pane.getChildren().addAll(okButton, cancelButton);
// küsimuse ja nuppude gruppi paigutamine
VBox vBox = new VBox(10);
vBox.setAlignment(Pos.CENTER);
vBox.getChildren().addAll(label, pane);
// stseeni loomine ja näitamine
Scene stseen2 = new Scene(vBox);
kusimus.setScene(stseen2);
kusimus.show();
}
}); // siin lõpeb aknasündmuse kirjeldus
// stseeni loomine ja näitamine
Scene stseen1 = new Scene(root, 960, 540, Color.GREEN);
peaLava.setTitle("BAILA 2.0");
// peaLava.setResizable(false);
stseen1.getStylesheets().add(
getClass().getClassLoader().getResource("test.css")
.toExternalForm());
peaLava.setScene(stseen1);
peaLava.show();
}
}
Sorry about Estonian language, it's compulsory in our school to write in our native language..
You can just do
nimiTekst.setOnKeyPressed(new EventHandler<KeyEvent>() {
public void handle(final KeyEvent keyEvent) {
if (keyEvent.getCode() == KeyCode.ENTER) {
if (nimiTekst.getText() != null) {
nimedlist.add(nimiTekst.getText());
nimiTekst.setText(null);
mängijate_arv.setText("Mängijaid on sisestatud: "+nimedlist.size());
}
}
}
});
If you are not using Java 8 (you appear not to be, since you are implementing all the handlers the old, long way...), you will have to declare mängijate_arv as final:
final Label mängijate_arv = new Label("Mängijaid on sisestatud: "+nimedlist.size());
If you want to be extra cool with this, you can use bindings instead. You will have to make nimidlist an observable list:
final ObservableList<String> nimedlist = FXCollections.observableArrayList();
and then:
mängijate_arv.bind(Bindings.format("Mängijaid on sisestatud: %d", Bindings.size(nimedList)));
and don't put the mängijate_arv.setText(...) call in the handler. This solution is nicer in many ways, as if you remove items from the list (or add other items elsewhere in your code), then the label will still remain properly updated without any additional code.
One other thing: it's a bit better to use an action handler on the text field, instead of a low-level key event handler:
nimiTekst.setOnAction(new EventHandler<ActionEvent>() {
public void handle(final ActionEvent keyEvent) {
if (nimiTekst.getText() != null) {
nimedlist.add(nimiTekst.getText());
nimiTekst.setText(null);
mängijate_arv.setText("Mängijaid on sisestatud: "+nimedlist.size());
}
}
});
(Sorry if I mangled your variable names. My Estonian is a bit weak ;). Your school's policy is a good one, for what it's worth.)

Drawing lines between Shapes laid out in HBox and VBox

I have a circle inside various containers (ScrollPane, Group, HBox and VBox)
I want to draw a line from 0,0 to the centre of the circle.
I think the code below shows the problem. There is some function unknown to me which should go
in //SOME CODE HERE TO WORK OUT WHERE THE CIRCLE IS to make it work
I have a sample application I wrote to simplify my problem.
import java.util.Random;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class TestAppForCoords extends Application {
//Scene Graph:
//ScrollPane - scroll
// - Group - root
// - HBox - hbox - with random padding
// - VBox
// - VBox - vbox - with random padding
// - Circle - circle
// - VBox
// - Group - lines
// - Line - line
#Override
public void start(final Stage primaryStage) throws Exception {
Random rand = new Random();
int randomNum1 = rand.nextInt((100 - 0) + 1) + 0;
int randomNum2 = rand.nextInt((100 - 0) + 1) + 0;
System.out.println(randomNum1);
System.out.println(randomNum2);
ScrollPane scroll = new ScrollPane();
scroll.setPrefSize(500, 300);
Scene scene = new Scene(scroll);
primaryStage.setScene(scene);
Group root = new Group();
HBox hbox = new HBox();
hbox.setPadding(new Insets(randomNum1));
VBox vbox = new VBox();
hbox.getChildren().add(new VBox());
vbox.setPadding(new Insets(randomNum2));
hbox.getChildren().add(vbox);
hbox.getChildren().add(new VBox());
Circle circle = new Circle();
circle.setRadius(10);
vbox.getChildren().add(circle);
Group lines = new Group();
root.getChildren().add(hbox);
root.getChildren().add(lines);
root.autosize();
Line line = new Line();
line.setStartX(0);
line.setStartY(0);
//SOME CODE HERE TO WORK OUT WHERE THE CIRCLE IS
line.setEndX(123);
line.setEndY(123);
lines.getChildren().add(line);
scroll.setContent(root);
primaryStage.show();
}
public static void main(String[] args) {
System.out.println("Start JavaFXTestApp");
launch(args);
System.out.println("End JavaFXTestApp");
}
}
Finally I have it working. I can add a setOnShown handler which is called to correct the line.
So I have found out that localToScene and sceneToLocal only work after the window is being displayed
primaryStage.setOnShown(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent arg0) {
Point2D p = circle.localToScene(circle.getCenterX(),circle.getCenterY());
p = line.sceneToLocal(p);
line.setEndX(p.getX());
line.setEndY(p.getY());
}
});
So the final working program is:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
public class TestAppForCoords extends Application {
//Scene Graph:
//ScrollPane - scroll
// - Group - root
// - VBox - vboxEXTRA - with random padding
// - HBox - hbox - with random padding
// - VBox
// - VBox - vbox - with random padding
// - Circle - circle
// - VBox
// - Group - lines
// - Line - line
Line line = new Line();
Circle circle = new Circle();
#Override
public void start(final Stage primaryStage) throws Exception {
Random rand = new Random();
int randomNum1 = rand.nextInt((100 - 0) + 1) + 0;
int randomNum2 = rand.nextInt((100 - 0) + 1) + 0;
int randomNum3 = rand.nextInt((100 - 0) + 1) + 0;
System.out.println(randomNum1);
System.out.println(randomNum2);
System.out.println(randomNum3);
ScrollPane scroll = new ScrollPane();
scroll.setPrefSize(500, 300);
Scene scene = new Scene(scroll);
primaryStage.setScene(scene);
Group root = new Group();
HBox hbox = new HBox();
hbox.setPadding(new Insets(randomNum1));
VBox vbox = new VBox();
hbox.getChildren().add(new VBox());
vbox.setPadding(new Insets(randomNum2));
hbox.getChildren().add(vbox);
hbox.getChildren().add(new VBox());
circle.setRadius(10);
vbox.getChildren().add(circle);
Group lines = new Group();
root.getChildren().add(hbox);
root.getChildren().add(lines);
root.autosize();
root.requestLayout();
lines.getChildren().add(line);
VBox vboxEXTRA = new VBox();
vboxEXTRA.setPadding(new Insets(randomNum3));
vboxEXTRA.getChildren().add(root);
scroll.setContent(vboxEXTRA);
line.setStartX(0);
line.setStartY(0);
//This dosen't work prob because we aren't drawing yet
Point2D p = circle.localToScene(circle.getCenterX(),circle.getCenterY());
p = line.sceneToLocal(p);
line.setEndX(p.getX());
line.setEndY(p.getY());
primaryStage.setOnShown(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent arg0) {
Point2D p = circle.localToScene(circle.getCenterX(),circle.getCenterY());
p = line.sceneToLocal(p);
line.setEndX(p.getX());
line.setEndY(p.getY());
}
});
primaryStage.show();
}
public static void main(String[] args) {
System.out.println("Start JavaFXTestApp");
launch(args);
System.out.println("End JavaFXTestApp");
}
}

Resources