Declare 2 standalone components in one UiBinder file? - java

I have a dialog which fires ValidEvent (GXT custom event) :
public class MyDialog extends Dialog implements HasValidHandlers {
...
}
So if I include it in a UiBinder file, I should be able to do something like (see #UiHandler) :
#UiField
MyDialog myDialog;
#UiHandler("myDialog")
void onValid(ValidEvent event) {
..
}
And I want to include the MyDialog in a widget also defined with UiBinder :
public class MyWidget extends Composite {
#UiField
MyDialog myDialog;
public MyWidget(Binder binder) {
initWidget(binder.createAndBindUi(this));
}
#UiHandler("myDialog")
void onValid(ValidEvent event) {
..
}
interface Binder extends UiBinder<Widget, MyWidget> {}
}
Problem : Where to place the component in the ui.xml file?
Including the dialog in the component will causes graphical problem as UiBinder will try to add the Dialog IN the widget :
<g:HTMLPanel>
<MyDialog ui:field="myDialog"/>
</g:HTMLPanel>
But : In uIBinder, I can have only one root component.
Question : How can I declare 2 different components in a single UiBinder file? I would like to avoid making a ui.xml just to declare the Dialog and if I instantiate it via new the #UiHandler will not work.

You partly have answered your own question.
Including the dialog in the component will causes graphical problem as UiBinder will try to add the Dialog IN the widget :
Hence you will need to create a ui-binder separately for the component, as you also intend to use it as a uiField etc too!
According to my guess (based on my knowledge) each ui-binder creates a single widget and it can be referenced in another ui-binder or file as required.

You can have two UiBinder in the same widget :
public class MyWidget extends Composite {
MyDialog myDialog;
public MyWidget(Binder binder) {
initWidget(binder.createAndBindUi(this));
DialogBinder dialogBinder = GWT.create(DialogBinder.class);
myDialog = dialogBinder.createAndBindUi(this);
}
#UiHandler("myDialog")
void onValid(ValidEvent event) {
..
}
interface Binder extends UiBinder<Widget, MyWidget> {}
#UiTemplate("DialogBinder.ui.xml")
interface DialogBinder extends UiBinder<MyDialog, MyWidget> {}
}
And your DialogBinder.ui.xml looks like :
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder">
<MyDialog ui:field="myDialog"/>
</ui:UiBinder>
I don't test it, but there can be a problem with different #UiField.
You can doo this this an Inner Class who own all Dialog #UiField and #UiHander.

Related

How to add footer and header to other views using routerLayout in java using vaadin

I created a class named "Footer" having just a Label. I also have a few views like loginview, orderview). And I would like to add that footer to every view. This is my code until now.
#ParentLayout(OrderView.class)
public class footer extends VerticalLayout implements RouterLayout {
public footer() {
add(new Span("This text should be underneath the page in the views"));
}
}
Underneath you have my orederview where I want to see that text from the footerclass.
#Route("order")
public class OrderView extends VerticalLayout implements RouterLayout {
public OrderView (){
// What am I supposed to code here to get that text from Footerclass.
}
}
I would like to know what I am missing.
Thanks for the help.
Your usage of the annotations is wrong. Here is super simplified outline how you should create MainLayout and route that defines a component that is shown in the mainlayout when navigated to that route.
public class MainLayout extends VerticalLayout implements RouterLayout {
private Div childWrapper = new Div();
public void MainLayout() {
setSizeFull();
Span header = new Span("This text should be above the page in the views");
Span footer = new Span("This text should be underneath the page in the views");
add(header);
addAndExpand(childWrapper)
add(footer);
}
#Override
public void showRouterLayoutContent(HasElement content) {
childWrapper.getElement().appendChild(content.getElement());
}
}
#Route(value = "order", layout = MainLayout.class)
public class OrderView extends VerticalLayout {
public OrderView (){
}
}
There is video tutorial about Router concept on vaadin.com page that explains this in detail.
Instead of
new Label("This text should be underneath the page in the views");
try
add(new Span("This text should be underneath the page in the views"));
In Vaadin Flow the Label component is meant to be used coupled with another component, not for adding stand-alone text like in Vaadin 8 and older. Also, every component needs to be added to the layout before they can become visible, just creating them isn't enough.
Unfortunately LoginOverlay doesn't have API for adding extra components within it, but there is an open ticket about the feature that you can add thumbs up on to add more weight to it, and there's also a workaround presented in the comments: https://github.com/vaadin/web-components/issues/626

How to refresh CDIView to reflect changes made in another CDIView?

I am using cdi-helpers addon and my UI extends ViewMenuUI. I have CDIViews like
OGSContractView
#UIScoped
#CDIView("Contract")
#ViewMenuItem(order = ViewMenuItem.DEFAULT, icon = FontAwesome.BANK)
public class OGSContractView extends CssLayout implements View{
// There's some UI Fields and some Functions to refresh the UI Fields
public void RefreshList(){...}
}
and
SchoolView
#UIScoped
#CDIView("School")
#ViewMenuItem(order = ViewMenuItem.DEFAULT, icon = FontAwesome.BANK)
public class SchoolView extends CssLayout implements View{
//Some UI and functions inside
//here, after some changes, I want to call a Refresh_Function
//from my OGSContractView class
someData.saveInDatabase();
ogsContractView.refreshList(); // here is my problem
}
In SchoolView, I am changing some data in the database and after that I want to call OGSContractView.refreshList() to update some ui fields there.
How can I do this?
For updated question. You do not need to call refresh() from the another view.
You can override method public void enter(ViewChangeEvent event) on OGSContractView, like
#Override
public void enter(ViewChangeEvent event) {
refresh():
}
Above method is called by internal navigator each time you enter to that view.

