How to change Rectangles with buttons - java

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 ;)

Related

Using JavaFX and Gluon, how do you change from loginPage to the MainMenu when the button is clicked?

I am new to the gluon application. I have used JavaFX and I am building a mobile application. The Login Page worked on its on and now I am trying to configure it to go to the main menu when the button is clicked. I am unsure how to set this up and if you need the init method to be adjusted.
I have tried adding another addViewFactory but that does not work. I tried to create a button with an action but the code fails to load after
This is the main file the application creates
public class AlexDemo extends MobileApplication {
#Override
public void init() {
addViewFactory(HOME_VIEW, LoginPage::new);
}
#Override
public void postInit(Scene scene) {
Swatch.BLUE.assignTo(scene);
((Stage) scene.getWindow()).getIcons().add(new Image(AlexDemo.class.getResourceAsStream("/icon.png")));
}
}
This is the Login Page
public class LoginPage extends View {
private Parent root;
private LoginPage(BorderPane root) {
super(root);
Scene scene = new Scene(root, 500, 800);
//For the label displaying "Sign In" to prompt the user
VBox login = new VBox();
Label statement = new Label("Sign In");
statement.setFont(Font.font("Verdana", FontWeight.BOLD, 13));
//HBox for the email the user wants to sign in with
HBox firstUserPrompt = new HBox();
Label email = new Label("Username/\nEmail: ");
email.setFont(Font.font("Verdana", 13));
firstUserPrompt.setAlignment(Pos.CENTER);
TextField userPrompt = new TextField();
firstUserPrompt.getChildren().addAll(email, userPrompt);
//HBox for the password the user wants to sign in with
HBox secondUserPrompt = new HBox();
Label password = new Label("Password: ");
password.setFont(Font.font("Verdana", 13));
secondUserPrompt.setAlignment(Pos.CENTER);
TextField userPrompt2 = new TextField();
secondUserPrompt.getChildren().addAll(password, userPrompt2);
//Sign in Button if the account exists
Button signIn = new Button("Sign In");
signIn.setMaxSize(150, 200);
signIn.setFont(Font.font("Verdana", 13));
/* signIn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
MainMenu main = new MainMenu(root, stage);
scene.setRoot(main);
primaryStage.setTitle("Main Menu");
primaryStage.setWidth(500);
primaryStage.setHeight(800);
});*/
//*** ADD SPACING BETWEEN SIGN IN AND SIGN UP ***
//If user does not have an account
VBox newAccount = new VBox();
Label noAccount = new Label("Don't have an account? Sign up here: ");
noAccount.setFont(Font.font("Verdana", FontWeight.BOLD, 13));
Button signUp = new Button("Create Account");
signUp.setMaxSize(150, 200);
signUp.setFont(Font.font("Verdana", 13));
newAccount.setSpacing(15);
newAccount.setAlignment(Pos.TOP_CENTER);
newAccount.setMargin(statement, new Insets(55, 25, 55, 25));
newAccount.getChildren().addAll(noAccount, signUp);
root.setBottom(newAccount);
//makes everything set vertically following one after another
setCenter(login);
login.setSpacing(15);
login.setAlignment(Pos.TOP_CENTER);
login.setMargin(statement, new Insets(55, 25, 55, 25));
login.setPadding(new Insets(0, 20, 10, 20));
login.getChildren().addAll(statement, firstUserPrompt, secondUserPrompt, signIn, newAccount);
}
public LoginPage() {
this(new BorderPane());
}
#Override
protected void updateAppBar(AppBar appBar) {
appBar.setTitleText("Book App");
appBar.setSpacing(115);
}
}
This is the main menu for now. Have more code here not shown which sets up the main menu
public class MainMenu extends View{
private final Parent prevPage;
private final Stage stage;
public MainMenu(Parent LoginPage, Stage stage){
this.prevPage = LoginPage;
this.stage = stage;
Label statement = new Label("Sign In");
}
}
When the button is clicked on the login page it should send me to the main menu page
For starters I'd suggest you have a look at the Gluon Mobile docs, to see how views work.
Also you should check the many different samples, that in many cases contain several views, so you can see how to switch from one view to another.
And you should try to use the Gluon plugin for your IDE, that will create an initial project for you with 2 views.
Now about your issues:
I have tried adding another addViewFactory but that does not work
That is the way you should use to add as many views as needed.
#Override
public void init() {
addViewFactory(HOME_VIEW, LoginPage::new);
addViewFactory("MainView", MainView::new);
...
}
About how you create your views, this is unnecessary:
public class LoginPage extends View {
private Parent root;
private LoginPage(BorderPane root) {
super(root);
Scene scene = new Scene(root, 500, 800);
VBox login = new VBox();
...
root.setBottom(newAccount);
setCenter(login);
...
VBox newAccount = new VBox();
...
root.setBottom(newAccount);
}
public LoginPage() {
this(new BorderPane());
}
}
For starters, View extends from BorderPane, and Gluon Mobile manages the views to get added to the scene, so you shouldn't need a Scene.
Your code above can be simplified to:
public class LoginPage extends View {
public LoginPage() {
VBox login = new VBox();
...
setCenter(login);
...
VBox newAccount = new VBox();
...
setBottom(newAccount);
}
}
About the MainMenu view, it can be simplified as well to:
public class MainMenu extends View {
public MainMenu() {
Label statement = new Label("Sign In");
setCenter(statement);
}
}
About switching views, for instance to switch from the home view to the MainMenu, you can simply do:
Button signIn = new Button("Sign In");
signIn.setOnAction(e ->
MobileApplication.getInstance().switchView("MainView"));
Or if you log out from main menu, you can go back to the home view:
Button logOut = new Button("Log Out");
logOut.setOnAction(e ->
MobileApplication.getInstance().goHome());

