I want to render an array of buttons and then a piechart to the screen. I've tried almost every method I could but something doesn't seems to work. either alone array of buttons(usercontrol()) or pie(the graph) can be render but when I try to do both it only render the array of buttons.plz don't worry about return types of function. any help will be really appreciated.
public class Layout {
// returns Windows height and width
private final double width = 600;
private final double height = 400;
private Button[] userControl() { // navigation bar buttons
Button[] buttons = new Button[3];
buttons[0] = new Button("BUY Share!"); // Buy shares buttons
buttons[0].setLayoutX(width - 100);
buttons[0].setLayoutY(10);
buttons[1] = new Button("Sell Shares!"); // Sell shares buttons
buttons[1].setLayoutX(width - 200);
buttons[1].setLayoutY(10);
buttons[2] = new Button("Show Share"); // Show shares buttons
buttons[2].setLayoutX(width - 300);
buttons[2].setLayoutY(10);
return buttons;
}
public void pie() {
ObservableList<PieChart.Data> shareHolders
= FXCollections.observableArrayList(
new PieChart.Data("user1", 13),
new PieChart.Data("user2", 25),
new PieChart.Data("user3", 10),
new PieChart.Data("user4", 22),
new PieChart.Data("user5", 30));
PieChart chart = new PieChart(shareHolders);
chart.setTitle("Share Holders Shares");
VBox pie = new VBox();
pie.setLayoutY(100);
pie.getChildren().addAll(chart);
pane().getChildren().add(pie);
// return pie;
}
private Pane pane() {
Pane pane = new Pane();
pane.getChildren().addAll(userControl());
return pane;
}
public Stage window() {
//pane().getChildren().add();
pie();
Scene scene = new Scene(pane(), 600, 400);
Stage primaryStage = new Stage();
primaryStage.setScene(scene);
primaryStage.setTitle("ShareHolders!");
primaryStage.show();
return primaryStage;
}
}
Your problem is that you are creating a new Pane every time you call the pane method. You need to change it, perhaps by using a global Pane object.
//First, declare a global Pane.
static Pane pane = new Pane();
//Make your pie() method return the pie VBox.
public VBox pie() {
/*Blah blah blah, making the pie...*/
return pie//Remember, pie is a VBox, which is why we are returning the VBox.
}
//Later, when you build your window, add the pie and the buttons to the GLOBAL PANE...
public Stage window() {
pane.getChildren().add(pie()); //...right here.
pane.getChildren().addAll(userControl());
/*Build the primary stage...*/
return primaryStage;
}
This should get you your desired result.
Related
I am new to java fx. I am creating a basic GUI which is meant to look like this:
However, when I try my image looks like this:
I am unsure as to why there is a large gap between the two buttons. I am using the grid pane format.
Here is my code:
public class Main extends Application {
#Override
public void start(Stage stage) {
//Creating Text field
TextField textField1 = new TextField();
//Creating Buttons
Button submit = new Button("Submit");
Button cancel = new Button("Cancel");
//Creating a Grid Pane
GridPane gridPane = new GridPane();
//Setting size for the pane
gridPane.setMinSize(200, 100);
//Setting the padding
gridPane.setPadding(new Insets(10, 10, 10, 10));
//Setting the vertical and horizontal gaps between the columns
gridPane.setVgap(5);
gridPane.setHgap(1);
//Setting the Grid alignment
gridPane.setAlignment(Pos.CENTER);
//Arranging all the nodes in the grid
gridPane.add(textField1, 0, 0);
gridPane.add(submit, 0, 1);
gridPane.add(cancel, 1,1);
//Creating a scene object
Scene scene = new Scene(gridPane);
//Setting title to the Stage
stage.setTitle("Simple Form");
//Adding scene to the stage
stage.setScene(scene);
//Displaying the contents of the stage
stage.show();
}
public static void main(String args[]){
launch(args);
}
}
Help would be appreciated :-)
What happens here is that your TextField is set in the top-left corner (0,0), but only spans a single column. You can see that the cancel Button, which is in the bottom right corner (1,1), starts where the TextField stops (if you look only at the x-position).
There is a debug option for GridPanes so you can visualize more what happens. Just call
gridPane.setGridLinesVisible(true):
The solution for this is to set the TextField to obtain/span 2 columns. You can do so by either calling:
GridPane.setColumnSpan(textField1, 2);
Or use a different add method:
gridPane.add(textField1, 0, 0, 2, 1);
See https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/GridPane.html for more information about how the GridPane works.
I have a BorderPane with Panes for left, right and center elements and HBox for top element. On the right Pane there is a Label. The Label contains some text, which doesn't wrap and therefore gets cut.
public class Main extends Application implements EventHandler<ActionEvent> {
private static BorderPane gamePane;
private static Pane cellsPane;
private static HBox buttonsPane;
private static Pane statsPane;
private static Pane setupsPane;
Label cellsCountLabel;
static int gameWidth= 700;
static int gameHeight=600;
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Hello World");
gamePane = new BorderPane();
buttonsPane = new HBox(5);
statsPane = new Pane();
cellsPane = makeGrid(20);
setupsPane = new Pane();
cellsPane.setStyle("-fx-background-color: #ffffff; -fx-border-color: black");
buttonsPane.setStyle("-fx-background-color: #f2f2f2; -fx-border-color: black");
statsPane.setStyle("-fx-background-color: #f2f2f2; -fx-border-color: black");
setupsPane.setStyle("-fx-background-color: #f2f2f2; -fx-border-color: black");
cellsPane.setMaxWidth(400);
statsPane.setMaxWidth((gameWidth-400)/2);
setupsPane.setMaxWidth((gameWidth-400)/2);
createCellButton = new Button();
deleteCellsButton = new Button();
createCellButton.setText("Create a cell");
deleteCellsButton.setText("Delete cells");
...
buttonsPane.setSpacing(10);
buttonsPane.setPadding(new Insets(10, 10, 10, 10));
buttonsPane.getChildren().add(createCellButton);
buttonsPane.getChildren().add(deleteCellsButton);
gamePane.setTop(buttonsPane);
gamePane.setCenter(cellsPane);
...
cellsCountLabel = new Label("Cells Count: " + (cellId + 1));
statsPane.getChildren().add(cellsCountLabel);
gamePane.setLeft(statsPane);
setupsPane.getChildren().add(new Label("Setups Panel1111115552222222133331111"));
gamePane.setRight(setupsPane);
gamePane.setMargin(statsPane, new Insets(0, 0, 0, 0));
gamePane.setMargin(cellsPane, new Insets(0,0,0,0));
gamePane.setMargin(setupsPane, new Insets(0,0,0,0));
statsPane.setPrefWidth(150);
setupsPane.setPrefWidth(150);
cellsCountLabel.setWrapText(true); //doesn't work
Scene scene = new Scene(gamePane, gameWidth, gameHeight);
primaryStage.setScene(scene);
...
primaryStage.show();
}
...
}
However, there exists space between left, center and right Panes. The space gets smaller as the content in those Panes get larger, however, when it gets too large it messes with the center Pane.
I tried using cellsCountLabel.setWrapText(true), but it didn't work.
Try this
Label label = new Label("Setups Panel1111115552222222133331111");
label.setWrapText(true);
label.setMaxWidth((gameWidth-400)/2);
setupsPane.getChildren().add(label);
Also if you go this route you may want to declare something like this
static double sidePaneWidth = (gameWidth-400)/2;
for later use
You can also make this into a function like so if necessary
private Label newSidePaneLabel(String labelString){
Label label = new Label(labelString);
label.setWrapText(true);
label.setMaxWidth(sidePaneWidth);
return label;
}
I am basically new to Java FX 2.
Scenario:
I have 3 Scenes and I want a way to add menu-bar such that I don't i don't want to explicitly remove the menu bar from previous scene and add it to new one. Like Some thing a Parent Scene or some way menu-bar is attached to Stage. I mean menu-bar is added just one time and always be present whatever scene is in front or not.
If This is Possible How Can I do this.
Here is the Default Example Provided by Oracle Docs of JavaFX http://docs.oracle.com/javafx/2/ui_controls/MenuSample.java.html
public class Main extends Application {
final ImageView pic = new ImageView();
final Label name = new Label();
final Label binName = new Label();
final Label description = new Label();
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
stage.setTitle("Menu Sample");
Scene scene = new Scene(new VBox(), 400, 350);
scene.setFill(Color.OLDLACE);
MenuBar menuBar = new MenuBar();
// --- Graphical elements
final VBox vbox = new VBox();
vbox.setAlignment(Pos.CENTER);
vbox.setSpacing(10);
vbox.setPadding(new Insets(0, 10, 0, 10));
makeContentsForVBox();// in this vBox area will be fill with name pic desrciption
vbox.getChildren().addAll(name, binName, pic, description); // name is lable
// --- Menu File
Menu menuFile = new Menu("File");
MenuItem add = new MenuItem("Shuffle",
new ImageView(new Image(getClass().getResourceAsStream("new.png"))));
add.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
shuffle();
vbox.setVisible(true);
}
});
MenuItem clear = new MenuItem("Clear");
clear.setAccelerator(KeyCombination.keyCombination("Ctrl+X"));
clear.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
vbox.setVisible(false);
}
});
MenuItem exit = new MenuItem("Exit");
exit.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
System.exit(0);
}
});
menuFile.getItems().addAll(add, clear, new SeparatorMenuItem(), exit);
((VBox) scene.getRoot()).getChildren().addAll(menuBar, vbox);
stage.setScene(scene);
stage.show();
}
}
So Here menuBar is added to a scene. if i swap the scene and bring an other scene in front ... What will i do. i think I remove menuBar from this scene and add to other or simply add to new one. so every time i have to do this when i change. Is there any way to avoid this??
The approach I would prefer is to use a Scene with BorderPane as its root
scene.setRoot(borderPane);
You can add the MenuBar to the top of the BorderPane and at its Center you can place SplitPane
BorderPane borderPane = new BorderPane();
borderPane.setTop(menuBar);
borderPane.setCenter(splitPane);
Whenever you need to switch to WebView just replace it with SplitPane :
borderPane.setCenter(webView);
Following this approach, your MenuBar will always remain on TOP and you can switch between SplitPane and WebView
I'm working on this example which is not working properly:
public class test extends Application
{
private void init(Stage primaryStage)
{
Group root = new Group();
primaryStage.setScene(new Scene(root));
String pillButtonCss = DX57DC.class.getResource("PillButton.css").toExternalForm();
// create 3 toggle buttons and a toogle group for them
ToggleButton tb1 = new ToggleButton("Left Button");
tb1.setId("pill-left");
ToggleButton tb2 = new ToggleButton("Center Button");
tb2.setId("pill-center");
ToggleButton tb3 = new ToggleButton("Right Button");
tb3.setId("pill-right");
final ToggleGroup group = new ToggleGroup();
tb1.setToggleGroup(group);
tb2.setToggleGroup(group);
tb3.setToggleGroup(group);
// select the first button to start with
group.selectToggle(tb1);
//////////////////////////////////////////
final VBox vbox = new VBox();
final Rectangle rect1 = new Rectangle(300, 300);
rect1.setFill(Color.ALICEBLUE);
final Rectangle rect2 = new Rectangle(300, 300);
rect2.setFill(Color.AQUA);
final Rectangle rect3 = new Rectangle(300, 300);
rect3.setFill(Color.AZURE);
tb1.setUserData(rect1);
tb2.setUserData(rect2);
tb3.setUserData(rect3);
group.selectedToggleProperty().addListener(new ChangeListener<Toggle>()
{
#Override
public void changed(ObservableValue<? extends Toggle> ov, Toggle toggle, Toggle new_toggle)
{
if (new_toggle == null)
{
//rect.setFill(Color.WHITE);
}
else
{
vbox.getChildren().addAll((Node[]) group.getSelectedToggle().getUserData());
//rect.setFill((Color) group.getSelectedToggle().getUserData());
}
}
});
///////////////////////////////////////////
HBox hBox = new HBox();
hBox.getChildren().addAll(tb1, tb2, tb3);
hBox.setPadding(new Insets(20, 20, 260, 20));
hBox.getStylesheets().add(pillButtonCss);
vbox.getChildren().add(hBox);
//vbox.getChildren().add(rect);
root.getChildren().add(vbox);
}
#Override
public void start(Stage primaryStage) throws Exception
{
init(primaryStage);
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
I want to create several Rectangles(or object in which or object) in which I want to store data. I want to switch the Rectangles(objects) which are displayed in front of the user using the buttons. The example which I implemented is not working properly. Can you tell me what is the proper way to implement this?
You could create a Stackpane with the Rectangle and a Label with Text on top of it (if thats the data you want to store). Alternatively you can also set the Background of any Pane to have a colored Rectangle.
Than add this Pane as Userdata to the corresponding button and add the buttons userdata to your VBox on toggle.
final StackPane rect1pane = new StackPane();
final Rectangle rect1 = new Rectangle(300, 300);
rect1pane.getChildren().add(rect1);
rect1pane.getChildren().add(new Label("Some text"));
tb1.setUserData(rect1pane);
togglePropertyListener:
...
else{
//Delete rectangles added before ( or check if this one isnt already dispayed)
if(group.getSelectedToggle().getUserData() instanceof Node)
vbox.getChildren().add((Node)group.getSelectedToggle().getUserData());
}
If you just want your example code to work change:
vbox.getChildren().addAll((Node[]) group.getSelectedToggle().getUserData());
to
vbox.getChildren().addAll((Node) group.getSelectedToggle().getUserData());
Because your just adding the Rectangle of the Selected ToggleButton it is only one and not an array.
Make your window bigger after a click to see the rectanlge (the 260px bottom padding doesn't help because even if the space is empty below hbox, it still is part of the hbox and cant get used by your added rectangle) or just move
group.selectToggle(tb1);
to the last line of your init method ;)
Since updating to JavaFX 2.0 b36 (SDK for Windows (32Bit) + Netbeans Plugin) from a previous JavaFX 2.0 version the SplitPane control does not work as expected any longer.
The divider can't be moved
The divider position is not as expected
The sizing of the contained sides is not as expected
Here my example code for a SplitPane .
public class FxTest extends Application {
public static void main(String[] args) {
Application.launch(FxTest.class, args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("SplitPane Test");
Group root = new Group();
Scene scene = new Scene(root, 200, 200, Color.WHITE);
Button button1 = new Button("Button 1");
Button button2 = new Button("Button 2");
SplitPane splitPane = new SplitPane();
splitPane.setPrefSize(200, 200);
splitPane.setOrientation(Orientation.HORIZONTAL);
splitPane.setDividerPosition(0, 0.7);
splitPane.getItems().addAll(button1, button2);
root.getChildren().add(splitPane);
primaryStage.setScene(scene);
primaryStage.setVisible(true);
}
}
As you can (hopefully) see the left side is clearly smaller than the right side.
Another funny fact is, when you change orientation to VERTICAL
splitPane.setOrientation(Orientation.VERTICAL);
and try to move the divider up or down you get some console output saying 'HERE'.
Looks like some test output.
What's the issue with this?
To get the SplitPane working as expected add a layout (e.g. BorderPane) to each side. Add the controls to display to each of these layouts. I think this should be made more clear in API documentation!
public class FxTest extends Application {
public static void main(String[] args) {
Application.launch(FxTest.class, args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("SplitPane Test");
Group root = new Group();
Scene scene = new Scene(root, 200, 200, Color.WHITE);
//CREATE THE SPLITPANE
SplitPane splitPane = new SplitPane();
splitPane.setPrefSize(200, 200);
splitPane.setOrientation(Orientation.HORIZONTAL);
splitPane.setDividerPosition(0, 0.7);
//ADD LAYOUTS AND ASSIGN CONTAINED CONTROLS
Button button1 = new Button("Button 1");
Button button2 = new Button("Button 2");
BorderPane leftPane = new BorderPane();
leftPane.getChildren().add(button1);
BorderPane rightPane = new BorderPane();
rightPane.getChildren().add(button2);
splitPane.getItems().addAll(leftPane, rightPane);
//ADD SPLITPANE TO ROOT
root.getChildren().add(splitPane);
primaryStage.setScene(scene);
primaryStage.setVisible(true);
}
}