How to work with canvas and text in javafx - java

I am new to JavaFX and I am trying to display a rational number.
For example for the number 5/7 I want the program to show the following:
Here is the code I've tried to use in order to get the result (but it shows nothing but a blank white pane):
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
public class Main extends Application {
Font fontLarge = Font.font("Droid Sans", FontWeight.BOLD, 15);
Font fontSmall = Font.font("Droid Sans", FontWeight.BOLD, 10);
#Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 200, 200);
root.getChildren().add(getBoxOfRationalNumber("5", "7"));
scene.setRoot(root);
stage.setScene(scene);
stage.show();
}
public VBox getBoxOfRationalNumber(String theNum, String theDenom) {
VBox vb = new VBox();
final Canvas num = new Canvas();
final Canvas denom = new Canvas();
final Canvas line = new Canvas();
GraphicsContext gNum = num.getGraphicsContext2D();
GraphicsContext gDenom = denom.getGraphicsContext2D();
GraphicsContext gLine = line.getGraphicsContext2D();
gLine.setFont(fontLarge);
gNum.setFont(fontLarge);
gDenom.setFont(fontLarge);
gLine.fillText("______", 0, 0);
gNum.fillText(theNum, 0, 0);
gDenom.fillText(theDenom, 0, 0);
vb.getChildren().add(num);
vb.getChildren().add(line);
vb.getChildren().add(denom);
return vb;
}
public static void main(String[] args) {
launch(args);
}
}

