Exception while evaluating select-binding in JavaFX 8 - java

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.

Related

Why are my JavaFX buttons unevenly spaced?

I'm new to JavaFX, trying to build a GUI program that displays a bill for a table at a restaurant when you click on that table. The spacing is off between the table buttons and I'm not sure why.
The GUI class for my program:
package restaurantBillingProgram;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.geometry.Pos;
public class BillingGUI extends Application {
#Override
public void start(Stage primaryStage) {
// Create grid pane
GridPane pane = new GridPane();
pane.setAlignment(Pos.CENTER);
pane.setHgap(5);
pane.setVgap(5);
// Label
pane.add(new Label("Generate bill"), 1, 0);
// Buttons
Button btT1 = new Button("Table 1");
pane.add(btT1, 0, 1);
btT1.setOnAction(e - > Billing.generateT1());
Button btT2 = new Button("Table 2");
pane.add(btT2, 1, 1);
btT2.setOnAction(e - > Billing.generateT2());
Button btT3 = new Button("Table 3");
pane.add(btT3, 2, 1);
btT3.setOnAction(e - > Billing.generateT3());
// Create scene and place in stage
Scene scene = new Scene(pane, 250, 250);
primaryStage.setTitle("Restaurant Billing Program");
primaryStage.setScene(scene);
primaryStage.show();
}
// Main method
public static void main(String[] args) {
launch(args);
}
}
From the Javadoc:
Row/Column Sizing
By default, rows and columns will be sized to fit their content; a column will be wide enough to accommodate the widest child, ...
The label in row 0 column 1 forces that column to be wider.
You probably want the label to be centered and span all 3 columns.
While doing you layout, use pane.setGridLinesVisible(true). This should only be used during debugging. It can be very useful for situations like your current situation. As #Jim Garrison pointed out, your Label is causing the issue:
Issue:
One way to fix this is to let the Label span all columns and center the Label's text.
Fix:
Key Code:
label.setMaxWidth(Double.MAX_VALUE);
label.setAlignment(Pos.CENTER);
pane.add(label, 0, 0, 3, 1);// Look at the following link to see how this add method works. https://openjfx.io/javadoc/11/javafx.graphics/javafx/scene/layout/GridPane.html#add(javafx.scene.Node,int,int,int,int)
Full Code:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.geometry.Pos;
public class BillingGUI extends Application {
#Override
public void start(Stage primaryStage) {
// Create grid pane
GridPane pane = new GridPane();
pane.setAlignment(Pos.CENTER);
pane.setHgap(5);
pane.setVgap(5);
pane.setGridLinesVisible(true);//Use for debugging only!!!!
// Label
Label label = new Label("Generate bill");
label.setMaxWidth(Double.MAX_VALUE);
label.setAlignment(Pos.CENTER);
pane.add(label, 0, 0, 3, 1);
// Buttons
Button btT1 = new Button("Table 1");
pane.add(btT1, 0, 1);
Button btT2 = new Button("Table 2");
pane.add(btT2, 1, 1);
Button btT3 = new Button("Table 3");
pane.add(btT3, 2, 1);
// Create scene and place in stage
Scene scene = new Scene(pane, 250, 250);
primaryStage.setTitle("Restaurant Billing Program");
primaryStage.setScene(scene);
primaryStage.show();
}
// Main method
public static void main(String[] args) {
launch(args);
}
}

Center objects in HBox and VBox (JavaFx)

