I am new to Java and JavaFX so sorry if this question seems a bit obvious but it is doing my head in. I have tried googling solutions but haven't been able to find anything so far.
Basically I am trying to re-use some code in Java FX to hide / show some objects when a button is pressed. Rather than copy / paste the whole code again, I want to put it in a method (or something similar) that gets called on different occasions.
So here is a simple code example that I hope explains what I am trying to do:
package src;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class example extends Application
{
#Override
public void start(Stage stage)
{
Button b1 = new Button();
b1.setText("Show Label 1 Only");
Button b2 = new Button();
b2.setText("Show Label 2 Only");
Button b3 = new Button();
b3.setText("Show Label 2 and 3");
Label l1 = new Label();
l1.setText("Label 1");
Label l2 = new Label();
l2.setText("Label 2");
Label l3 = new Label();
l3.setText("Label 3");
b1.setOnAction(e ->
{
l1.setVisible(true);
l2.setVisible(false);
l3.setVisible(false);
});
b2.setOnAction(e ->
{
l1.setVisible(false);
l2.setVisible(true);
l3.setVisible(false);
});
b3.setOnAction(e ->
{
l1.setVisible(false);
l2.setVisible(true);
l3.setVisible(true);
});
VBox root = new VBox();
root.setSpacing(10);
root.setAlignment(Pos.CENTER);
l1.setVisible(false);
l2.setVisible(false);
l3.setVisible(false);
root.getChildren().addAll(b1, b2, b3, l1, l2, l3);
Scene scene = new Scene(root, 200, 200);
stage.setScene(scene);
stage.setTitle("Example");
stage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
As you can see, the first 2 lines of the code for B2 and B3 are the same, so it would be nice if I could just put these lines in a method that gets called in both scenarios. This is in essence what i am trying to achieve.
Any guidance would be much appreciated. Like I said, I'm new to JAVA / JAVAFX so sorry if it seems like an obvious question.
One simple way is to make the labels instance variables and just to define a method taking a boolean for each one, indicating if it should be visible:
public class Example extends Application {
private Label l1;
private Label l2;
private Label l3;
private void labelVisibility(boolean l1Visible, boolean l2Visible, boolean l3Visible) {
l1.setVisible(l1Visible);
l2.setVisible(l2Visible);
l3.setVisible(l3Visible);
}
#Override
public void start(Stage stage) {
Button b1 = new Button();
b1.setText("Show Label 1 Only");
Button b2 = new Button();
b2.setText("Show Label 2 Only");
Button b3 = new Button();
b3.setText("Show Label 2 and 3");
l1 = new Label();
l1.setText("Label 1");
l2 = new Label();
l2.setText("Label 2");
l3 = new Label();
l3.setText("Label 3");
b1.setOnAction(e -> labelVisibility(true, false, false));
b2.setOnAction(e -> labelVisibility(false, true, false));
b3.setOnAction(e -> labelVisibility(false, true, true));
VBox root = new VBox();
root.setSpacing(10);
root.setAlignment(Pos.CENTER);
labelVisibility(false, false, false);
root.getChildren().addAll(b1, b2, b3, l1, l2, l3);
Scene scene = new Scene(root, 200, 200);
stage.setScene(scene);
stage.setTitle("Example");
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
If you don't want to expand the scope of the labels (and want a bit more generality), your method can take a list of all the labels, and a list of the ones you want visible:
public class Example extends Application {
private void labelVisibility(List<Node> allNodes, Node... visibleNodes) {
List<Node> visibleNodeList = Arrays.asList(visibleNodes);
for (Node node : allNodes) {
node.setVisible(visibleNodeList.contains(node));
}
}
#Override
public void start(Stage stage) {
Button b1 = new Button();
b1.setText("Show Label 1 Only");
Button b2 = new Button();
b2.setText("Show Label 2 Only");
Button b3 = new Button();
b3.setText("Show Label 2 and 3");
Label l1 = new Label();
l1.setText("Label 1");
Label l2 = new Label();
l2.setText("Label 2");
Label l3 = new Label();
l3.setText("Label 3");
List<Node> allLabels = List.of(l1, l2, l3);
b1.setOnAction(e -> labelVisibility(allLabels, l1));
b2.setOnAction(e -> labelVisibility(allLabels, l2));
b3.setOnAction(e -> labelVisibility(allLabels, l2, l3));
VBox root = new VBox();
root.setSpacing(10);
root.setAlignment(Pos.CENTER);
labelVisibility(allLabels);
root.getChildren().addAll(b1, b2, b3, l1, l2, l3);
Scene scene = new Scene(root, 200, 200);
stage.setScene(scene);
stage.setTitle("Example");
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Related
Sorry, I have just begun learning javaFX and cannot figure out how to get all of my icons on buttons the same size. I tried a couple things but could not get it working, all help is appreciated. Thank you!
Wont let me post my question unless I add more details but I cant think of anything else to put so just ignore this whole paragraph as I ramble on so I can post my question and continue coding my game.
public class Main extends Application {
Stage window;
Button button;
Scene scene1, scene2;
public static final int ROCK = 0;
public static final int PAPER = 1;
public static final int SCISSORS = 2;
public static int userChoice;
public static void main(String [] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception
{
window = primaryStage;
//Layout 1
VBox layout = new VBox(20);
Label label = new Label("Rock Paper Scissors");
Button myButton = new Button("Start");
myButton.setOnAction(e -> window.setScene(scene2));
Button exit = new Button("Exit");
exit.setOnAction(e -> System.exit(0));
layout.getChildren().addAll(label, myButton, exit);
layout.setAlignment(Pos.CENTER);
scene1 = new Scene(layout, 300, 300);
//Layout 2
BorderPane border = new BorderPane();
VBox layout1 = new VBox(10);
Label label1 = new Label("Choose One");
layout1.setAlignment(Pos.CENTER);
//Layout 3
HBox layout2 = new HBox(10);
//Rock Image Button
Image rockIm = new Image(getClass().getResourceAsStream("Rock2.png"));
Button rock = new Button();
rock.setGraphic(new ImageView(rockIm));
rock.setOnAction(e -> userChoice = ROCK);
//Paper Image Button
Image paperIm = new
Image(getClass().getResourceAsStream("Paper2.png"));
Button paper = new Button();
paper.setGraphic(new ImageView(paperIm));
paper.setOnAction(e -> userChoice = PAPER);
//Scissor Image Button
Image scissorIm = new
Image(getClass().getResourceAsStream("Scissor2.png"));
Button scissors = new Button();
scissors.setGraphic(new ImageView(scissorIm));
scissors.setOnAction(e -> userChoice = SCISSORS);
Button quit = new Button("Return");
quit.setOnAction(e -> window.setScene(scene1));
layout2.getChildren().addAll(rock, paper, scissors, quit);
layout2.setAlignment(Pos.CENTER);
scene2 = new Scene(layout2, 300, 300);
window.setTitle("Rock Paper Scissors");
window.setScene(scene1);
window.show();
}
}
I want get data from Tab in Tabpane JavaFX
I have 2 Tab in Tabpane, And each Tab I have a TextArea, I want click Button will get data from 2 tab
Here's my code:
btnThem.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
try {
i++;
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("/fxml/tab.fxml"));
Parent parent = (Parent) fxmlLoader.load();
Tab tab = new Tab("Điểm " + i);
tab.setContent(parent);
tab.setClosable(true);
tabPane.getTabs().add(tab);
controllerTab = (ControllerTab) fxmlLoader.getController();
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
}
});
Your question is ambiguous but it seems you want to get data from each textArea in tab.To do this you should get nodes (children) from each tab and by using lookup() we confirm and we parse node to textArea.I tried to figure your scene and made this example to help you :
public class example extends Application {
TextArea textArea = new TextArea();
TextArea textArea1 = new TextArea();
Button button = new Button("button");
#Override
public void start(Stage primaryStage) {
Tab tab1 = new Tab("tab1");
Tab tab2 = new Tab("tab2");
tab1.setContent(textArea);
tab2.setContent(textArea1);
TabPane pane = new TabPane();
pane.getTabs().addAll(tab1, tab2);
Node node1 = tab1.getContent();
Node node2 = tab2.getContent();
button.setOnAction((ActionEvent event) -> {
if (node1.lookup("TextArea") != null && node2.lookup("TextArea") != null) {
TextArea area1 = (TextArea) node1.lookup("TextArea");
TextArea area2 = (TextArea) node2.lookup("TextArea");
System.out.println(area1.getText() + " " + area2.getText());
}
});
VBox root = new VBox();
root.setAlignment(Pos.TOP_RIGHT);
root.getChildren().add(pane);
root.getChildren().add(button);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
And you can see the result :
Hello ,tab1 Hello ,tab2
Deleting directory C:\Users\Electron\Documents\NetBeansProjects\Buttono\dist\run341573612
jfxsa-run:
BUILD SUCCESSFUL (total time: 22 seconds)
i am using a combobox to get data from the database on stage.show(), so far i can retrieve the data and also implement my changelistener on the combobox.
the problem is that i am getting ["example"] from the database instead of "example". its my first time of using javafx and don;t know how the output is supposed to look like, but this one is strange to me.
below is a screenshot of it and also my code
[http://i.stack.imgur.com/QWawZ.png]
package libman;
import java.sql.*;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.stage.*;
import javafx.scene.control.*;
import javafx.scene.text.*;
import javafx.collections.*;
/**
/**
*
* #author kels
*/
public class BorrowMenu extends Application {
private ObservableList<ObservableList> data;
DBOperator login;
ResultSet rs;
Statement stat;
private String getval;
#Override
#SuppressWarnings({"static-access", "Convert2Lambda"})
public void start(Stage primaryStage){
//define the UI elements
Label lblID = new Label("Name: ");
Label lblTitle = new Label("Book Title: ");
Label lblauthor = new Label("Author: ");
Label lblissue = new Label("Issue Date: ");
Label lblreturn = new Label("Return Date: ");
ComboBox title = new ComboBox();
TextField txtid = new TextField();
TextField txtitle = new TextField();
TextField txtauthor = new TextField();
TextField txtissue = new TextField();
TextField txtreturn = new TextField();
//set prompt text
txtid.setPromptText("Enter Borrower's Name");
txtitle.setPromptText("Enter Book Title");
txtauthor.setPromptText("Enter Author's Name");
txtissue.setPromptText("Enter Issue Date");
txtreturn.setPromptText("Enter Return Date");
title.setPromptText("Fills books from database");
//ToolTip ttip = new ToolTip("Back Menu");
Button btn = new Button("Borrow Book");
Button btnexit = new Button("Menu>>");
btnexit.setTooltip(new Tooltip("Back to Menu"));
//set the gripane to add in components
GridPane gridpane = new GridPane();
gridpane.setPadding(new Insets(20));
gridpane.setHgap(5);
gridpane.setVgap(5);
//set components
gridpane.setHalignment(lblID, HPos.RIGHT);
gridpane.add(lblID, 0,0);
gridpane.setHalignment(txtid, HPos.RIGHT);
gridpane.add(txtid,1,0);
gridpane.setHalignment(lblTitle, HPos.RIGHT);
gridpane.add(lblTitle, 0,1);
gridpane.setHalignment(title, HPos.RIGHT);
gridpane.add(title, 1,1);
gridpane.setHalignment(lblauthor, HPos.RIGHT);
gridpane.add(lblauthor, 0,2);
gridpane.setHalignment(txtauthor, HPos.RIGHT);
gridpane.add(txtauthor, 1,2);
gridpane.setHalignment(lblissue, HPos.RIGHT);
gridpane.add(lblissue, 0,3);
gridpane.setHalignment(txtissue, HPos.RIGHT);
gridpane.add(txtissue, 1,3);
gridpane.setHalignment(lblreturn, HPos.RIGHT);
gridpane.add(lblreturn, 0,4);
gridpane.setHalignment(txtreturn, HPos.RIGHT);
gridpane.add(txtreturn, 1,4);
gridpane.setHalignment(btn, HPos.RIGHT);
gridpane.add(btn, 1,5);
gridpane.setHalignment(btnexit, HPos.RIGHT);
gridpane.add(btnexit, 2,5);
//display the values from db to combobox on windows launch
data = FXCollections.observableArrayList();
primaryStage.setOnShowing(new EventHandler<WindowEvent>(){
#Override
public void handle(WindowEvent event){
try{
login = new DBOperator();
stat = login.getStatement();
rs=stat.executeQuery("SELECT * FROM BOOKDB");
while(rs.next()){
ObservableList<String> row =FXCollections.observableArrayList();
row.add(rs.getString("Title"));
// row.add(rs.getString("Author"));
data.add(row);
}
title.setItems(data);
rs.close();
}
catch(SQLException ex){
System.out.println("Driver Not Found!!!" + ex);
System.exit(0);
}
}
});
//add the gridpane to the stackpane
StackPane root = new StackPane();
root.getChildren().add(gridpane);
//title.setO
Scene scene = new Scene(root, 380,220);
primaryStage.setTitle("Borrow Menu");
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
//System.out.println(row);
//activate the combo listener at selection
title.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>(){
#Override
public void changed(ObservableValue<? extends Object> observable, Object oldvalue, Object newvalue){
System.out.println(newvalue.toString());
// txtauthor.setText(newvalue.toString());
}
});
}
public static void main(String [] args){
launch(args);
}
}
Please help thanks
You are getting the correct result for what you are actually doing: ObservableList<ObservableList> data bundles two collections.
For each item of the comboBox you will have a collection, so that's why you see "[ ]" when it is rendered.
This minimum sample reproduces your case:
#Override
public void start(Stage primaryStage) {
ComboBox title = new ComboBox();
StackPane root = new StackPane();
root.getChildren().add(title);
ObservableList<ObservableList> data = FXCollections.observableArrayList();
List<String> test = Arrays.asList("Test", "Example");
for(String s : test) {
ObservableList<String> row =FXCollections.observableArrayList();
row.add(s);
data.add(row);
}
title.setItems(data);
Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
with the same result you have:
You need to simplify your collection: ObservableList<String> data.
#Override
public void start(Stage primaryStage) {
ComboBox<String> title = new ComboBox();
StackPane root = new StackPane();
root.getChildren().add(title);
ObservableList<String> data = FXCollections.observableArrayList();
List<String> test = Arrays.asList("Test", "Example");
for(String s : test) {
data.add(s);
}
title.setItems(data);
Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
And you will have the expected result:
EDIT
In the case you want to add several items from the database to each item of the combo, you just need to provide a way to render the data, using ComboBox.setCellFactory(), so you can override the default method that produces the string [item1, item2, ... ].
I want the user to be able to drag-move the circles around the pane. The circles dont seem to register (almost) no mouse events (as defined in the end). I have the same exact code for an empty pane it works just fine. Also if I change
circle1.setOnMouseDragged
to
paneForCircles.setOnMouseDragged
it works just fine but its not what I want because I need to manipulate both circles. Any ideas ? I would appreciate it if you could also tell me how to hide the part of the circle that overlaps with the adjacent elements if its center is too close to the pane border.
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class Ex168 extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
Circle circle1 = new Circle(30);
Circle circle2 = new Circle(35);
circle1.setCenterX(100);
circle1.setCenterY(100);
circle2.setCenterX(150);
circle2.setCenterY(120);
circle1.setStroke(Color.BLACK);
circle1.setFill(null);
circle2.setStroke(Color.BLACK);
circle2.setFill(null);
VBox vBoxForScene = new VBox(5);
vBoxForScene.setPadding(new Insets(5));
vBoxForScene.setAlignment(Pos.TOP_CENTER);
Pane paneForCircles = new Pane();
paneForCircles.setStyle("-fx-border-color: black");
vBoxForScene.heightProperty().addListener(ov -> paneForCircles.setPrefHeight(vBoxForScene.heightProperty().divide(1.2).doubleValue()));
paneForCircles.setPrefHeight(300);
HBox hBoxForFields = new HBox(5);
hBoxForFields.setAlignment(Pos.CENTER);
hBoxForFields.setSpacing(5);
// VBofForLeftFields
VBox vBoxForLeftFields = new VBox(5);
vBoxForLeftFields.setAlignment(Pos.CENTER_LEFT);
Label lblCircle1 = new Label("Enter Circle 1 info");
lblCircle1.setAlignment(Pos.TOP_LEFT);
TextField tfCircle1CenterX = new TextField();
tfCircle1CenterX.textProperty().bind(circle1.centerXProperty().asString());
TextField tfCircle1CenterY = new TextField();
tfCircle1CenterY.textProperty().bind(circle1.centerYProperty().asString());
TextField tfCircle1Radius = new TextField();
tfCircle1Radius.textProperty().bind(circle1.radiusProperty().asString());
tfCircle1CenterX.setPrefColumnCount(5);
tfCircle1Radius.setPrefColumnCount(5);
tfCircle1CenterY.setPrefColumnCount(5);
Label lblCenterX = new Label("Center x:", tfCircle1CenterX);
Label lblCenterY = new Label("Center x:", tfCircle1CenterY);
Label lblCircle1Radius= new Label("Radius: ", tfCircle1Radius);
lblCenterX.setContentDisplay(ContentDisplay.RIGHT);
lblCenterY.setContentDisplay(ContentDisplay.RIGHT);
lblCircle1Radius.setContentDisplay(ContentDisplay.RIGHT);
//VBoxForRightFields
VBox vBoxForRightFields = new VBox(5);
Label lblCircle2 = new Label("Enter Circle 2 info");
TextField tfCircle2CenterX = new TextField();
TextField tfCircle2CenterY = new TextField();
TextField tfCircle2Radius = new TextField();
tfCircle2CenterX.setPrefColumnCount(5);
tfCircle2CenterX.textProperty().bind(circle2.centerXProperty().asString());
tfCircle2Radius.setPrefColumnCount(5);
tfCircle2Radius.textProperty().bind(circle2.radiusProperty().asString());
tfCircle2CenterY.setPrefColumnCount(5);
tfCircle2CenterY.textProperty().bind(circle2.centerYProperty().asString());
Label lblCenter2X = new Label("Center x:", tfCircle2CenterX);
Label lblCenter2Y = new Label("Center x:", tfCircle2CenterY);
Label lblCircle2Radius= new Label("Radius: ", tfCircle2Radius);
lblCenter2X.setContentDisplay(ContentDisplay.RIGHT);
lblCenter2Y.setContentDisplay(ContentDisplay.RIGHT);
lblCircle2Radius.setContentDisplay(ContentDisplay.RIGHT);
vBoxForRightFields.getChildren().addAll(lblCircle2, lblCenter2X, lblCenter2Y, lblCircle2Radius);
vBoxForLeftFields.getChildren().addAll(lblCircle1, lblCenterX, lblCenterY, lblCircle1Radius);
hBoxForFields.getChildren().addAll(vBoxForLeftFields, vBoxForRightFields);
Label lblResult = new Label("Do the two circles intersect?");
Button btReDrawCircles = new Button("Redraw Circles");
vBoxForScene.getChildren().addAll(lblResult, paneForCircles, hBoxForFields, btReDrawCircles);
circle1.setOnMouseDragged(e -> {
System.out.println(e.getX());
circle1.setCenterX(e.getX());
circle1.setCenterY(e.getY());
});
circle2.setOnMouseDragged(e -> {
circle2.setCenterX(e.getX());
circle2.setCenterY(e.getY());
});
paneForCircles.getChildren().addAll(circle1, circle2);
Scene scene = new Scene(vBoxForScene);
primaryStage.setScene(scene);
primaryStage.setMinHeight(400);
primaryStage.setMinWidth(340);
primaryStage.setAlwaysOnTop(true);
primaryStage.show();
circle1.requestFocus();
}
}
This code on the other hand, which is supposed to do the same thing, works perfectly
public class CircleDraggingSample extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
final double RADIUS=10;
Pane pane = new Pane();
pane.setPrefHeight(300);
pane.setPrefWidth(300);
Circle circle1 = new Circle(RADIUS);
circle1.setCenterX(30);
circle1.setCenterY(30);
Circle circle2 = new Circle(RADIUS);
circle2.setCenterX(100);
circle2.setCenterY(100);
Line line = new Line();
line.endXProperty().bind(circle2.centerXProperty());
line.endYProperty().bind(circle2.centerYProperty());
line.startXProperty().bind(circle1.centerXProperty());
line.startYProperty().bind(circle1.centerYProperty());
pane.getChildren().addAll(circle1, circle2, line);
circle2.setOnMouseDragged(e -> {
circle2.setCenterX(e.getX());
circle2.setCenterY(e.getY());
});
circle1.setOnMouseDragged(e -> {
circle1.setCenterX(e.getX());
circle1.setCenterY(e.getY());
});
Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.show();
}
}
Even though you have posted an example, I'd rather show you a way with mine how it is done in general. There are several ways, this is one that works:
public class DragNodes extends Application {
public static List<Circle> circles = new ArrayList<Circle>();
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
Group root = new Group();
Circle circle1 = new Circle( 100, 100, 50);
circle1.setStroke(Color.GREEN);
circle1.setFill(Color.GREEN.deriveColor(1, 1, 1, 0.3));
Circle circle2 = new Circle( 200, 200, 50);
circle2.setStroke(Color.BLUE);
circle2.setFill(Color.BLUE.deriveColor(1, 1, 1, 0.3));
Line line = new Line();
line.setStrokeWidth(20);
// binding
line.startXProperty().bind(circle1.centerXProperty());
line.startYProperty().bind(circle1.centerYProperty());
line.endXProperty().bind(circle2.centerXProperty());
line.endYProperty().bind(circle2.centerYProperty());
MouseGestures mg = new MouseGestures();
mg.makeDraggable( circle1);
mg.makeDraggable( circle2);
mg.makeDraggable( line);
root.getChildren().addAll(circle1, circle2, line);
primaryStage.setScene(new Scene(root, 1024, 768));
primaryStage.show();
}
public static class MouseGestures {
class DragContext {
double x;
double y;
}
DragContext dragContext = new DragContext();
public void makeDraggable( Node node) {
node.setOnMousePressed( onMousePressedEventHandler);
node.setOnMouseDragged( onMouseDraggedEventHandler);
node.setOnMouseReleased(onMouseReleasedEventHandler);
}
EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
if( event.getSource() instanceof Circle) {
Circle circle = ((Circle) (event.getSource()));
dragContext.x = circle.getCenterX() - event.getSceneX();
dragContext.y = circle.getCenterY() - event.getSceneY();
} else {
Node node = ((Node) (event.getSource()));
dragContext.x = node.getTranslateX() - event.getSceneX();
dragContext.y = node.getTranslateY() - event.getSceneY();
}
}
};
EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
if( event.getSource() instanceof Circle) {
Circle circle = ((Circle) (event.getSource()));
circle.setCenterX( dragContext.x + event.getSceneX());
circle.setCenterY( dragContext.y + event.getSceneY());
} else {
Node node = ((Node) (event.getSource()));
node.setTranslateX( dragContext.x + event.getSceneX());
node.setTranslateY( dragContext.y + event.getSceneY());
}
}
};
EventHandler<MouseEvent> onMouseReleasedEventHandler = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
}
};
}
}
It shows how to drag circles and bind another node (the line) so that it gets modified as well when you drag the circles. You can also drag the line separately which is a Node and handled differently.
In case you still got problems let me know.
As a general note, it's always advisable to add this to a node in order to understand which events happen:
node.addEventFilter(Event.ANY, e -> System.out.println( e));
and then check the console output while you do something on screen.
Regarding your main problem: You mustn't set Fill to null. In that case the click event won't get registered. You should use Color.TRANSPARENT instead. You can verify the event difference with the above mentioned method.
I have a small test a JButton in a SwingNode in a Stage, using Java 8.
Problem: right click is not triggered, the middle click is interpreted as right click ...
Here is the code:
Platform.runLater(new Runnable() {
#Override
public void run() {
HBox hb = new HBox();
SwingNode n = new SwingNode();
JButton b = new JButton("CLICK ME!!!");
b.addMouseListener(new MouseAdapter() {
public final void mousePressed(MouseEvent e) {
boolean isLeftClick = SwingUtilities.isLeftMouseButton(e);
boolean isRightClick = SwingUtilities.isRightMouseButton(e);
if (isLeftClick)
System.out.println("Left");
if (isRightClick)
System.out.println("Right");
}
});
n.setContent(b);
hb.getChildren().add(n);
Stage stage = new Stage();
Scene appScene = new Scene(hb,100, 100);
stage.setScene(appScene);
stage.show();
}
});