Java/JavaFX Event Handler and setFill() trouble - java

I was programming a game inspired by Conway's "Game of Life".
Although I have the overall game logic figured out (but not coded), I am still having trouble with getting the fill colors of my rectangle objects to change once the player's first turn is over. When I run my program it skips over the requirement for player one's color (Color.BLUE) and goes straight to player two's color (Color.RED).
Here is the code:
//William Fisher
//July.11.2017
package cellularautomatagame;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.canvas.*;
import javafx.scene.input.MouseEvent;
import static javafx.scene.paint.Color.*;
public class CellularAutomataGame extends Application {
#Override
public void start(Stage stage) {
Group root = new Group();
Scene s = new Scene(root, 300, 300, Color.BLACK);
Canvas canvas = new Canvas(1280,720);
GraphicsContext gc = canvas.getGraphicsContext2D();
root.getChildren().add(canvas);
stage.setScene(s);
stage.show();
gc.setFill(WHITE);
gc.fillRect(0, 0, 5, 720);
gc.fillRect(0, 0, 1280, 5);
gc.fillRect(0, 715, 1280, 5);
gc.fillRect(1275, 0, 5, 720);
Player player1 = new Player();
Player player2 = new Player();
player1.playerFirstMove(root,canvas,Color.BLUE);
player2.playerFirstMove(root,canvas,Color.RED);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
//William Fisher
// July.11.2017
package cellularautomatagame;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import static javafx.scene.paint.Color.*;
import javafx.scene.shape.Rectangle;
public class Player {
int firstMove = 0;
public void playerFirstMove(Group root,Canvas canvas,Color color){
canvas.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>(){
#Override
public void handle (MouseEvent e){
while(firstMove < 1){
if(e.getClickCount() == 1){
Rectangle r = new Rectangle(e.getX(),e.getY(),5,5);
r.setFill(color);
root.getChildren().add(r);
firstMove++;
}
}
}
});
firstMove--;
}
}
/** (07/11/2017)Current Problem: The first player is unable to make their first move. Only the
* second player is able to make a first move.
*
* (07/16/2017)Current Problem: Same as previous problem, changed the code so that a rectangle
* object would spawn upon mouse click event. Problem possibly has to do with "setFill()" function.
*/
On line 52 of the main JavaFX method where it shows player1's first turn, it should call the playerFirstMove method and allow a blue rectangle to spawn once the mouse is clicked, as shown in the playerFirstMove method starting on line 18 of the Player class. However when the mouse is clicked, one red rectangle is spawned instead of a blue one. It is as though the program skipped over player1.playerfirstMove(...) on line 52 and went straight to the player2.playerfirstMove(...) on line 53. I've tried for hours to fix this small problem, reading the JavaFX API and searching the internet. The program is doing what I want it to do (spawn only one rectangle per mouse click) but it seems as though it is skipping the instructions on line 52 (player1.playerfirstMove(...)).
To me it seems as though there may be a bug involving the setFill() function?
I would deeply appreciate any help.
Thanks All!

If I understand correctly every mouse click should draw a rectangle of the current player and pass turn to the next player. If so, I reworked your code to have Player with color and draw rectangle logic only:
class Player {
private final Color color;
Player(final Color color) {
this.color = color;
}
void doSomething(final Group root, final double x, final double y) {
Rectangle r = new Rectangle(x, y, 5, 5);
r.setFill(color);
root.getChildren().add(r);
}
}
In main class I have organized cycled iteration (by using Google guava collection utils) and the iterator allows to work only with the current player:
Player player1 = new Player(Color.BLUE);
Player player2 = new Player(Color.RED);
Player player3 = new Player(Color.YELLOW);
final Iterator<Player> playerIterator = Iterators.cycle(player1, player2, player3);
canvas.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> {
if (e.getClickCount() == 1) {
playerIterator.next().doSomething(root, e.getX(), e.getY());
}
});
As result I may have even 3 players and each click triggers only the next one:
BTW, this solution allows to have as many players as needed.