I am making a simple GUI for one of my assignments. I have created a bare bone interface and I am currently having some problems. The program displays everything fine it's just that I want to center the objects so it would look neater. What I tried is to put the button (belongs on the bottom) to a borderPane and align it to the center using the setCetner method but that did nothing. is there another way I can try to center all my objects on my pane?
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Main extends Application {
private TextField startDate;
private Text start;
private Text end;
private TextField endDate;
private Button count;
#Override
public void start(Stage primaryStage) {
start = new Text("Start Date: ");
end = new Text("End Date: ");
startDate = new TextField("1/1/2000");
endDate = new TextField(getDate());
count = new Button("Count");
HBox startLine = new HBox(10);
startLine.getChildren().addAll(start, startDate);
HBox endLine = new HBox(10);
endLine.getChildren().addAll(end, endDate);
HBox button = new HBox();
button.getChildren().add(count);
BorderPane borderPane = new BorderPane();
borderPane.setCenter(button);
VBox vbox = new VBox(10);
vbox.getChildren().addAll(startLine, endLine, button);
Pane root = new Pane();
root.getChildren().addAll(vbox);
Scene scene = new Scene(root, 400, 300);
primaryStage.setTitle("Date Counter");
primaryStage.setScene(scene);
primaryStage.show();
}
public String getDate(){
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
Date date = new Date();
return dateFormat.format(date);
}
public static void main(String[] args) {
Application.launch(args);
}
}
To let the UI look nicer I prefer GridPane (e. g. the Textfields are aligned)
// set the "coordinates" of the nodes
GridPane.setConstraints(start, 0, 0);
GridPane.setConstraints(startDate, 1, 0);
GridPane.setConstraints(end, 0, 1);
GridPane.setConstraints(endDate, 1, 1);
// center button here
GridPane.setConstraints(count, 0, 2, 2, 1, HPos.CENTER, VPos.CENTER);
// some spacing, otherwise the nodes stick together
Insets spacing = new Insets(3d);
GridPane.setMargin(start, spacing);
GridPane.setMargin(startDate, spacing);
GridPane.setMargin(end, spacing);
GridPane.setMargin(endDate, spacing);
GridPane.setMargin(count, spacing);
// nodes to the grid
GridPane grid = new GridPane();
grid.getChildren().addAll(start, startDate, end, endDate, count);
Scene scene = new Scene(grid, 400, 300);
If you want to center the complete grid you have to add grid.setAlignment(Pos.TOP_CENTER);.

How to make overlay Vbox nodes clickable?

