How to change between wireframe and solid in javafx - java

3d software allow user to change draw mode dinamically. It can be implemented on javafx ?

Changing draw mode with radio buttons
In this approach a Box instance change its DrawMode with radiobuttons.
This is a single class javafx you can try .
App.java
public class App extends Application {
#Override
public void start(Stage stage) {
var perspective = new PerspectiveCamera(true);
perspective.setNearClip(0.1);
perspective.setFarClip(500);
perspective.setTranslateZ(-150);
Shape3D cube = new Box(50, 50, 50);
cube.setCullFace(CullFace.NONE);
cube.setMaterial(new PhongMaterial(Color.CORAL));
var toggleGroup = new ToggleGroup();
var solid = new RadioButton("solid");
solid.setToggleGroup(toggleGroup);
solid.setSelected(true);
var wire = new RadioButton("wireframe");
wire.setToggleGroup(toggleGroup);
var hBox = new HBox(solid, wire);
toggleGroup.selectedToggleProperty().addListener((o) -> {
Toggle selectedToggle = toggleGroup.getSelectedToggle();
if (selectedToggle == solid) {
cube.setDrawMode(DrawMode.FILL);
}
if (selectedToggle == wire) {
cube.setDrawMode(DrawMode.LINE);
}
});
var group3d = new Group(perspective, cube);
var subscene = new SubScene(group3d, 300, 400, true, SceneAntialiasing.BALANCED);
subscene.setCamera(perspective);
var stack = new StackPane(subscene, hBox);
stage.setScene(new Scene(stack, 300, 400));
stage.show();
}
public static void main(String[] args) {
launch();
}
}

Related

How do I get the selected string from a combobox?

This is my main class. I'm trying to get the string that is being selected from the combobox and "get the wall color" from that string. The problem is that when I run the application, after hitting the playbutton I get an error saying that in line 75 - if (stringWallColor.equals("Default - Black")), stringWallColor is null.
Does that I mean that it uses the public static String stringWallColor which is null as default? And how can I fix this?
public static String stringWallColor;
public static void main(String[] args) {
launch(args);
System.out.println("Done!");
}
public void start(Stage primaryStage) throws Exception {
Main.primaryStage = primaryStage;
MenuBar MENU = new MenuBar();
MenuGenerator.menuCreator(MENU);
Button playButton = new Button("Play Game");
ComboBox<String> wallColorCombo = new ComboBox<>();
wallColorCombo.setPromptText("Choose wall color");
wallColorCombo.getItems().addAll(
"Default - Black",
"Dark Green",
"Dark Red",
"Dark Gray",
"Saddle Brown",
"Midnight Blue",
"Dark Magenta",
"Crimson",
"Navy");
stringWallColor = wallColorCombo.getSelectionModel().getSelectedItem();
gameGrid = new GridPane();
GridPane root = new GridPane();
root.add(MENU,0,0);
root.add(gameGrid, 0, 1);
gameScene = new Scene(root,600,625);
GridPane startGrid = new GridPane();
startGrid.setHgap(20);
startGrid.setVgap(20);
playButton.setLineSpacing(10);
startGrid.add(playButton,8,12);
startGrid.add(wallColorCombo,7,12);
GridPane root0= new GridPane();
root0.add(startGrid,0,1);
Scene startScene = new Scene(root0, 400, 400);
primaryStage.setScene(startScene);
primaryStage.setTitle(GameEngine.GAME_NAME);
primaryStage.show();
System.out.println("Default save file not loaded yet");
playButton.setOnAction(e -> {
MenuGenerator.loadDefaultSaveFile(primaryStage);
System.out.println("Default save file loaded");
primaryStage.setScene(gameScene); });
}
public static Color getWallColor() {
Color wallColor = Color.BLACK;
if (stringWallColor.equals("Default - Black"))
wallColor = Color.BLACK;
if (stringWallColor.equals("Dark Green"))
wallColor = Color.DARKGREEN;
if (stringWallColor.equals("Dark Red"))
wallColor = Color.DARKRED;
if (stringWallColor.equals("Dark Gray"))
wallColor = Color.DARKGRAY;
if (stringWallColor.equals("Saddle Brown"))
wallColor = Color.SADDLEBROWN;
if (stringWallColor.equals("Midnight Blue"))
wallColor = Color.MIDNIGHTBLUE;
if (stringWallColor.equals("Dark Magenta"))
wallColor = Color.DARKMAGENTA;
if (stringWallColor.equals("Crimson"))
wallColor = Color.CRIMSON;
if (stringWallColor.equals("Navy"))
wallColor = Color.NAVY;
return wallColor;
}
}
Solved by setting stringWallColor = wallColorCombo.getSelectionModel().getSelectedItem(); as an action for the playbutton.