Although, you could use a canvas for this, I advise to not try to solve this problem with a canvas. In your case, using only scene graph nodes rather than canvas is most likely a more appropriate solution to your problem.
Here is a sample solution using scene graph nodes.
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Line;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;
public class FractionDisplay extends Application {
private class Fraction extends VBox {
private double offset;
public Fraction(int numerator, int denominator) {
init(numerator + "", denominator + "");
}
public Fraction(String numerator, String denominator) {
init(numerator, denominator);
}
private void init(String numerator, String denominator) {
setAlignment(Pos.CENTER);
Text numeratorText = new Text(numerator);
Text denominatorText = new Text(denominator);
offset = numeratorText.getBaselineOffset() * 1.5;
double dividerWidth =
Math.max(
numeratorText.getLayoutBounds().getWidth(),
denominatorText.getLayoutBounds().getWidth()
) + 6;
Line divider = new Line(0, 1, dividerWidth, 1);
divider.setStrokeWidth(2);
getChildren().addAll(
numeratorText,
divider,
denominatorText
);
}
public double getBaselineOffset() {
return offset;
}
}
#Override
public void start(Stage stage) {
TextFlow flow = new TextFlow(
new Text("In mathematics, the infinite series "),
new Fraction(1, 2),
new Text(" - "),
new Fraction(1, 4),
new Text(" + "),
new Fraction(1, 8),
new Text(" - "),
new Fraction(1, 16),
new Text(" . . . "),
new Text(" is a simple example of an alternating series that converges absolutely.")
);
flow.setPadding(new Insets(5));
Scene scene = new Scene(flow, 300, 100);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Of course, the above is a pretty simplistic and incomplete solution to a general issue of typesetting math. If you need sophisticated mathematics typesetting, you could use something like MathJax in a WebView.

The main problem of your code seems to be that the canvases don't have a size. But the whole code seems to be a strange mixture of concepts for me.
Why do you use three separate canvases? Why do you combine them with a VBox? Would you do all that too if you were just writing on a piece of paper?

Related

Layout bounds of a group and invisible elements in JavaFX

I have a number of nodes in a group, whose visibility I would like to control using the visibleProperty(). I have observed that turning visibility of an element off affects the layout bounds of the group. They are recalculated as if the element wasn't there at all, not just wasn't visible. Is there a way to keep the presence of a node, but just turn off its visibility, so that the layout bounds were adjusted as if the node was there the whole time?
Example to ilustrate the problem, let's assume that the nodes are circles below.
Circle c1 = new Circle(0.0, 0.0, 3); // radius is 3
Circle c2 = new Circle(10.0, 10.0, 3);
Circle c3 = new Circle(20.0, 20.0, 3);
Group g = new Group();
g.getChildren().addAll(c1, c2, c3);
Bounds b1 = g.getLayoutBounds();
c3.visibleProperty().setValue(false);
Bounds b2 = g.getLayoutBounds();
Above bounds b and b2 will span:
b1 = BoundingBox [minX:-3.0, minY:-3.0, minZ:0.0, width:26.0, height:26.0, depth:0.0, maxX:23.0, maxY:23.0, maxZ:0.0]
b2 = BoundingBox [minX:-3.0, minY:-3.0, minZ:0.0, width:16.0, height:16.0, depth:0.0, maxX:13.0, maxY:13.0, maxZ:0.0]
Bounds b2 are calculated after turning off the visibility of circle c3, so they shrinked with respect to the original bounds b1. I would like to have the method of having the bounds expanded to b1, even though some elements in the group are not visible.
Edit
Minimal reproducible example:
package sample;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.HBox;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Circle c1 = new Circle(0.0, 0.0, 3); // radius is 3
Circle c2 = new Circle(10.0, 10.0, 3);
Circle c3 = new Circle(20.0, 20.0, 3); // radius is 3
Circle c4 = new Circle(30.0, 30.0, 3);
Group g1 = new Group();
Group g2 = new Group();
g1.getChildren().addAll(c1, c2);
g2.getChildren().addAll(c3, c4);
Group main = new Group(g1, g2);
CheckBox checkBox1 = new CheckBox("Show");
g2.visibleProperty().bind(checkBox1.selectedProperty());
Bounds b1 = main.getLayoutBounds();
System.out.println(b1);
checkBox1.selectedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> observableValue, Boolean aBoolean, Boolean t1) {
System.out.println(main.getLayoutBounds());
}
});
HBox hbox = new HBox(checkBox1, main);
Scene scene = new Scene(hbox, 400, 300);
primaryStage.setTitle("Hello Stackoverflow, are you happy now?");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Now, any time you select the checkbox, not only 2 of 4 circles appear, but you will also see that layout bounds of the group change. The problem is that I need to know all the time the layout bounds as if all the groups were visible. I can't store the bounds value when they are all visible, because for simplicity I included here only 4 circles, while in real application, they are in thousands and they are moving around also when not visible, and there are also other objects of different sizes bound to them, which may expand the layout bounds of the main group even more.
Updated solution.
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Shape;
public class ShapesGroup extends Group {
public final BooleanProperty transparentProperty = new SimpleBooleanProperty();
private final ObservableList<Shape> shapes = FXCollections.observableArrayList();
public ShapesGroup() {
Bindings.bindContent(getChildren(), shapes);
shapes.addListener((ListChangeListener<Shape>) change -> {
while (change.next()) {
if (change.wasAdded()) {
for (Shape shape : change.getAddedSubList()) {
shape.fillProperty().addListener((ChangeListener<Paint>) (observable, oldFill, newFill) -> {
transparentProperty.addListener((ChangeListener<Boolean>) (observable1, oldTransparent, newTransparent) -> {
if (!newTransparent) {
shape.setFill(oldFill);
}
});
});
transparentProperty.addListener((ChangeListener<Boolean>) (observable, oldValue, newValue) -> {
if (newValue) {
shape.setFill(Color.TRANSPARENT);
}
});
}
}
}
});
}
public ObservableList<Shape> getShapes() {
return shapes;
}
}
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class MainApp extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
Rectangle rectangle = new Rectangle(40, 40, Color.YELLOW);
Circle circle = new Circle(20, Color.RED);
ShapesGroup group = new ShapesGroup();
group.getShapes().addAll(rectangle, circle);
StackPane stackPane = new StackPane(group);
Button button = new Button("Switch");
VBox vBox = new VBox(stackPane, button);
VBox.setVgrow(stackPane, Priority.ALWAYS);
Scene scene = new Scene(vBox, 400, 400);
stage.setScene(scene);
stage.show();
button.setOnAction(event -> {
group.transparentProperty.set(!group.transparentProperty.get());
});
}
}

Label moves backwards slowly