Related

Display ArrayList of shapes in pane (JavaFX)

I am writing a code that is a program that has a user create circles on the screen, based on where they click. What I have tried is to put the create new circle method in the first event handler but all it did was give me problems. As of now, I am trying to approach the problem differently. I am now using an ArrayList to group all the shapes together and display them on the pane. But the circles are not displaying when I run the code.
This is my code:
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
import java.util.ArrayList;
public class Main extends Application {
private Pane root;
private Circle circle;
private Line line;
private boolean isClicked = false;
private ArrayList<Circle> circleList;
#Override
public void start(Stage primaryStage) {
root = new Pane();
circle = new Circle();
line = new Line();
circleList = new ArrayList<Circle>();
root.getChildren().addAll(line);
//root.getChildren().addAll(circle); //when this is uncommented the program runs just fine but there is only one circle there at a time
root.getChildren().addAll(circleList); //I feel like the problem could be here?
root.setOnMousePressed(new mouseClick());
root.setOnMouseMoved(new moveMouse());
Scene scene = new Scene(root, 600, 600);
primaryStage.setTitle("blank");
primaryStage.setScene(scene);
primaryStage.show();
}
private double getRadius(double pointOnRadiusX, double pointOnRadiusY, double circleCenterX, double circleCenterY) {
return Math.sqrt(Math.pow(Math.abs(pointOnRadiusX) - Math.abs(circleCenterX), 2) + Math.pow(Math.abs(pointOnRadiusY) - Math.abs(circleCenterY), 2));
}
private class mouseClick implements EventHandler<MouseEvent> {
#Override
public void handle(MouseEvent e) {
if (!isClicked) {
if(e.getEventType() == MouseEvent.MOUSE_PRESSED){
circle.setRadius(0);
circle.setCenterX(e.getSceneX());
circle.setCenterY(e.getSceneY());
circle.setStroke(Color.RED);
circle.setFill(Color.TRANSPARENT);
line.setStartX(e.getSceneX());
line.setStartY(e.getSceneY());
line.setStroke(Color.RED);
isClicked = true;
circleList.add(circle);
}
}
else {
circle.setRadius(getRadius(e.getSceneX(),e.getSceneY(),circle.getCenterX(), circle.getCenterY()));
circle.setStroke(Color.GREEN);
line.setStroke(Color.TRANSPARENT);
isClicked = false;
}
}
}
private class moveMouse implements EventHandler <MouseEvent>{
#Override
public void handle(MouseEvent e) {
{
if (isClicked) {
circle.setRadius(getRadius(e.getSceneX(),e.getSceneY(),circle.getCenterX(), circle.getCenterY()));
line.setEndX(e.getSceneX());
line.setEndY(e.getSceneY());
}
}
}
}
public static void main(String[] args) {
Application.launch(args);
} }
When this code is executed:
root.getChildren().addAll(circleList);
The circleList is empty. Given that you later add to the circleList I'm going to assume you're under the impression that the addAll method somehow "links" the two lists together. It does not. All that method does is copy all the elements from one list and append them to the other. And note by "copy" I don't mean each element is duplicated; the elements added to the one list are the same instances as in the given list. But the lists themselves remain separate.
You also must make sure not to add the same Circle instance to the root more than once. A Node can only appear in the scene graph at most once. When the processes for adding a new circle is started you should be creating a new Circle object. The same goes for your Line if you plan to have multiple lines displayed.
Here's a working example (without your Line):
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class App extends Application {
private Pane root;
private Circle circle;
#Override
public void start(Stage primaryStage) {
root = new Pane();
root.setOnMousePressed(this::handleMousePressed);
root.setOnMouseMoved(this::handleMouseMoved);
primaryStage.setScene(new Scene(root, 1000.0, 650.0));
primaryStage.show();
}
private void handleMousePressed(MouseEvent e) {
if (e.getButton() == MouseButton.PRIMARY && e.getClickCount() == 1) {
if (circle == null) {
// start drawing a new circle
circle = new Circle(e.getX(), e.getY(), 0.0, Color.TRANSPARENT);
circle.setStroke(Color.RED);
circle.setStrokeWidth(2.0);
root.getChildren().add(circle);
} else {
// "lock" the circle in place
circle.setStroke(Color.GREEN);
circle = null;
}
}
}
private void handleMouseMoved(MouseEvent e) {
// if 'circle' is null then there's no circle being drawn
if (circle != null) {
double x1 = circle.getCenterX();
double y1 = circle.getCenterY();
double x2 = e.getX();
double y2 = e.getY();
double r = Math.sqrt(Math.pow(x2 - x1, 2.0) + Math.pow(y2 - y1, 2.0));
circle.setRadius(r);
}
}
}
Note I used private methods and method references to implement the mouse handlers. It's more concise that way but is behaviorally the same as your inner classes.
Also note that I don't use Math.abs when computing the radius. Using abs is actually wrong and can give you the wrong results (|x2| - |x1| != x2 - x1). For example, what if you had -3 - 2? That gives you |-3| - |2| = 1 which is not the same as -3 - 2 = -5.