chart and Button in javafx doesn't render

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.

Cannot find a way to switch scenes with a button from class JavaFX

I'm trying to make a my scene switch to another when you click my button
My problem is in my second button in my class I am not sure what to put in it, I can't set the stage from inside that button because it is in another method I need to set about 10 different scenes, very confused any help is appreciated its a school culminating -_-. (If there is any better way to make a program that changes picture please inform me thank you!)
public class MainStage extends Application {
SceneSwitch switcher1= new SceneSwitch();
MediaPlayer mp3;
String i="file:///C://NetbeanFiles//plane.jpg";
Image pic=new Image(i);
#Override
public void start(Stage primaryStage) {
Media musicfile=new Media("file:///C://NetbeanFiles//Stereo.mp3");
mp3= new MediaPlayer(musicfile);
mp3.setAutoPlay(true);
mp3.setVolume(0.05);
ImageView view = new ImageView(pic);
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
primaryStage.setScene(switcher1.Switcher());
}
});
BorderPane pane = new BorderPane();
pane.setCenter(view);
btn.setPadding(new Insets(10 ,10, 10, 10));
pane.setTop(btn);
Scene scene = new Scene(pane, 1920, 1080);
//how to keep button centered last number is X
pane.setMargin(btn, new Insets(10, 10, 10, 875));
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
//End of MAINSTAGE
//Start of SCENESWITCH class
public class SceneSwitch {
int j=0;
String i="file:///C://NetbeanFiles//planet.jpg";
ArrayList<String> Hello= new ArrayList<String>();
public SceneSwitch(){
Hello.add("file:///C://NetbeanFiles//planet.jpg");
`Hello.add("file:///C://NetbeanFiles//download.jpg");
}
public Scene Switcher(){
ImageView view = new ImageView(Hello.get(j));
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
//**HERE IS MY PROBLEM NOT SURE WHAT TO PUT IN HERE**
}
});
BorderPane pane = new BorderPane();
pane.setCenter(view);
btn.setPadding(new Insets(10 ,10, 10, 10));
pane.setTop(btn);
Scene scene = new Scene(pane, 1920, 1080);
//how to keep button centered last number is X
pane.setMargin(btn, new Insets(10, 10, 10, 875));
return scene;
}
}

How to Achieve One Menubar for more then one scenes in javaFx

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

JavaFX 2.0 SplitPane no longer working as expected

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);
}
}

Categories

Resources