Create eye-catching BarChart by JavaFx with Slider to view due to Category data so long

I'm trying to make bar chart by Javafx. However It quite small to see it.
I want to make it more attractive like
Here is code's program
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("JavaFX Chart Demo");
StackPane pane = new StackPane();
pane.getChildren().add(createBarChart());
stage.setScene(new Scene(pane, 400, 200));
stage.show();
}
public ObservableList<XYChart.Series<String, Double>>
getDummyChartData() {
ObservableList<XYChart.Series<String, Double>> data =
FXCollections.observableArrayList();
Series<String, Double> as = new Series<>();
Series<String, Double> bs = new Series<>();
Series<String, Double> cs = new Series<>();
Series<String, Double> ds = new Series<>();
Series<String, Double> es = new Series<>();
Series<String, Double> fs = new Series<>();
as.setName("A-Series");
bs.setName("B-Series");
cs.setName("C-Series");
ds.setName("D-Series");
es.setName("E-Series");
fs.setName("F-Series");
Random r = new Random();
for (int i = 1900; i < 2017; i += 10) {
as.getData().add(new XYChart.Data<>
(Integer.toString(i), r.nextDouble()));
bs.getData().add(new XYChart.Data<>
(Integer.toString(i), r.nextDouble()));
cs.getData().add(new XYChart.Data<>
(Integer.toString(i), r.nextDouble()));
ds.getData().add(new XYChart.Data<>
(Integer.toString(i), r.nextDouble()));
es.getData().add(new XYChart.Data<>
(Integer.toString(i), r.nextDouble()));
fs.getData().add(new XYChart.Data<>
(Integer.toString(i), r.nextDouble()));
}
data.addAll(as, bs, cs, ds, es, fs);
return data;
}
public XYChart<CategoryAxis, NumberAxis>
createBarChart() {
CategoryAxis xAxis = new CategoryAxis();
NumberAxis yAxis = new NumberAxis();
BarChart bc = new BarChart<>(xAxis, yAxis);
bc.setData(getDummyChartData());
bc.setTitle("Bar Chart on Random Number");
return bc;
}
}
Please help me how to get it by Javafx. I found it can be solve by JFree Chart However.I don't know how to make it by BarChart javafX. It's really challenge to me these day. Thank you
Just make the chart in a scroll pane.
public void start(Stage stage) throws Exception {
stage.setTitle("JavaFX Chart Demo");
StackPane stackPane = new StackPane();
stackPane.setPrefSize(1000, 200);
stackPane.getChildren().add(createBarChart());
ScrollPane scrollPane = new ScrollPane();
scrollPane.setPrefSize(400, 220);
scrollPane.setContent(stackPane);
stage.setScene(new Scene(scrollPane));
stage.show();
}

JavaFX CheckBoxTreeItem graphic disappear/appear when expanding/collapsing

I'm trying to make TreeView with CheckBoxTreeItems. When I collapse/expand a CheckBoxTreeItems the image I set up does not display correctly. I googled but I couldn't find correct answer. On Stack Overflow, I found a similar problem, but I didn't get a valid answer.
E.g
JavaFX CheckBoxTreeItem graphic disappear when siblings collapse
JavaFX CheckBoxTreeItem: Graphic disappears if graph is extended
Any ideas?
public class ClientApplication extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(final Stage stage) {
ImageView folderIcon = new ImageView();
Image folderImage = new Image("image/folder.png");
folderIcon.setImage(folderImage);
folderIcon.setFitWidth(16);
folderIcon.setFitHeight(16);
CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem<String>("folder", folderIcon);
rootItem.setExpanded(true);
for (int i = 0; i < 4; i++) {
CheckBoxTreeItem<String> checkBoxTreeItem = new CheckBoxTreeItem<String>("Sample" + (i + 1), folderIcon);
rootItem.getChildren().add(checkBoxTreeItem);
}
final TreeView<String> tree = new TreeView<String>(rootItem);
tree.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
tree.setRoot(rootItem);
tree.setShowRoot(true);
StackPane root = new StackPane();
root.getChildren().add(tree);
stage.setScene(new Scene(root, 300, 250));
stage.show();
}
}
enter image description here
I tried to use the ideas provided by #Jai,But when I click the expand/collapse icon, there is still a problem.Attachment is a screenshot.Thanks in advance.
enter image description here
ImageView is a JavaFX control. This means that each instance represents a unique control you see on your screen. You should never use the same instance for multiple locations in your GUI.
On the other hand, Image represents an image (i.e. an array of pixel data), so it is reusable.
This should work:
#Override
public void start(final Stage stage) {
final Image folderImage = new Image("image/folder.png");
CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem<String>("folder", createImageView(folderImage));
rootItem.setExpanded(true);
for (int i = 0; i < 4; i++) {
CheckBoxTreeItem<String> checkBoxTreeItem = new CheckBoxTreeItem<String>("Sample" + (i + 1), createImageView(folderImage));
rootItem.getChildren().add(checkBoxTreeItem);
}
final TreeView<String> tree = new TreeView<String>(rootItem);
tree.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
tree.setRoot(rootItem);
tree.setShowRoot(true);
StackPane root = new StackPane();
root.getChildren().add(tree);
stage.setScene(new Scene(root, 300, 250));
stage.show();
}
private ImageView createImageView(Image folderImage) {
ImageView folderIcon = new ImageView();
folderIcon.setImage(folderImage);
folderIcon.setFitWidth(16);
folderIcon.setFitHeight(16);
return folderIcon;
}