How to properly implement the Action Listener in a bullseye animation

This program first displays a bullseye created by three different sized circles.
Once the animate me button is clicked, the function animation() will make the existing circles shrink inwards until the size of the circles is zero.
Once the user presses the button named "Press to stop", the animation will then stop. If the user presses the button again, it will then keep going from the state it was stopped from, so on so forth.
Currently, this is not working as intended. It only creates about 9 circles (including the nine circles that the program began with). I know I will need to use the action listener in order to make the program run, but I'm having a hard time in terms of the documentation of the action listener. What am I supposed to put in the parameters of the listener? If you see any other ways around this, please feel free to let me know.
package target;
import javafx.animation.ScaleTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Target extends Application
{
Circle[] cir = new Circle[7];
Button btn = new Button("Animate me!");
StackPane root = new StackPane();
public static void main(String[] args)
{
launch(args);
}
/**
* start method will create the target and the start button first
* displayed on-screen to the user
*/
#Override
public void start(Stage primaryStage)
{
root.setStyle("-fx-border-color:black;");
cir[0] = new Circle(400, 250, 200);
cir[0].setFill(Color.RED);
cir[0].setStyle("-fx-border-color:black;");
cir[1] = new Circle(315, 165, 115);
cir[1].setFill(Color.WHITE);
cir[1].setStyle("-fx-border-color:black;");
cir[2] = new Circle(230, 80, 30);
cir[2].setFill(Color.RED);
cir[2].setStyle("-fx-border-color:black;");
root.getChildren().addAll(cir[0], cir[1], cir[2]);
root.getChildren().add(btn);
primaryStage.setScene(new Scene(root));
primaryStage.show();
btn.setOnAction(e ->
{
animation();
btn.setText("Press to Stop");
});
}
public void animation()
{
//Timeline animation = new Timeline(
//)
ScaleTransition[] st = new ScaleTransition[7];
boolean recycleCircles = false;
st[0]= new ScaleTransition(Duration.seconds(7), cir[0]);
st[0].setToX(0.0f);
st[0].setToY(0.0f);
st[0].play();
st[1] = new ScaleTransition(Duration.seconds(5.5), cir[1]);
st[1].setToX(0.0f);
st[1].setToY(0.0f);
st[1].play();
st[2] = new ScaleTransition(Duration.seconds(4), cir[2]);
st[2].setToX(0.0f);
st[2].setToY(0.0f);
st[2].play();
// int delayInc = 1;
int delay = 1;
//will create circles (will rotate between white and red) and then add
//to scaleTransitions
//while(btn.isPressed() == false)
{
for(int i = 3; i<st.length; i++)
{
if(recycleCircles == true)
{
i = 0;
recycleCircles = false;
}
if(i % 2 == 1)
{
cir[i] = new Circle(400,250,200);
cir[i].setFill(Color.WHITE);
cir[i].setStyle("-fx-border-color:black;");
root.getChildren().add(cir[i]);
cir[i].toBack();
st[i] = new ScaleTransition(Duration.seconds(7), cir[i]);
st[i].setDelay(Duration.seconds(delay));
delay++;
st[i].setToX(0.0f);
st[i].setToY(0.0f);
st[i].play();
}
else if(i%2==0)
{
cir[i] = new Circle(400, 250, 200);
cir[i].setFill(Color.RED);
cir[i].setStyle("-fx-border-color:black;");
root.getChildren().add(cir[i]);
cir[i].toBack();
st[i] = new ScaleTransition(Duration.seconds(7), cir[i]);
st[i].setDelay(Duration.seconds(delay));
delay++;
st[i].setToX(0.0f);
st[i].setToY(0.0f);
st[i].play();
}
if(i == 6)
recycleCircles = true;
}
}
//btn.pressedProperty().addListener(listener);
btn.setOnMousePressed(event ->
{
});
btn.setOnMouseReleased(event ->
{
for(int y = 0; y<st.length;y++)
{
}
});
}
}
Not sure whether you have any specific use case with each circle. If your are using the circles only for the purpose of alternating row colors, then you can get similar effect with radial gradient's repeat option.
To the extent I understand the question, below program is what I can think of. May be this can help you.
Just to let you know, the overall effect is slightly different from your program. The main difference in effects is, your program gives an effect/impression that each circle are shrinking towards center, as the distance between each circle is always same till it shrinked completely.
My program gives the effect/.impression like the entire board is moving away from your sight till it vanishes. In my program the distance between each circle decreases proportianally till it shrinks.
import javafx.animation.ScaleTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class TargetAnimation extends Application {
Button btn = new Button("Animate me!");
StackPane root = new StackPane();
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
root.setPrefSize(400, 400);
root.setStyle("-fx-border-color:black;");
Circle board = new Circle();
board.setRadius(200);
board.setStyle("-fx-fill:radial-gradient(focus-angle 0deg , focus-distance 0% , center 50% 50% , radius 21% , repeat, red 44% , white 46% );-fx-stroke-width:1px;-fx-stroke:black;");
root.getChildren().addAll(board, btn);
primaryStage.setScene(new Scene(root));
primaryStage.show();
ScaleTransition transition = new ScaleTransition(Duration.seconds(7), board);
transition.setToX(0);
transition.setToY(0);
btn.setOnAction(e -> {
switch (transition.getStatus()) {
case RUNNING:
transition.pause();
break;
case PAUSED:
transition.play();
break;
default:
board.setScaleX(1);
board.setScaleY(1);
transition.playFromStart();
}
});
}
}
The code given to setOnAction is an EventHandler, which is a #FunctionalInterface with the single method handle. That means that you can give it a lambda expression instead. The method takes an argument, which is the ActionEvent of clicking the button (created for you by JavaFX), and runs the code you give it.
If you want to pause the animation, call Animation#pause, and if you want to resume it, call Animation#play. I suggest that you create a ParallelTransition with all of your ScaleTransitions as its children. Then call the above methods on the ParallelTransition in the event handler.
That means that the setup code, like naming the button and creates the animations, goes outside of the event handler.

