javafx how to reuse custom component in different FXML - javafx-8

After several searching i could find any solution for this and would like to ask for help. Thanks in advance.
I have a FXML with HBox with several buttons (new, show, edit). Each button has onAction method. It is used in other 2 FXML (A & B) and I would like to reuse such HBox.
Other 2 FXML (A, B) have some controls (tableview, ...)
This is what i tried:
1) import HBox FXML is not an option as changes must be performed in all FXML (a & b).
2) include using fx:id: I will have a dedicated controller for HBox and I would like to have controls and methods on A, B controllers.
3) include using fx:root: I think this is the way to achieve this but i have errors.
Navigation.fxml file:
<fx:root spacing="5.0" type="HBox" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button fx:id="btnOpen" mnemonicParsing="false" onAction="#onActionOpen" text="Open" />
<Button fx:id="btnSave" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#onActionSave" text="Save" />
<Separator visible="false" HBox.hgrow="ALWAYS" />
<Button fx:id="btnClose" layoutX="62.0" layoutY="10.0" mnemonicParsing="false" onAction="#onActionClose" text="Close" />
</children>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</fx:root>
Pane1controller.java:
public Pane1Controller() {
System.out.println("Pane1_Controller");
NavigationController nav = new NavigationController();
System.out.println("NavigationController ... done");
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("pane1.fxml"));
System.out.println("setting root");
fxmlLoader.setRoot(this);
System.out.println("setting controller");
fxmlLoader.setController(this);
try {
System.out.println("loading fxml");
pnlMain = fxmlLoader.load();
System.out.println("done");
} catch (IOException exception) {
System.out.println("exception");
pnlMain = null;
throw new RuntimeException(exception);
}
System.out.println("done");
} ...
}
using setRoot ....
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: Root
value already specified.
file:/C:/Users/ecejdap/data/DEV/dev.java.nb/Testfx_fxroot/dist/run573616745/Testfx_fxroot.jar!/testfx_fxroot/pane1.fxml
removing setroot
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: Root value already specified.
file:/C:/Users/ecejdap/data/DEV/dev.java.nb/Testfx_fxroot/dist/run2127482879/Testfx_fxroot.jar!/testfx_fxroot/Navigation.fxml
Which is the correct way to achieve this?
Thanks for your support.
BR

This must be caused due to the <fx:root> tag
I've created a sample project for the above task. Visit GitHub for the project. Clone it and refer. I think you can understand it. Link

Related

How to make a multi-steps registration page with multi ContentView?

In the app I'm working on, there's a multi-steps registration, 4 steps:
to accomplish it, I'm thinking to have a single page to host a content view of the registration step, when it passes the validation requirements I remove it and inject the next content view.
This is an example to simplify my need:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamApp"
x:Class="XamApp.MainPage">
<local:Register1/>
</ContentPage>
and the Register1 looks like this:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamApp"
x:Class="XamApp.Register1">
<ContentView.Resources>
<ResourceDictionary>
<local:IntToBoolConverter x:Key="intToBool"/>
</ResourceDictionary>
</ContentView.Resources>
<ContentView.Content>
<StackLayout>
<Label Text="Page 1" FontSize="Large"/>
<Entry x:Name="txtName" Placeholder="Name"/>
<Button Text="Next" IsEnabled="{Binding Source={x:Reference txtName},
Path=Text.Length,
Converter={StaticResource intToBool}}"
Clicked="Button_Clicked"/>
</StackLayout>
</ContentView.Content>
</ContentView>
There are two problems:
1- I don't know how to handle the data (view model) between steps, to have only one object through all steps (Shall I use DI? if yes , then how in MVVMLight?)
2- How to to inject the content view into the main registration page dynamically in an MVVM fashion?
The solution I came up with, is creating an interface:
public interface INavigate
{
INavigate Next();
INavigate Previous();
}
all the ContentViews inherit from, for example the second ContentView implementation:
public INavigate Next()
=> new View3();
public INavigate Previous()
=> new View1();
the container page's Content property is bound to the view model's property CurrentView of type INavigate,
the command of the next button execute this:
CurrentView = CurrentView.Next();
and this is for the previous button:
CurrentView = CurrentView.Previous();

One WPF Window that displays different DataGrid's based on Menu selection?