I'm trying to build a javafx trimmer, I've done it, however when I added a setOnMouseClicked on ImageViews the trimmer I made hides these nodes, so the action is not handled.
I've have set Rectangle -50 in order to overlay the trimmer to the ImageView, unfortunately, this make event not working.
Rectangle rectangle = new Rectangle(0, -50, 80, 40);
the flowing controller builds is frame
package app.controller;
import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ScrollPane;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
public class Trimmer2 implements Initializable {
private Node selectedNode;
#FXML
private HBox hboxStream;
#FXML
private HBox hboxStreamTrim;
#FXML
private Label lblTime;
public void initialize(URL arg0, ResourceBundle arg1) {
buidTrimmer();
}
private void buidTrimmer() {
ImageView pic = null;
HBox hbox = new HBox();
DropShadow shadow = new DropShadow();
ClassLoader classLoader = getClass().getClassLoader();
File path = new File(classLoader.getResource("streams/sub_stream").getPath());
File [] files = path.listFiles();
Image[] images = new Image[files.length];
ImageView[] pics = new ImageView[files.length];
for (int i = 0; i < files.length; i++) {
final Image image = images[i] =
new Image(files[i].toURI().toString(), 80, 40, false, false);
pic = pics[i] =
new ImageView(image);
pic.setEffect(shadow);
pic.setOnMouseClicked((MouseEvent me) -> {
System.out.println("do action");
});
hbox.getChildren().add(pics[i]);
}
Rectangle rectangle = new Rectangle(0, -50, 80, 40);
rectangle.setFill(Color.rgb(33, 150, 243, 0.5));
Pane pane = new Pane( rectangle );
makeSelectable(rectangle, pane);
VBox vbox = new VBox();
vbox.setSpacing(10);
vbox.getChildren().addAll(hbox,pane);
ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(vbox);
scrollPane.setId("my_scrollPane");
hboxStream.getChildren().add(scrollPane);
}
private void makeSelectable(Node node, Pane root) {
node.setOnMouseClicked(event -> {
if (selectedNode != node) {
root.getChildren().removeIf(candidate -> candidate instanceof ResizingControl);
selectedNode = node;
node.toFront();
ResizingControl resizingControl = new ResizingControl(node);
root.getChildren().add(resizingControl);
}
System.out.println("here");
event.consume();
});
}
}
Try to add the Hbox and the rectangle inside your pane, by the way that pane must be empty. hope it helps :)
Rectangle rectangle = new Rectangle(0, 0, imgWidth, imgHeight);
rectangle.setFill(Color.rgb(33, 150, 243, 0.35));
Pane pane = new Pane();
VBox vbox = new VBox();
vbox.getChildren().addAll(pane);
pane.getChildren().addAll(hbox,rectangle);
Mouse events go to the topmost node that is not mouse transparent. Simply set the property to true and the mouse events will be handled at the usual node. One additional thing that can make your life easier is the fact that you can also place nodes inside a layout that are not affected by the layout algorithm of the parent and that do not contribute to the size calculations. Simply set managed to false. This allows you to implement the selection like this:
private Node selectedNode;
#Override
public void start(Stage primaryStage) throws Exception {
HBox container = new HBox();
File directory = new File("someDirectory");
Rectangle selection = new Rectangle(80, 40, Color.rgb(100, 100, 255, 0.5));
selection.setStrokeType(StrokeType.INSIDE);
selection.setStrokeWidth(4);
selection.setStroke(Color.WHITE);
selection.setVisible(false);
selection.setMouseTransparent(true);
selection.setManaged(false);
for (File file : directory.listFiles(f -> f.getName().endsWith(".jpg"))) {
Image image = new Image(file.toURI().toURL().toExternalForm(), 80, 40, false, false);
ImageView imageView = new ImageView(image);
container.getChildren().add(imageView);
imageView.setOnMouseClicked(evt -> {
if (selectedNode == imageView) {
selection.setVisible(false);
selectedNode = null;
} else {
selection.setVisible(true);
selection.setLayoutX(imageView.getLayoutX());
selectedNode = imageView;
}
});
}
container.getChildren().add(selection);
Scene scene = new Scene(new ScrollPane(container), 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
Note: I also removed the use of getResource and that is for a good reason. Resources are not guaranteed to be available as files. E.g. if you use a .jar file, you won't be able to access them via File. Either store outside of the classpath in a directory or make a list of the resources available as text resource to allow you multiple resources without hardcoding every single one of them. (Don't use File with the latter approach.)

Can't get Mediaview and square to show on borderpane

I need some help trying to get two things appearing on this borderpane. Currently I have the center set as a Gridpane. I need to add a mediaview and the text displayed in the class ButtonDemo both to the Gridpane. I also have to set the top of the borderpane to have a moving square. I can't figure out how to animate the square. But currently I am having trouble getting these two things to display. If anyone could help explain why these two objects won't display that would be very helpful. Thanks!
import javafx.application.Application;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.beans.property.DoubleProperty;
import javafx.stage.Stage;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.CheckBox;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.Slider;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.util.Duration;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
//Up and Down Button Class
class ButtonDemo extends Application {
protected Text text = new Text(50, 50, "Assignment 7");
public GridPane grid = new GridPane();
protected BorderPane getPane() {
HBox paneForButtons = new HBox(20);
Button btUp = new Button("^ Up ");
Button btDown = new Button("v Down ");
paneForButtons.getChildren().addAll(btUp, btDown);
paneForButtons.setStyle("-fx-border-color: green");
BorderPane border = new BorderPane();
border.setBottom(paneForButtons);
Pane paneForText = new Pane();
paneForText.getChildren().add(text);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(0, 10, 0, 10));
border.setCenter(grid);
grid.add(paneForText, 1, 10);
btUp.setOnAction(e -> text.setY(text.getY() - 10));
btDown.setOnAction(e -> text.setY(text.getY() + 10));
return border;
}
#Override
public void start(Stage primaryStage) {
Scene scene = new Scene(getPane(), 800, 650);
primaryStage.setTitle("Assignment 7");
primaryStage.setScene(scene);
primaryStage.show();
}
}
//Font Type Class
class CheckBoxDemo extends ButtonDemo {
#Override
protected BorderPane getPane() {
BorderPane border = super.getPane();
Font fontBoldItalic = Font.font("Arial",
FontWeight.BOLD, FontPosture.ITALIC, 20);
Font fontBold = Font.font("Arial",
FontWeight.BOLD, FontPosture.REGULAR, 20);
Font fontItalic = Font.font("Arial",
FontWeight.NORMAL, FontPosture.ITALIC, 20);
Font fontNormal = Font.font("Arial",
FontWeight.NORMAL, FontPosture.REGULAR, 20);
text.setFont(fontNormal);
VBox paneForCheckBoxes = new VBox(20);
paneForCheckBoxes.setPadding(new Insets(5, 5, 5, 5));
paneForCheckBoxes.setStyle("-fx-border-color: green");
CheckBox chkBold = new CheckBox("Bold");
CheckBox chkItalic = new CheckBox("Italic");
paneForCheckBoxes.getChildren().addAll(chkBold, chkItalic);
border.setLeft(paneForCheckBoxes);
EventHandler<ActionEvent> handler = e -> {
if (chkBold.isSelected() && chkItalic.isSelected()) {
text.setFont(fontBoldItalic);
}
else if (chkBold.isSelected()) {
text.setFont(fontBold);
}
else if (chkItalic.isSelected()) {
text.setFont(fontItalic);
}
else {
text.setFont(fontNormal);
}
};
chkBold.setOnAction(handler);
chkItalic.setOnAction(handler);
return border;
}
}
//Color Button Class
class RadioButtonDemo extends CheckBoxDemo {
#Override
protected BorderPane getPane() {
BorderPane border = super.getPane();
VBox paneForRadioButtons = new VBox(20);
paneForRadioButtons.setPadding(new Insets(5, 5, 5, 5));
paneForRadioButtons.setStyle("-fx-border-color: black");
paneForRadioButtons.setStyle("-fx-border-color: green");
RadioButton rbYellow = new RadioButton("Yellow");
RadioButton rbOrange = new RadioButton("Orange");
RadioButton rbPurple = new RadioButton("Purple");
paneForRadioButtons.getChildren().addAll(rbYellow, rbOrange, rbPurple);
border.setRight(paneForRadioButtons);
ToggleGroup group = new ToggleGroup();
rbYellow.setToggleGroup(group);
rbOrange.setToggleGroup(group);
rbPurple.setToggleGroup(group);
rbYellow.setOnAction(e -> {
if (rbYellow.isSelected()) {
text.setFill(Color.YELLOW);
}
});
rbOrange.setOnAction(e -> {
if (rbOrange.isSelected()) {
text.setFill(Color.ORANGE);
}
});
rbPurple.setOnAction(e -> {
if (rbPurple.isSelected()) {
text.setFill(Color.PURPLE);
}
});
return border;
}
}
//Rectangle Bouncing Class
class BouncingRectangle extends RadioButtonDemo {
private Rectangle rectangle = new Rectangle( 0, 0, 10, 10);
private Timeline animation;
#Override
protected BorderPane getPane() {
BorderPane border = super.getPane();
Pane squarePane = new Pane();
rectangle.setFill(Color.BLUE);
squarePane.getChildren().add(rectangle);
border.setTop(squarePane);
return border;
}
}
//MP4 Class
class MediaDemo extends RadioButtonDemo {
private static final String MEDIA_URL =
"http://cs.armstrong.edu/liang/common/sample.mp4";
#Override
protected BorderPane getPane() {
BorderPane border = super.getPane();
Media media = new Media(MEDIA_URL);
MediaPlayer mediaPlayer = new MediaPlayer(media);
MediaView mediaView = new MediaView(mediaPlayer);
Button playButton = new Button(">");
playButton.setOnAction(e -> {
if (playButton.getText().equals(">")) {
mediaPlayer.play();
playButton.setText("||");
} else {
mediaPlayer.pause();
playButton.setText(">");
}
});
Button rewindButton = new Button("<<");
rewindButton.setOnAction(e -> mediaPlayer.seek(Duration.ZERO));
Slider slVolume = new Slider();
slVolume.setPrefWidth(150);
slVolume.setMaxWidth(Region.USE_PREF_SIZE);
slVolume.setMinWidth(30);
slVolume.setValue(50);
mediaPlayer.volumeProperty().bind(
slVolume.valueProperty().divide(100));
HBox hBox = new HBox(10);
hBox.setAlignment(Pos.CENTER);
hBox.getChildren().addAll(playButton, rewindButton,
new Label("Volume"), slVolume);
BorderPane paneForMedia = new BorderPane();
paneForMedia.setCenter(mediaView);
paneForMedia.setBottom(hBox);
grid.add(paneForMedia, 6, 10);
return border;
}
}
public class n00935124 extends RadioButtonDemo {
public static void main(String[] args) {
launch(args);
}
}
Thanks again
First, this is a really non-standard way to organize things. Not wrong in any sense(*), but just so non-standard that it took me a while to figure out what was going on.
The reason you are not seeing the last two additions of content is that your inheritance hierarchy is wrong. You want:
class MediaDemo extends BouncingRectangle
and
public class n00935124 extends MediaDemo
instead of both extending RadioButtonDemo (which I'm guessing is just a copy-and-paste error).
(*) I guess the issue is that you are using inheritance solely to add state here, which is something of an anti-pattern. Inheritance is best used to either add behavior, or to provide alternative implementations of behavior.

JavaFX Stage wont show in Android

I have deployed a JavaFX application in Android using Gluon Plugin. What Im trying to do right now is to show a second Stage, but unfortunately it wont show.
Here's the code of the second Stage:
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Setting {
public Setting(){
Text title = new Text("Settings");
title.setId("setting-title");
title.setFont(Font.font("Arial", (int)(MainApp.HEIGHT * 0.04)));
Label label_url = new Label("URL");
label_url.setFont(Font.font("Arial", (int)(MainApp.HEIGHT * 0.03)));
Label label_style = new Label("Style");
label_style.setFont(Font.font("Arial", (int)(MainApp.HEIGHT * 0.03)));
TextField text_url = new TextField(MainApp.URL);
text_url.setFont(Font.font("Arial", (int)(MainApp.HEIGHT * 0.03)));
ComboBox style_box = new ComboBox();
style_box.setStyle("-fx-font-size:"+(int)(MainApp.HEIGHT * 0.03)+"px;");
ObservableList<String> data = FXCollections.observableArrayList();
data.add("Blue");
data.add("Red");
data.add("Yellow");
style_box.setItems(data);
GridPane grid = new GridPane();
grid.setVgap(5);
grid.setHgap(5);
grid.add(label_url, 0, 0);
grid.add(label_style, 0, 1);
grid.add(text_url, 1, 0);
grid.add(style_box, 1, 1);
VBox root = new VBox();
root.setAlignment(Pos.CENTER);
root.getChildren().addAll(title,grid);
Scene scene = new Scene(root, MainApp.WIDTH * 0.6, MainApp.HEIGHT * 0.4);
if(MainApp.SETTING == null){
MainApp.SETTING = new Stage();
MainApp.SETTING.setScene(scene);
MainApp.SETTING.initOwner(MainApp.MAINSTAGE);
MainApp.SETTING.setTitle("Settings");
}
}
public void show(){
if(!MainApp.SETTING.isShowing()) MainApp.SETTING.show();
}
}
This code works when I tried to run it as a desktop application. Im using Android 4.2.
Using JavaFXPorts you can change scenes and stages while running on Android.
I've modified the Gluon plugin for NetBeans default sample to achieve this, first switching scenes:
private Scene mainScene;
#Override
public void start(Stage stage) {
Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();
Label label = new Label("Main Scene");
StackPane root = new StackPane(label);
mainScene = new Scene(root, visualBounds.getWidth(), visualBounds.getHeight());
stage.setScene(mainScene);
stage.show();
label.setOnMouseClicked(e->{
Label labelSettings = new Label("Settings Scene. Click to go back");
StackPane rootSettings = new StackPane(labelSettings);
Scene settingsScene = new Scene(rootSettings, visualBounds.getWidth(), visualBounds.getHeight());
stage.setScene(settingsScene);
labelSettings.setOnMouseClicked(t->stage.setScene(mainScene));
});
}
Now switching stages:
private Scene mainScene;
#Override
public void start(Stage stage) {
Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();
Label label = new Label("Main Stage");
StackPane root = new StackPane(label);
root.setStyle("-fx-background-color: aquamarine;");
mainScene = new Scene(root, visualBounds.getWidth(), visualBounds.getHeight());
stage.setScene(mainScene);
stage.setTitle("Main Stage");
stage.show();
label.setOnMouseClicked(e->{
Label labelSettings = new Label("Settings Stage. Click to go back");
StackPane rootSettings = new StackPane(labelSettings);
rootSettings.setStyle("-fx-background-color: burlywood;");
Scene settingsScene = new Scene(rootSettings, visualBounds.getWidth(), visualBounds.getHeight());
Stage stage2 = new Stage();
stage2.setScene(settingsScene);
stage2.show();
labelSettings.setOnMouseClicked(t->stage2.hide());
});
}
And there's another possibility: you can use Gluon Charm, to manage different views.
Have a look at this project to get you started.

Categories

Resources