Listen for transformation changes

Is there way to listen for transformation changes? I'd like to get notified when for example a cube has turned. Especially I'am interested in getLocalToSceneTransform.
Here is my try:
#Override
public void start(Stage primaryStage) throws Exception {
final Group root = new Group();
final Scene scene = new Scene(root);
final Box cube = new Box(1, 1, 1);
cube.setRotationAxis(Rotate.Y_AXIS);
cube.setMaterial(new PhongMaterial(Color.RED));
root.getChildren().add(cube);
cube.getLocalToSceneTransform().addEventHandler(TransformChangedEvent.TRANSFORM_CHANGED, (e) -> {
// never get called
System.out.println("Transformation has changed");
});
final Camera camera = new PerspectiveCamera(true);
camera.setTranslateZ(-4);
scene.setCamera(camera);
final Timeline turnCube = new Timeline();
turnCube.getKeyFrames().add(new KeyFrame(Duration.seconds(0), new KeyValue(cube.rotateProperty(), 0)));
turnCube.getKeyFrames().add(new KeyFrame(Duration.seconds(5), new KeyValue(cube.rotateProperty(), 360)));
turnCube.setCycleCount(Timeline.INDEFINITE);
turnCube.play();
primaryStage.setWidth(1024);
primaryStage.setHeight(768);
primaryStage.setScene(scene);
primaryStage.show();
}
While the cube is turned the EventHandler get never called.
You can add a changeListener to the cube's localToSceneTransformProperty() to get notified when the cube is rotated.
cube.localToSceneTransformProperty().addListener((value, oldValue, newValue) -> {
System.out.println("Transformation has changed");
});

Why does Transform in JavaFX looks like 3D?

Looks like Transform class in JavaFX contains 3 coordinates (x, y and z).
What will happen if I rotate out of plane? Will it do perspective?
UPDATE
Actually object disappears if rotated out of plane even by 1 degree. Why?
public class TransformTry extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Drawing Operations Test");
Group root = new Group();
Canvas canvas = new Canvas(300, 250);
//canvas.getTransforms().add(new Rotate(1, new Point3D(0, 1, 0))); // square disappears
canvas.getTransforms().add(new Rotate(1, new Point3D(0, 0, 1))); // rotates correctly
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.strokeRect(-50, -50, 100, 100);
root.getChildren().add(canvas);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
}
UPDATE 2
I found a way to use perspective camera, but it works strange: it looks always from above the center of a window, so out-of-plane object changes on window resize:
public class ShapeTry01 extends Application {
#Override
public void start(Stage stage) throws Exception {
Shape shape = new Rectangle(100,100,50,50);
shape.setStroke(Color.RED);
shape.setFill(null);
Group group = new Group();
group.getChildren().add(shape);
//group.getTransforms().add(new Rotate(10, new Point3D(0, 0, 1)));
group.getTransforms().add(new Rotate(10, new Point3D(0, 1, 0)));
PerspectiveCamera camera = new PerspectiveCamera();
camera.setFieldOfView(45);
Scene scene = new Scene(group);
scene.setCamera( camera );
stage.setTitle("ShapeTry01");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
JavaFX 2 was started with 3D in mind, thus a lot of API has z coordinate mentioned. But actually useful 3D was added only in JavaFX8 (to be released in next year).
You can see documentation here: http://docs.oracle.com/javafx/8/3d_graphics/jfxpub-3d_graphics.htm and try developers preview: https://jdk8.java.net/download.html

Categories