I want to display different DataSource (SQL) queries in one 'DataGrid' based on Menu selections. Am I barking up the wrong tree by looking at UserControl's? How would this be implemented?
Edit:
I've finally found Changing user control on list selection which seems to answer my question pretty well, or at least modifies my question a little. So one Menu is to list all "Parts" available. The other Menu has MenuItems that correspond to locations and ultimately the inventory of said Parts at each location. Currently I am using a Click handler for each MenuItem and create a new instance of a specific UserControl for Parts and each location.
private void menuParts_Click(object sender, RoutedEventArgs e)
{
dgRoot.Children.Clear();
UserControl control = new ucParts();
this.dgRoot.Children.Add(control);
this.Title = "Inventory Manager - Parts";
}
and
private void menuSG1_Click(object sender, RoutedEventArgs e)
{
dgRoot.Children.Clear();
UserControl control = new ucSG1();
this.dgRoot.Children.Add(control);
this.Title = "Inventory Manager - SG1";
}
My question now is, can I create a reusable UserControl template that the Click handler can feed the location name to? The data is displayed, formatted, used, etc the same way, it's ultimately just the underlying DataSource query that is different.
You seemingly CAN do this. Just create the generic usercontrol Grid in my case.
MainWindow.xaml
<DockPanel>
<Menu DockPanel.Dock="Top" Name="menuMain" Height="27" HorizontalAlignment="Stretch" VerticalAlignment="Top" ScrollViewer.VerticalScrollBarVisibility="Disabled" >
<MenuItem Header="Parts">
<MenuItem Name="menuParts" Header="Parts" Click="menuParts_Click"/>
<Separator />
<MenuItem Name="addPart" Header="Add Part" Click="addPart_Click" />
</MenuItem>
<MenuItem Header="Inventory">
<MenuItem Name="menuBrady" Header="Brady" Click="menuBrady_Click"/>
<MenuItem Name="menuCO" Header="Community" Click="menuCO_Click"/>
<MenuItem Name="menuPoly" Header="Poly" Click="menuPoly_Click"/>
<MenuItem Name="menuSG1" Header="SG1" Click="menuSG1_Click"/>
<MenuItem Name="menuWS" Header="West Shore" Click="menuWS_Click"/>
</MenuItem>
</Menu>
<Grid Name="dgRoot" />
</DockPanel>
Then as shown in my Click handlers above, use them!

Events selection is considered as event moving

