I am working on JavaFX . I have a java file that includes the design configuration.I need to write the same as an fxml file,that java FX allows.For eg:
GridPane gridPane = new GridPane();
Label label = new Label();
label.setText("My Label");
GridPane.setRowIndex(label, 0);
GridPane.setColumnIndex(label, 0);
gridPane.getChildren().add(label);
The Fxml equivalents is:
<GridPane>
<children>
<Label text="My Label">
<GridPane.rowIndex>0</GridPane.rowIndex>
<GridPane.columnIndex>0</GridPane.columnIndex>
</Label>
</children>
</TabPane>.
Now I am using more than one layouts like vbox,hbox along with gridpane.how can i generate the fxml for that?
Java code is given below.Please help in generating its fxml.
VBox vBox = new VBox();
vBox.setSpacing(10);
vBox.setPadding(new Insets(60, 0, 0, 20));
vBox.setAlignment(Pos.TOP_CENTER);
HBox hbox= new HBox();
hbox.setPadding(new Insets(1,0,0,770));
hbox.setSpacing(2);
hbox.setAlignment(Pos.CENTER);
GridPane homegrid = new GridPane();
homegrid.setPadding(new Insets(100, 100, 90, 50));
homegrid.setVgap(5);
homegrid.setHgap(5);
Button employee = new Button("");
employee.setUserData(Font.BOLD);
employee.setMinSize(100, 100);
homegrid.setConstraints(employee, 10,10);
homegrid.getChildren().addAll(employee,shop,product,datamanager,leave,users);
rootGroup.getChildren().addAll(vb);
rootGroup.getChildren().addAll(homegrid,hbox);
The easiest way now is to try Oracle's SceneBuilder -- new UI design tool for JavaFX. You design app by visual tool and will get FXML as a result.
Public beta was released yesterday: http://fxexperience.com/2012/04/announcing-javafx-scene-builder-public-beta/
Related
Hello I am new to Xamarin Development and I am currently working on PCL project.
I did implementation of the Navigation drawer using MasterDetailsPage concept. It is working fine.
But issue I am facing is that MasterDetailsPage is coming with the Blue Color Actionbar and menu icon to open/close navigation drawer.I need to override it with black color. Kindly suggest something.
I have mentioned the code I am currently using.
Also, there is whitespace appearing, I want get rid of it.
On below URl they have mentioned some ways, as I am new to this not able to write the CustomRenderer for each platform.
https://forums.xamarin.com/discussion/comment/244966/#Comment_244966
Please giude me how to write a customrenderer to remove that white space as well as change color of toolbar.
Code:
My XAML File :
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:WYH_XAMARIN.MasterDetailPageNavigation"
x:Class="WYH_XAMARIN.MasterDetailPageNavigation.NavigationDrawerPage">
<MasterDetailPage.Master>
<ContentPage Title="Menu"
BackgroundColor="#e8e8e8">
<StackLayout Orientation="Vertical">
<!--
This StackLayout you can use for other
data that you want to have in your menu drawer
-->
<StackLayout BackgroundColor="#e74c3c"
HeightRequest="75">
<Label Text="Some Text title"
FontSize="20"
VerticalOptions="CenterAndExpand"
TextColor="White"
HorizontalOptions="Center"/>
</StackLayout>
<ListView x:Name="navigationDrawerList"
RowHeight="60"
SeparatorVisibility="None"
BackgroundColor="#e8e8e8"
ItemSelected="OnMenuItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<!-- Main design for our menu items -->
<StackLayout VerticalOptions="FillAndExpand"
Orientation="Horizontal"
Padding="20,10,0,10"
Spacing="20">
<Image Source="{Binding Icon}"
WidthRequest="40"
HeightRequest="40"
VerticalOptions="Center" />
<Label Text="{Binding Title}"
FontSize="Medium"
VerticalOptions="Center"
TextColor="Black"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
</NavigationPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
and my class file is :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WYH_XAMARIN.PojoClasses;
using Xamarin.Forms;
namespace WYH_XAMARIN.MasterDetailPageNavigation
{
public partial class NavigationDrawerPage : MasterDetailPage
{
LoginSuccessfullResponse loginSuccessResponse;
public List<MasterPageItem> menuList { get; set; }
public NavigationDrawerPage()
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
menuList = new List<MasterPageItem>();
// Creating our pages for menu navigation
// Here you can define title for item,
// icon on the left side, and page that you want to open after selection
var page1 = new MasterPageItem() { Title = "My Profile", Icon = "icon.png", TargetType = typeof(TestPage1) };
var page2 = new MasterPageItem() { Title = "Service Booking", Icon = "icon.png", TargetType = typeof(TestPage2) };
var page3 = new MasterPageItem() { Title = "Item 3", Icon = "icon.png", TargetType = typeof(TestPage3) };
// Adding menu items to menuList
menuList.Add(page1);
menuList.Add(page2);
menuList.Add(page3);
// Setting our list to be ItemSource for ListView in MainPage.xaml
navigationDrawerList.ItemsSource = menuList;
// Initial navigation, this can be used for our home page
Detail = new NavigationPage((Page)Activator.CreateInstance(typeof(TestPage1)));
}
public NavigationDrawerPage(LoginSuccessfullResponse loginSuccessResponse)
{
this.loginSuccessResponse = loginSuccessResponse;
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
menuList = new List<MasterPageItem>();
// Creating our pages for menu navigation
// Here you can define title for item,
// icon on the left side, and page that you want to open after selection
var page1 = new MasterPageItem() { Title = "My Profile", Icon = "icon.png", TargetType = typeof(TestPage1) };
var page2 = new MasterPageItem() { Title = "Service Booking", Icon = "icon.png", TargetType = typeof(TestPage2) };
var page3 = new MasterPageItem() { Title = "Item 3", Icon = "icon.png", TargetType = typeof(TestPage3) };
// Adding menu items to menuList
menuList.Add(page1);
menuList.Add(page2);
menuList.Add(page3);
// Setting our list to be ItemSource for ListView in MainPage.xaml
navigationDrawerList.ItemsSource = menuList;
// Initial navigation, this can be used for our home page
Detail = new NavigationPage((Page)Activator.CreateInstance(typeof(TestPage1)));
}
// Event for Menu Item selection, here we are going to handle navigation based
// on user selection in menu ListView
private void OnMenuItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = (MasterPageItem)e.SelectedItem;
Type page = item.TargetType;
Detail = new NavigationPage((Page)Activator.CreateInstance(page));
IsPresented = false;
}
}
}
Guys please help me to resolve this.
Any sample code or working tutorial will be helpful.
Thanks in advance!!
But issue I am facing is that MasterDetailsPage is coming with the Blue Color Actionbar and menu icon to open/close navigation drawer.
You do not need to do customer render to change the ActionBar color
try to use
Detail = new NavigationPage((Page)Activator.CreateInstance(typeof(MainPage))) { BarBackgroundColor = Color.Red };
there is whitespace appearing
I did not reproduce your issue, my master detail page works fine without write line. You can refer to my project.
by checking the answer of the link you provide. I have created a customer render of MarstDetialPage at android project:
[assembly: ExportRenderer(typeof(MasterDetailPage), typeof(CustomMasterDetailRenderer))]
namespace MasterDetialPage_MyTest.Droid
{
public class CustomMasterDetailRenderer : MasterDetailPageRenderer
{
public override void AddView(Android.Views.View child)
{
child.GetType().GetRuntimeProperty("TopPadding").SetValue(child, 0);
var padding = child.GetType().GetRuntimeProperty("TopPadding").GetValue(child);
base.AddView(child);
}
}
}
It will get screen without notification bar.
Note: I have only test it on the android platform
I am creating an app that has a main BorderPane with a menubar in the TOP. I want to change the CENTER content when a specific menu option is selected. However, when I do this, the AnchorPane that I load into the CENTER pane is not resizing to fill the CENTER pane. It keeps it's preferred size. I have tried setting it to USE_COMPUTED_SIZE, but that does not resize it to fill the CENTER pane. I also tried to add an HBOX as a wrapper around the AnchorPane (I am fairly new to JavaFX UI design) which also did not work.
<BorderPane id="BorderPane" prefHeight="650.0" prefWidth="980.0"
xmlns="http://javafx.com/javafx/8.0.60"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="fileinventory.ApplicationFrameController">
<top><MenuBar BorderPane.alignment="CENTER">...</MenuBar></top>
<center><AnchorPane BorderPane.alignment="CENTER" /></center>
</BorderPane>
I load the pane to set in the CENTER using the following call from the main class:
public void viewClients() {
ViewClientsController dlg =
new ViewClientsController(this.bundle, this.rootLayout);
}
And the actual controller for the AnchorPane being loaded to the CENTER pane.
public class ViewClientsController {
public ViewClientsController(ResourceBundle bundle, BorderPane layout) {
FXMLLoader fxmlLoader =
new FXMLLoader(getClass().getResource("ViewClients.fxml"));
fxmlLoader.setController(this);
fxmlLoader.setResources(bundle);
try {
layout.setCenter(new AnchorPane((Parent) fxmlLoader.load()));
} catch (Exception ignore) {}
I do not know a lot about JavaFX layouts. I am more of a backend guy, so I am at a bit of a loss here.
I have three layers
Root layout, home, content (rootLayout.fxml, home.fxml and content.fxml)
FXMLLoader loader = new FXMLLoader();
loader.setLocation(GenerateReport.class
.getResource("/skin/rootLayout.fxml"));
rootLayout = (AnchorPane) loader.load();
Scene scene = new Scene(rootLayout);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(GenerateReport.class
.getResource("/skin/home.fxml"));
AnchorPane homeLayout = (AnchorPane) loader.load();
rootLayout.getChildren().addAll(homeLayout);
.
.
.
rootLayout.getChildren().addAll(contentLayout);
like this I am adding content layout. In rootLayout.fxml i have a home button. My requiredment is if a user clicks home button
then i want content layout to be removed and home layout to be visible.
content.fxml
<AnchorPane id="myContent" ... fx:controller="com.ReportController">
rootLayout.fxml
<AnchorPane id="AnchorPane" .. fx:controller="com.ReportController">
<children>
<Button fx:id="home" onAction="#homeBtn" .../>
</children>
</AnchorPane>
In my Controller (In all the fxml file i am pointing to the same controller) class i created
#FXML
private Button home;
#FXML
private AnchorPane myContent;
#FXML
protected void homeBtn(ActionEvent event) throws Exception {
System.out.println("click! homeBtn");
myContent.getChildren().clear();
}
The problem i am facing is i am getting NullPointerException. i.e. myContent.getChildren() is returning null. Could anyone help me in resolving this issue.
You're getting a Null Pointer Exception because Javafx doesn't associate your myContent with the AnchorPane stored in the fxml, and does not attach a reference to that object.
Nodes in fxml files are given their name identifiers by using fx:id. Note, for example, that your #FXML private Button home is marked in the fxml as <Button fx:id="home"...>.
In this case, your #FXML AnchorPane myContent is marked in fxml as <AnchorPane id="myContent"...>, not <AnchorPane fx:id="myContent"...>.
id="" is used only in CSS.
I'm quite new to java and javafx and have a problem which i could not solve.
I need to dynamically add new custom controlls to a javafx scene. Further i need interaction between the main control and the added controls.
I found already some useful information in the web but could not put it together.
So i build a little example for explanation:
main class:
public class Test_TwoController extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Fxml1.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The main fxml:
<AnchorPane id="fxml1_anchorpane_id" fx:id="fxml1_anchorpane" prefHeight="206.0" prefWidth="406.0" xmlns:fx="http://javafx.com/fxml" fx:controller="test_twocontroller.Fxml1Controller">
<children>
<HBox id="fxml1_hbox_id" fx:id="fxml1_hbox" prefHeight="200.0" prefWidth="400.0">
<children>
<Button id="fxml1_button_id" fx:id="fxml1_button" mnemonicParsing="false" onAction="#button_action" prefHeight="200.0" prefWidth="200.0" text="Button" />
</children>
</HBox>
</children>
</AnchorPane>
and its controller:
public class Fxml1Controller implements Initializable {
#FXML HBox hbox;
#FXML Button button;
#Override
public void initialize(URL url, ResourceBundle rb) { }
public void button_action(ActionEvent event) throws IOException {
// 1. add an instance of Fxml2 to hbox
// 2. change to tab2 in new Fxml2
// or
// notify Fxml2Controller to change to tab2 in Fxml2
}
}
And now the control to dynamically add:
Its fxml:
<AnchorPane id="fxml2_anchorpane_id" fx:id="fxml2_anchorpane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="200.0" xmlns:fx="http://javafx.com/fxml" fx:controller="test_twocontroller.Fxml2Controller">
<children>
<TabPane id="fxml2_tabpane_id" fx:id="fxml2_tabpane" prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab id="fxml2_tab1_id" fx:id="fxml2_tab1" text="tab1">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab id="fxml2_tab2_id" fx:id="fxml2_tab2" onSelectionChanged="#onSelectionChanged" text="tab2">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>
and the controler:
public class Fxml2Controller {
#FXML TabPane tabpane;
#FXML Tab tab1;
#FXML Tab tab2;
public Fxml2Controller() throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("Fxml2.fxml"));
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.setScene(scene);
}
public void onSelectionChanged(Event e) throws IOException {
FXMLLoader loader = new FXMLLoader();
// how can i get the current Fxml1 anchorpane instance?
AnchorPane root = (AnchorPane) loader.load(getClass().getResource("Fxml1.fxml").openStream());
Button b = (Button)root.lookup("#fxml1_button_id");
b.setText("New Button Text"); // dont change the buttons text!!!
}
}
The usage is: A fxml2 should be added to the hbox of fxml1. Then after a button click in fxml1 the tabs of fxml2 should change.
You may have a look at that image http://s13.postimage.org/uyrmgylo7/two_controlls.png
So my questions are:
how can i add one or more of the fxml2 controller into the hbox of fxml1?
how can i access one control from another or communicate between controlls? See onSelectionChanged() method in Fxml2Controller for detail.
Thank you in advance,
solarisx
You seem to have mixed quite a few concepts together which are distinct. First of all, a Stage can be understood as a window on the screen. It has a Scene object which holds the actual SceneGraph. In your example, you are creating a new Stage and a new Scene that get filled which the content of your second fxml-file. This means that, if working, a second window will pop up containing your stuff. I don't think that this is what you want to achieve.
Moreover, when the FXMLLoader reads a file, it looks for the class that is specified as its controller and constructs an instance of it via reflection. This means that when you call the load method in the constructor of the controller of the fxml-file you are loading with it, you are causing an infinite loop.
The last thing to understand is that the object that load() returns is an arbitrary node which can be put into the SceneGraph of your application just like any other node.
So to make your concept work, you should make the following:
Move the loading-code which is currently in the constructor of your second controller to the button_Action method of your first controller.
Throw away the new-stage-new-scene code in the button_action and take the Node returned by the FXMLLoader and add it to the children of the HBox.
For your second question, you can get the controller instance if you actually create an instance of an FXMLLoader instead of calling the static method, and use the load() method in it. After calling load() you can retrieve the controller and root object of the fxml-file via getController() and getRoot(). You can then use them just like any arbitrary object in your logic.
In JavaFX 1.x, where I've used the FX-Script to setup the Scene, I had the bind keyword:
Dynamic/instant resize in JavaFX
How can I have the same behavior in 2.0?
If you want automatic resize, you should do something like this
private BorderPane root;
#Override
public void start(Stage stage) throws Exception
{
root = new BorderPane();
//ROOT SHOULD BE ONE OF THE LAYOUTS : BorderPane, HBox, VBox, StackPane,
//GridPane, FlowPane
scene = new Scene(root, 500, 500);
stage.setScene(scene);
stage.show();
root.setCenter(new Label("sample label"));
}
I have tried only with BorderPane and it works. Also if you want to create custom
component, your class should extend one of layouts. Automatic resize won't work if your component extends Pane or Group
I think this will help to you.
Best regards
Sandro
I've just found the answer on another plattform:
It is as easy as
FlowPane layout=new FlowPane();
layout.prefWidthProperty().bind(stage.widthProperty());
layout.prefHeightProperty().bind(stage.heightProperty());
If your flow pane has margins, you need perhaps something like this:
innerHorizontalFlowPane.prefWidthProperty().bind(
Bindings.add(-50, stage.widthProperty()))