javafx full screen on SECOND screen

For the life of me, I can't seem to get help on this. I have a JavaFX screen and I am trying to get to show fullscreen on my 2nd monitor. I tried the following based on other recommendations but to no avail. I know the coordinates are right but it KEEPS going full screen on my MAIN monitor. Please help.
if (mainSet.getBoolean("fullScr", false)) {
int count = mainSet.getInt("MonSel", 0);
if (count > 0) {
int i = 0;
for (Screen screen: Screen.getScreens()) {
if (count == i) {
Rectangle2D bounds = screen.getBounds();
primaryStage.setX(bounds.getMinX());
System.out.println(bounds.getMinX());
System.out.println(bounds.getMinY());
primaryStage.setY(bounds.getMinY());
}
i++;
}
}
primaryStage.setFullScreen(true);
}
The first if checks a preference to see if fullscreen is set. the 2nd if sees if another monitor besides the first one was selected. It's 1, so that should be the 2nd monitor. The program loops through all screens and tries to move the program and THEN will go full screen. I know the coordinates are the same but no dice, it still goes full screen on the main screen. Please help.
I don't know if I truly understand your problem, but if you have two screens, why loop through the screens? Why not just use the info associated with the screen in position two/index one of the ObservableList? I am posting a sample app that demos how to display full screen on a second monitor.
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Screen;
import javafx.stage.Stage;
/**
*
* #author blj0011
*/
public class JavaFXApplication257 extends Application
{
#Override
public void start(Stage primaryStage)
{
ObservableList<Screen> screens = Screen.getScreens();//Get list of Screens
Button btn = new Button();
btn.setText("Full Screen - Screen 1");
btn.setOnAction((ActionEvent event) -> {
Rectangle2D bounds = screens.get(0).getVisualBounds();
primaryStage.setX(bounds.getMinX());
primaryStage.setY(bounds.getMinY());
primaryStage.setFullScreen(true);
//primaryStage.setWidth(bounds.getWidth());
//primaryStage.setHeight(bounds.getHeight());
});
Button btn2 = new Button();
btn2.setText("Full Screen - Screen 2");
btn2.setOnAction((ActionEvent event) -> {
if (screens.size() > 0) {
Rectangle2D bounds = screens.get(1).getVisualBounds();
primaryStage.setX(bounds.getMinX());
primaryStage.setY(bounds.getMinY());
primaryStage.setFullScreen(true);
//primaryStage.setWidth(bounds.getWidth());
//primaryStage.setHeight(bounds.getHeight());
}
});
StackPane root = new StackPane();
root.getChildren().add(new VBox(btn, btn2));
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);
}
}