I'm using a daypilot scheduler for a booking hotel's rooms.
I want to use events multiselection but when I enable this feature the scheduler is considering it as an event moving and not a selection
I did as following
AllowMultiSelect="true"
OnEventSelect="MonthScheduler_EventSelect"
EDIT:
<div id="colright" style="margin-left:20px;">
<div class="row">
<DayPilot:DayPilotScheduler ID="MonthScheduler"
OnEventMenuClick="Scheduler_EventMenuClick"
runat="server"
RowHeaderWidthAutoFit="true"
DataStartField="Start"
DataEndField="End"
DataTextField="Name"
DataValueField="Id"
DataResourceField="ressource"
HeaderFontSize="9pt"
EventHeight="25"
EventFontSize="11px"
RowHeaderWidth="200"
Width="1050"
Height="500"
HeightSpec="Fixed"
ShowToolTip="false"
CellDuration="1440"
CellGroupBy="Week"
TreeEnabled="true"
TreeIndent="15"
ClientObjectName="dps1"
UseEventBoxes="Always"
EnableViewState="true"
ScrollLabelsVisible="false"
BubbleID="DayPilotBubble1"
ResourceBubbleID="DayPilotBubble1"
DataTagFields="Description"
TimeRangeSelectedHandling="PostBack"
OnTimeRangeMenuClick="DayPilotScheduler1_TimeRangeMenuClick"
OnEventResize="MonthScheduler_EventResize"
OnTimeRangeDoubleClick="MonthScheduler_TimeRangeDoubleClick"
OnTimeRangeSelected="MonthScheduler_TimeRangeSelected"
DragOutAllowed="false"
EventResizeHandling="PostBack"
EventMoveHandling="PostBack"
OnEventMove="MonthScheduler_EventMove"
xCellBubbleID="DayPilotBubble1"
OnBeforeEventRender="MonthScheduler_BeforeEventRender"
OnBeforeResHeaderRender="MonthScheduler_BeforeResHeaderRender"
OnBeforeTimeHeaderRender="MonthScheduler_EventMove_BeforeTimeHeaderRender"
EventMovingStartEndEnabled="true"
EventResizingStartEndEnabled="true"
OnScroll="MonthScheduler_Scroll"
Theme="scheduler_traditional"
BorderColor="#666666"
OnResourceCollapse="MonthScheduler_ResourceCollapse"
TimeRangeSelectingStartEndFormat=""
AllowMultiSelect="true"
OnEventSelect="MonthScheduler_EventSelect"
EventClickHandling="Select"
ContextMenuSelectionID="DayPilotMenuSelection"
TreePreventParentUsage="true"
HourNameBackColor="#F0F0F0">
</DayPilot:DayPilotScheduler>
</div>
<DayPilot:DayPilotBubble ID="DayPilotBubble1" runat="server" ClientObjectName="bubble"
Width="0" OnRenderEventBubble="MonthScheduler_RenderEventBubble" OnRenderContent="MonthScheduler_RenderContent"
Corners="Rounded" Position="Mouse" Animated="false" >
</DayPilot:DayPilotBubble>
<DayPilot:DayPilotMenu ID="DayPilotMenu1" CssClassPrefix="menu_default"
runat="server" ClientObjectName="DayPilotMenu1" MenuTitle="Action" ShowMenuTitle="true">
<DayPilot:MenuItem Action="PostBack" Command="Modifier" Text="Edit" />
<DayPilot:MenuItem Action="PostBack" Command="Delete" Text="Delete" />
</DayPilot:DayPilotMenu>
<DayPilot:DayPilotMenu ID="DayPilotMenuSelection" runat="server" ZIndex="10003" MenuTitle="Action" CssClassPrefix="menu_default" >
<DayPilot:MenuItem Action="PostBack" Command="New" Text="Add new" />
<DayPilot:MenuItem Action="PostBack" Command="Old" Text="Add old" />
</DayPilot:DayPilotMenu>
</div>
and this my event select (which is not fired on selection)
protected void MonthScheduler_EventSelect(object sender, DayPilotEventArgs e)
{
//do }
You need to map one of the user actions to the "Select" behavior.
There are two basic options:
Click
EventClickHandling="Select"
Double click
EventDoubleClickHandling="Select"
See also event selecting topic in the docs. This will of course prevent you from using this action for another behavior (like opening the edit dialog). If you want to open the edit dialog you can also add a special "edit" icon (using active areas).
The upcoming version (8.0) will also support "rectangle event selecting" that will let you select multiple events using Shift + drag, just like in desktop file manager applications. See a preview here:
http://javascript.daypilot.org/sandbox/scheduler/eventmultiselecting.html

Titanium Alloy ListView XML Uncaught TypeError: Object #<UI> has no method 'createTemplates'

I am new to Titanium, so excuse my lack of understanding.
Even though I am using sdk version 3.2 (have sdk-version: 3.2.0.v20130801162445 in my tiapp.xml) when I try and have a view that uses the xml above I get this error:
[ERROR][V8Exception( 615)] Exception occurred at alloy/controllers/feed.js:22: Uncaught TypeError: Object # has no method 'createTemplates'
I cut down all my code so that the feed.js file is just:
function loadMoreBtnClicked(_event) {
alert('not implemented yet');
}
function createListView(_data) {
// this is pretty straight forward, assigning the values to the specific
// properties in the template we defined above
var items = [];
for (var i in _data) {
// add items to an array
items.push({
template : "template1", // set the template
textLabel : {
text : _data[i].name // assign the values from the data
},
pic : {
image : _data[i].pic_square // assign the values from the data
}
});
}
// add the array, items, to the section defined in the feed.xml file
$.section.setItems(items);
}
alert('feed loaded');
The XML is in feed.xml and looks like this:
<Alloy>
<Window class="container" formFactor="handheld">
<ListView id="list" defaultItemTemplate="template1">
<Templates>
<ItemTemplate name="buttonItem" height="Ti.UI.SIZE">
<!-- will use this in the next blog post -->
<Button id="loadMoreBtn" onClick="loadMoreBtnClicked">Load More</Button>
</ItemTemplate>
<!-- main template for displaying the list items -->
<ItemTemplate id="template1" name="template1" class="template1">
<ImageView id="pic" bindId="pic" class="imageThumb"/>
<View id="textContainer">
<Label id="textLabel" bindId="textLabel" class="title"/>
</View>
</ItemTemplate>
</Templates>
<!-- we only have one section and the items are contstucted using template1 -->
<ListSection id="section" >
<ListItem template="template1" />
</ListSection>
</ListView>
</Window>
</Alloy>
I still get the error (just using the XML with no actual controller code other than the alert running). If I pull the ListView XML out of the feed.xml file the alert fires, when I put the ListView XML back in I get the Error above.
I am trying to use code from this example:
https://gist.github.com/aaronksaunders/5896390
but cant really tell what I am missing?
Thanks!
-James
found out what the issue was, my problem had to do with not having the updated version of alloy that is needed to support the ListView Templates in XML. I needed to run this at the command line in Windows: "npm install -g alloy#1.2.0-alpha" (without quotes). After that I was able to use ListView templates in XML as shown above.

jsf - commandLink doesn't call bean method

My h:commandLink doesn't work. I've got a navigation rule in the faces-config.xml and a String method doSave() in my bean. I don't know why It only reloads the page without jumping into the doSave() method.
jsf-page
<h:form id="surveyForm">
<div class="srvButton">
<h:commandLink action="#{surveyBean.doSave}" value="#{msg.srvButton}" />
</div>
</h:form>
faces-config
<navigation-rule>
<from-view-id>/pages/survey.xhtml</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/pages/surveyFinish.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
bean
public String doSave() {
// Kundendaten speichern
saveCustomer();
return "success";
}
I cleaned the content in the jsf-page for a better view, but all you need to know is the form and button I think.
I just solved my problem. I replaced all my c:if tags with ui:fragment tags and it worked! Maybe, this could interest you c:foreach vs ui:repeat
Thanks #matthandy for his effort..