The code below should move the Label based on the position of the horizontal scroll bar so that the Label appears to remain stationary. This almost works perfectly however when you move the scrollbar to the end the label has moved slightly so it does not look like it is in the same position.
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class LblMoves extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
try {
VBox images = new VBox();
images.setPadding(new Insets(0, 0, 0, 0));
Label posLbl = new Label("0");
images.getChildren().add(posLbl);
images.setPrefSize(Integer.MAX_VALUE, 50);
ScrollPane scrollPane = new ScrollPane(images);
scrollPane.setStyle("-fx-background: #FFFFFF;");
scrollPane.hvalueProperty().addListener(new ChangeListener<Number>() {
public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) {
double screenPer = scrollPane.getHvalue() * scrollPane.getWidth();
double pos = scrollPane.getHvalue() * images.getWidth();
double marg = pos - screenPer;
posLbl.setPadding(new Insets(0, 0, 0, marg));
}
});
Scene scene = new Scene(scrollPane, 600, 600);
primaryStage.setScene(scene);
primaryStage.setMaximized(true);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
You use the width of the ScrollPane. However the width used in the calculations for ScrollPane use the viewportBounds.
Also since by default the position is rounded to full pixels, which causes some movement of the Label (which could be fixed by using translateX instead of the padding).
InvalidationListener listener = o -> {
double marg = (images.getWidth() - scrollPane.getViewportBounds().getWidth()) * scrollPane.getHvalue();
posLbl.setTranslateX(marg);
// posLbl.setPadding(new Insets(0, 0, 0, marg));
};
scrollPane.hvalueProperty().addListener(listener);
scrollPane.viewportBoundsProperty().addListener(listener);
listener.invalidated(null);

Changing an Int value to a String in object oriented programming