How do I insert all my shapes into an array?

I am Trying to build a cinema booker, where I have to select the seats. I was thinking about make placing all my rectangles in an array so i could use it for later, when clicking on a seat it should check if left and right seats are booked. Here the array index should help me. However I cant figure out how to get to this stage. (See picture.)
Take this scenario:
You click on a rectangle (representing a seat). It changes color only it is not Red colored. So Seats[][].checkNeighbourColor or something like that.See picture
package sample;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import java.awt.*;
import java.util.ArrayList;
public class Main extends Application {
private int seats = 12;
private int rows = 8;
private static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); //gets screen resolution data
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("");
Group root = new Group();
Scene scene = new Scene(root, screenSize.getWidth()/4, screenSize.getHeight()/3, Color.WHITE);
for (int i = 0; i<= seats; i++)
{
Rectangle r = new Rectangle();
r.setFill(Color.GREEN);
r.setX(scene.getWidth()/5+i*30);
r.setY(scene.getHeight()/5);
r.setWidth(screenSize.getHeight()/80);
r.setHeight(screenSize.getHeight()/80);
root.getChildren().add(r);
for (int q = 0; q<=rows; q++)
{
Rectangle s = new Rectangle();
s.setFill(Color.GREEN);
s.setX(scene.getWidth()/5+i*30);
s.setY(scene.getHeight()/5+q*30);
s.setWidth(screenSize.getHeight()/80);
s.setHeight(screenSize.getHeight()/80);
root.getChildren().add(s);
s.setOnMouseClicked(event ->{
s.setFill(Color.BLACK);
});
}
}
primaryStage.setScene(scene);
primaryStage.show();
}
}
It's not entirely clear to me what you're asking, but can't you just do
private Rectangle[][] rectangles = new Rectangle[seats][rows];
and then just do
rectangles[i][q] = s ;
For your listener you can do
final int row = i ;
final int seat = q ;
s.setOnMouseClicked(event -> {
// check rectangles[row-1][seat] and rectangles[row+1][seat] as needed,
// checking for range of row first
});
Aside: don't mix AWT and JavaFX. Use the Screen API to get the dimension of the physical screen(s) in JavaFX.
Okay I found my mistake. It was a simple ArrayOutOfBound (The statement in my for-loops was wrong), but thank you all for your help :)