GWT AbsolutePanel not shown in browser

I create widget containing AbsolutePanel using GWT UiBinder like this:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<g:VerticalPanel>
<g:Label>Label1</g:Label>
<g:AbsolutePanel height="500" width="500">
<g:at left='10' top='60'>
<g:Label>Label2</g:Label>
</g:at>
<g:at left='10' top='100'>
<g:Label>Label3</g:Label>
</g:at>
</g:AbsolutePanel>
<g:Label>Label4</g:Label>
</g:VerticalPanel>
</ui:UiBinder>
Than create corresponding class :
public class TestAbsPanelWidget extends Composite {
#UiTemplate("TestAbsPanelWidget.ui.xml")
interface MyUiBinder extends UiBinder<Widget, TestAbsPanelWidget> {}
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
public TestAbsPanelWidget() {
initWidget(uiBinder.createAndBindUi(this));
}
}
Than use it my GWT entry point like this:
public class TestAbsPanel2 implements EntryPoint {
public void onModuleLoad() {
RootPanel.get("div_id").add(new TestAbsPanelWidget());
}
}
After that I see "Label1" and "Label4" on screen in browser, but no "Label2" and "Label3". It seems that AbsolutePanel not shown. What am I doing wrong help me please.
You try to set the panel's width and height with:
<g:AbsolutePanel height="500" width="500">
but you don't specify CSS units. Try:
<g:AbsolutePanel height="500px" width="500px">
and you will see Label2 and Label3.

Swing: How to close JDialog programmatically from a controller?

I've got a JDialog bound to my (separate) controller class via beans binding (Netbeans). My dialog has a "close" Button. The action property of this button is bound to an action in my controller.
Dialog:
public class AppVersionCheckDialog extends javax.swing.JDialog {
...
binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, controller, org.jdesktop.beansbinding.ELProperty.create("${closeButtonActionListener}"), btnOk, org.jdesktop.beansbinding.BeanProperty.create("action"));
bindingGroup.addBinding(binding);
...
}
So basically I got
public class AppVersionCheckDialogController extends AbstractController {
private final Action closeAction = new AbstractAction("Close") {
#Override
public void actionPerformed(ActionEvent e) {
// dialog.dispose() - no reference of dialog instance here
}
};
public Action getCloseButtonActionListener(){
return closeAction;
}
}
in my controller.
I do not have any reference to the dialog within the controller. And I don't want to introduce one, as it breaks the whole principle of binding things together.
So how to close the dialog? Is there a way to bind the dialog instance to a property of my controller? If so, how?
I don't have a compiler with me now, but if I understand correctly what you want is similar to this:
public void actionPerformed(ActionEvent e) {
Component component = (Component) e.getSource();
JDialog dialog = (JDialog) SwingUtilities.getRoot(component);
dialog.dispose();
}
I'll have a look when I have the chance to compile and if it has problems. I hope, it solves your problem.

Adding to GWT RootPanel or just setting the default view?

I have the following GWT classes:
public class MyDefaultView extends Composite {
// Uses UiBinder and just contains all the widgets for this view.
}
public class MyDefaultActivity extends AbstractActivity {
#Inject
private MyDefaultView myDefView;
#Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
panel.setWidget(myDefView);
}
}
public class MyActivityMapper implements ActivityMapper {
#Override
public Activity getActivity(Place place) {
if(place instanceof MyDefaultPlace)
return new MyDefaultActivity();
else
return null;
}
}
public class MyAppModule implements EntryPoint {
#Override
public void onModuleLoad() {
// Lots of initialization and wiring...
// Why do I need this?!?
MyDefaultView myDefaultView = GWT.create(MyDefaultView.class);
RootPanel.add(myDefaultView);
Place myDefaultPlace = GWT.create(MyDefaultPlace.class);
PlaceHistoryHandler historyHandler = getHistoryHandler();
historyHandler.register(myPlaceController, myEventBus, myDefaultPlace);
historyHandler.handleCurrentHistory();
}
}
Why do I need to add MyDefaultView to RootPanel, if I'm just going to call PlaceHistoryHandler#handleCurrentHistory() and display MyDefaultView when the module loads?
If I shouldn't be adding MyDefaultView directly to RootPanel, then what should I be adding?
Thanks in advance!
1) You don't need to add MyDefaultView, but you need to a panel that implements AcceptsOneWidget and set that panel on the activity manager. This will take care of having your views made visible.
2) In most applications you have a part of the application that is always visible. For example a bar at the top showing among other things the user name. This kind panel needs to be added to the root panel. In that panel on the position where your views should be visible a widget/panel that implements AcceptsOneWidget should be used. This widget should be set as display in your activityManager, via setDisplay. That widget will be passed to the start method in your activity. Here is how the code to use with the ActivityManager and RootPanel could look like:
final ActivityManager activityManager = new ActivityManager(myActivityMapper, eventBus);
activityManager.setDisplay(rootView.getViewPanel());
Rootpanel.add(rootView);

Categories