I am making a simple game on JavaFX right now.
The picture of my program is here
So far, my code is generating random monsters using a random number generator, and my health will decrease a random number each time I hit the explore button.
I also added a stats box. This box will display my current health, hunger, and hydration levels.
My problem is, is that I am not sure how I am supposed to change the values in my stats box. Every time my character gets hit by a monster, I want the health text to change. When I do :
dStatBox.setText(mainCharacter.getHealthLevel());
It says that I must convert the int to a string. How can I go about doing this?
My whole code is below:
import java.util.Random;
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.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
public class Game extends Application {
public static TextArea dialogue = new TextArea();
public static TextArea dStatBox = new TextArea();
Button exploreButton;
Random r = new Random();
int ogreDamage = r.nextInt(20) + 1;
public void start(Stage primaryStage) {
Character mainCharacter = new Character("Nikki");
BorderPane pane = new BorderPane();
HBox top = new HBox();
VBox gameBox = new VBox();
VBox explore = new VBox();
VBox statBox = new VBox();
exploreButton = new Button("Explore");
Label stats = new Label("Stats");
stats.setFont(Font.font(30));
stats.setFont(Font.font("Helvetica", FontWeight.BOLD, FontPosture.REGULAR, 24));
statBox.setPadding(new Insets(10,10,10,10));
statBox.setSpacing(10);
statBox.setMaxHeight(300);
statBox.setPrefWidth(300);
statBox.getChildren().addAll(stats, dStatBox);
statBox.setAlignment(Pos.TOP_CENTER);
dStatBox.setEditable(false);
dStatBox.setText("Health: 100/100\n");
Label label = new Label("Game Dialogue");
label.setFont(Font.font(30));
label.setFont(Font.font("Helvetica", FontWeight.BOLD, FontPosture.REGULAR, 24));
gameBox.setPadding(new Insets(10,10,10,10));
gameBox.setSpacing(10);
dialogue.setMaxHeight(200);
dialogue.setMaxWidth(470);
dialogue.setWrapText(true);
dialogue.setEditable(false);
gameBox.getChildren().addAll(label, dialogue, exploreButton);
gameBox.setAlignment(Pos.CENTER);
top.getChildren().addAll(gameBox, statBox);
top.setAlignment(Pos.TOP_LEFT);
pane.setTop(top);
dialogue.appendText("Welcome to Wild Berries - the Ultimate Survival Game\n");
dialogue.appendText("How long can you survive for? Only time will tell...\n");
exploreButton.setOnAction(e -> {
Random r = new Random();
int ogreDamage = r.nextInt(20) + 1;
int randomInt = r.nextInt(3) + 1;
dialogue.appendText("You begin to explore the wild...\n");
if(randomInt == 1) {
dialogue.appendText("A wild Ogre has appeared!\n");
dialogue.appendText("You have been hurt. -" + ogreDamage + " HP.\n");
mainCharacter.setHealthLevel(mainCharacter.getHealthLevel() - ogreDamage);
dialogue.appendText(mainCharacter.getHealthLevel());
if(mainCharacter.getHealthLevel() <= 0) {
dialogue.appendText("You have died. Thank you for playing.");
}
}
if(randomInt == 2) {
dialogue.appendText("A wild Goblin has appeared!\n");
}
if(randomInt == 3) {
dialogue.appendText("A wild Ghost has appeared!\n");
}
});
Scene scene = new Scene(pane, 800, 450);
primaryStage.setScene(scene);
primaryStage.setTitle("Wild Berries GUI");
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
I'm assuming that mainCharacter.getHealthLevel() is returning an int. You should do dStatBox.setText("Health: " + mainCharacter.getHealthLevel());
As simple as this:
int healthLevel = mainCharacter.getHealthLevel();
String.valueOf(healthLevel);
//or
Integer.toString(healthLevel);

javafx pane not being created

My JavaFx code does not work as it should do. I am trying to create 10X10 text matrix populated with either a 1 or 0, so it looks similar to a 2d array filled with 1's and 0's. When I put the code that is currently in the MatrixPane class in main it works fine, but with this code it just sets the scene but it looks like no pane is added or created.
If anyone can help me I would greatly appreciate it.
I realize I have Imported some unused things, I am using them for other parts of the program.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.FlowPane;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.text.Text;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javafx.scene.shape.Arc;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.geometry.Pos;
import javafx.collections.ObservableList;
public class Button1 extends Application
{
public void start(Stage primaryStage)
{
GridPane pane = new GridPane();
MatrixPane Matrix = new MatrixPane();
pane.getChildren().add(Matrix);
Scene scene = new Scene(pane, 700, 500);
primaryStage.setTitle("1 window "); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
public static void main(String[] args)
{
Application.launch(args);
}
}
class MatrixPane extends Pane
{
double HEIGHT = 500;
double WIDTH = 200;
private GridPane pane1 = new GridPane();
public MatrixPane()
{
}
public void fillmatrix()
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
TextField text = new TextField(Integer.toString((int)(Math.random() * 2)));
text.setMinWidth(WIDTH / 8.0);
text.setMaxWidth(WIDTH / 10.0);
text.setMinHeight(HEIGHT / 8.0);
text.setMaxHeight(HEIGHT / 10.0);
this.pane1.add(text, j, i);
}
}
}
}
Call fillMatrix(); method from Button1.start()
Add GridPane to MatrixPane in MatrixPane construcor
private GridPane pane1 = new GridPane();
public MatrixPane() {
getChildren().add(pane1);
}
This will work.
Well I checked your code and you are excessively using GridPane. First you have a class named MatrixPane which inherits Pane, but also this class has a property GridPane. Finally, you use GridPane once again to add MatrixPane!
So, what I did is to use composition, but first I change the start method
public void start(Stage primaryStage) {
GridPane pane = new GridPane();
MatrixPane Matrix = new MatrixPane();
//pane.getChildren().add(Matrix);
Matrix.fillmatrix();
Scene scene = new Scene(Matrix.getPane1(), 700, 500);
...
So here the scene is going to receive the data of pane1, this attribute has the values stored when fillmatrix was called.
Then I add the getter method in MatrixPane for the attribute pane1
class MatrixPane {
double HEIGHT = 500;
double WIDTH = 200;
private GridPane pane1 = new GridPane();
public GridPane getPane1() {
return pane1;
}
...

Exception while evaluating select-binding in JavaFX 8

Here is an example from Pro JavaFx 8:
package projavafx.reversi.examples;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.InnerShadow;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Ellipse;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import projavafx.reversi.model.Owner;
import projavafx.reversi.model.ReversiModel;
/**
* #author Stephen Chin <steveonjava#gmail.com>
*/
public class BorderLayoutExample extends Application {
TilePane scoreTiles;
TilePane titleTiles;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
BorderPane borderPane = new BorderPane();
borderPane.setTop(createTitle());
borderPane.setCenter(createBackground());
borderPane.setBottom(createScoreBoxes());
Scene scene = new Scene(borderPane, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
// scoreTiles.prefTileWidthProperty().bind(Bindings.selectDouble(scoreTiles.parentProperty(), "width").divide(2));
// titleTiles.prefTileWidthProperty().bind(Bindings.selectDouble(titleTiles.parentProperty(), "width").divide(2));
}
private Node createTitle() {
StackPane left = new StackPane();
left.setStyle("-fx-background-color: black");
Text text = new Text("JavaFX");
text.setFont(Font.font(null, FontWeight.BOLD, 18));
text.setFill(Color.WHITE);
StackPane.setAlignment(text, Pos.CENTER_RIGHT);
left.getChildren().add(text);
Text right = new Text("Reversi");
right.setFont(Font.font(null, FontWeight.BOLD, 18));
titleTiles = new TilePane();
titleTiles.setSnapToPixel(false);
TilePane.setAlignment(right, Pos.CENTER_LEFT);
titleTiles.getChildren().addAll(left, right);
titleTiles.setPrefTileHeight(40);
titleTiles.prefTileWidthProperty().bind(Bindings.selectDouble(titleTiles.parentProperty(), "width").divide(2));
return titleTiles;
}
private Node createBackground() {
Region answer = new Region();
RadialGradient rg = new RadialGradient(225, 0, 0, 0, 1, true, CycleMethod.NO_CYCLE,
new Stop(0.0, Color.WHITE),
new Stop(1.0, Color.GRAY)
);
answer.setBackground(new Background(new BackgroundFill(rg, null, null)));
// answer.setStyle("-fx-background-color: radial-gradient(radius 100%, white, gray)");
return answer;
}
private Node createScoreBoxes() {
scoreTiles = new TilePane(createScore(Owner.BLACK), createScore(Owner.WHITE));
scoreTiles.setSnapToPixel(false);
scoreTiles.setPrefColumns(2);
scoreTiles.prefTileWidthProperty().bind(Bindings.selectDouble(scoreTiles.parentProperty(), "width").divide(2));
return scoreTiles;
}
private Node createScore(Owner owner) {
Region background;
Ellipse piece = new Ellipse(32, 20);
piece.setFill(owner.getColor());
DropShadow pieceEffect = new DropShadow();
pieceEffect.setColor(Color.DODGERBLUE);
pieceEffect.setSpread(.2);
piece.setEffect(pieceEffect);
Text score = new Text();
score.setFont(Font.font(null, FontWeight.BOLD, 100));
score.setFill(owner.getColor());
Text remaining = new Text();
remaining.setFont(Font.font(null, FontWeight.BOLD, 12));
remaining.setFill(owner.getColor());
VBox remainingBox = new VBox(10, piece, remaining);
remainingBox.setAlignment(Pos.CENTER);
FlowPane flowPane = new FlowPane(20, 10, score, remainingBox);
flowPane.setAlignment(Pos.CENTER);
background = new Region();
background.setStyle("-fx-background-color: " + owner.opposite().getColorStyle());
ReversiModel model = ReversiModel.getInstance();
StackPane stack = new StackPane(background, flowPane);
InnerShadow innerShadow = new InnerShadow();
innerShadow.setColor(Color.DODGERBLUE);
innerShadow.setChoke(.5);
background.effectProperty().bind(Bindings.when(model.turn.isEqualTo(owner))
.then(innerShadow)
.otherwise((InnerShadow) null));
DropShadow dropShadow = new DropShadow();
dropShadow.setColor(Color.DODGERBLUE);
dropShadow.setSpread(.2);
piece.effectProperty().bind(Bindings.when(model.turn.isEqualTo(owner))
.then(dropShadow)
.otherwise((DropShadow) null));
score.textProperty().bind(model.getScore(owner).asString());
remaining.textProperty().bind(model.getTurnsRemaining(owner).asString().concat(" turns remaining"));
return stack;
}
}
A warning pops up in the console when running this app:
sept. 20, 2015 11:07:03 AM com.sun.javafx.binding.SelectBinding$SelectBindingHelper getObservableValue
WARNING: Exception while evaluating select-binding [width]
sept. 20, 2015 11:07:03 AM com.sun.javafx.binding.SelectBinding$SelectBindingHelper getObservableValue
WARNING: Exception while evaluating select-binding [width]
What went wrong here?
The problem is the following bit of code in the method createTitle():
titleTiles.prefTileWidthProperty().bind(
Bindings.selectDouble(
titleTiles.parentProperty(), "width").divide(2));
At this moment, the titleTiles have not yet been added to the borderPane, so the value of the parentProperty is null, hence the width property can not be found on it.
Same in createScoreBoxes().
Next time, though, it would be nice, if you cut down your sample code a bit, especially remove references to classes from your project (import projavafx.reversi.model.ReversiModel;), do that one can paste it into his IDE and run it right away.

Categories

Resources