JavaFX 3D depth rendering incorrectly

Setup:
The following code, renders a 3D scene with a visible co-ordinate axis positioned at the origin, from a camera displaced by -156 units in the Z direction. Also, the camera's Z position is a function of mouse scroll, such that scrolling up/down will move the camera further/closer from the origin.
Problem:
upon initial startup of the program, the red and green axis are rendered at/near the origin, when in the physical world, it would be impossible to see them there from the current camera view. (blue axis blocking them). Also, when you scroll backwards and forwards, you can see glitches/flashes where the red/green axis are visible behind the blue axis, which should not occur.
Screenshot of result (with my manual adding of issue description):
initial_screenshot
Question:
1) Is this a problem with my setup? or JavaFX?
2) if this is a problem with my setup, then can someone please explain what I can do to remedy this issue?
Code:
/*
* 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 testproblemjavafx01;
/**
*
* #author ad
*/
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.event.EventHandler;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.input.ScrollEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.stage.Stage;
public class TestProblemJavaFX01 extends Application {
#Override
public void start(Stage primaryStage) {
Group root = new Group();
buildAxes(root);
Scene scene = new Scene(root, 600, 400, true, SceneAntialiasing.BALANCED);
PerspectiveCamera camera = new PerspectiveCamera(true);
scene.setFill(Color.WHITE);
camera.setNearClip(0);
camera.setFarClip(1000.0);
camera.setTranslateX(0);
camera.setTranslateY(0);
camera.setTranslateZ(-156);
scene.setCamera(camera);
setMouseEvents(scene);
primaryStage.setResizable(false);
primaryStage.setTitle("TestProblemJavaFX01");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
private void buildAxes(Group root) {
final PhongMaterial redMaterial = new PhongMaterial();
redMaterial.setDiffuseColor(Color.DARKRED);
redMaterial.setSpecularColor(Color.RED);
final PhongMaterial greenMaterial = new PhongMaterial();
greenMaterial.setDiffuseColor(Color.DARKGREEN);
greenMaterial.setSpecularColor(Color.GREEN);
final PhongMaterial blueMaterial = new PhongMaterial();
blueMaterial.setDiffuseColor(Color.DARKBLUE);
blueMaterial.setSpecularColor(Color.BLUE);
final Box xAxis = new Box(240.0, 1, 1);
final Box yAxis = new Box(1, 240.0, 1);
final Box zAxis = new Box(1, 1, 240.0);
xAxis.setMaterial(redMaterial);
yAxis.setMaterial(greenMaterial);
zAxis.setMaterial(blueMaterial);
root.getChildren().addAll(xAxis, yAxis, zAxis);
}
private void setMouseEvents(final Scene scene) {
scene.setOnScroll(
new EventHandler<ScrollEvent>() {
#Override
public void handle(ScrollEvent event) {
double deltaY = event.getDeltaY();
Camera camera = scene.getCamera();
camera.setTranslateZ(camera.getTranslateZ() + deltaY);
event.consume();
}
});
}
}
I think the problem is within the line camera.setNearClip(0);
From the documentation of setNearClip:
Specifies the distance from the eye of the near clipping plane of this
Camera in the eye coordinate space. Objects closer to the eye than
nearClip are not drawn. nearClip is specified as a value greater than
zero. A value less than or equal to zero is treated as a very small
positive number.
Try to set the value to its default value of 0.1. Or just remove the line.

Categories

Resources