Codename one - Navigate from Form A to Form B with action events and new GUI builder - and navigate back from B to A - forms

What is the best practice with the new GUI Builder, to simply navigate from "form A" to another "form B" by clicking a button in "form A", with use of the action events?
If I create Form B inside Form A like this
public void oncreateAccountActionEvent(com.codename1.ui.events.ActionEvent ev) {
new FormB().show();
}
Then I am obviously not able to modify Form B from inside the main class (start, stop, destroy methods) before I do new FormB().show(). In this case new FormA().show(); is located in the start-method of the main class.
I want to be able to specfiy e.g. a back-button to Form B to navigate back to Form A, but I want to add this inside the start-method of the Main class.
Thanks!
Edit:
I have the Main-class (with start(), stop(), destroy()-methods), in this class I do new FormA().show().
But inside the class of FormA I have the oncreateAccountActionEvent-method (and button) which shows FormB by new FormB().show().
However I want to be able to specify formB.setBackCommand() (into the toolbar of FormB inside the main-class.
So to say I want to specify both forms in the main class with new FormA/B() - then modify the forms like adding buttons to the toolbar - and then tell FormA that FormB should be used inside the action event method.

Use showBack() method to go back to FormA from FormB as shown in the code below. You can just keep a reference to the previous/next form instances.
FormA formA = new FormA();
FormB formB = new FormB();
public void oncreateAccountActionEvent(com.codename1.ui.events.ActionEvent ev) {
formB.show();
}
public void showFormA(){
formA.showBack();
}

I came to an obvious solution to my problem by simply overriding the oncreateAccountActionEvent-method in the Main-class and still being able to create and modify formB before:
Form formB= new FormB();
// Modifying formB
formB.setBackCommand(backCommand);
...
//Create formA and show the modified formB on button click
FormA formA= new FormA() {
#Override
public void oncreateAccountActionEvent(ActionEvent ev) {
//Navigate to FormB
formB.show();
};
};
And for navigating back from formB to formA I found this solution, to keep a reference of the previous form by implementing the show()-method of the class of formB:
private Form previous;
...
public void show() {
previous = Display.getInstance().getCurrent();
super.show();
}
...
//go to the form before
public void goBack(){
previous.showBack();
}
Maybe this helps someone else, too.

Related

How to lock Form during lunch a class?

I have a simple Form MyCustomForm, in a Form's Button in Clicked method I call a Class (method run), so I want to lock (or block) this form during run execution.
My code is look like this :
void clicked()
{// in Button clicked in **MyCustomForm**
MyClass myClass;
super();
myClass = new MyClass();
// here I want to freeze my FORM
myClass.run();
// here I want to unlock my Form
}
I need this because when class (MyClass) is running can display Dialog etc, but I don't want to touc/click and other on MyCustomForm
If I use :
element.wait(); // not work well - block all
myClass.run();
Thanks,
enjoy.
If your class displays dialog you can make this dialog modal using the following line of code dialog.parmIsModal(true).
Or formRun.wait(true) for forms.

Custom Perspective Switcher Toolbar: How can I dynamically update it?

I'm trying to implement a custom perspective switcher toolbar to replace eclipse's built-in one. I couldn't get the toolbar to display, and it was shown to me that due to a bug with the dynamic element in a menu contribution, I have to use a control element instead, as described in the workaround to the dynamic bug.
I have a toolbar displaying following that approach, but I cannot figure out how to update it dynamically. The workaround instruction is to call ContributionItem#fill(CoolBar, int) from my WorkbenchControlContributionItem's update method instead of doing the fill in the createControl method.
I don't know who is supposed to call update, but it never gets invoked no matter what I do. I have a perspective listener which knows when to update the toolbar, so from that listener's callback I call fill(CoolBar, int). But I wasn't sure how to get the CoolBar to pass to that method, so I created one on the current shell.
The end result of all this is that the toolbar displays the correct number of items initially, but when I need to add an item, it has no effect. I call fill(CoolBar, int) and it adds the new item to the toolbar, but everything I've tried to make the CoolBar and ToolBarupdate does not work. When I re-launch the app, the toolbar has the added item.
I'm sure I'm doing this wrong, but I can't figure out the right way. Here's an elided representation of my code (omitting methods, layout code, etc not related to the update problem).
public class PerspectiveSwitcherToolbar extends WorkbenchWindowControlContribution implements IPerspectiveListener {
...
#Override
protected Control createControl(Composite parent) {
this.parent = parent;
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
page.getWorkbenchWindow().addPerspectiveListener(this);
toolBarManager = (ToolBarManager)parent.getParent().getData();
fTopControl = new Composite(parent, SWT.BORDER);
fill(new CoolBar(page.getWorkbenchWindow().getShell(), SWT.HORIZONTAL), -1);
return fTopControl;
}
#Override
public void fill(CoolBar coolbar, int index) {
IPerspectiveDescriptor[] openPerspectives = page.getOpenPerspectives();
String activePerspective = getPerspectiveId();
ToolBar toolbar = new ToolBar(fTopControl, SWT.NONE);
for(IPerspectiveDescriptor descriptor : openPerspectives) {
ToolItem item = new ToolItem(toolbar, SWT.RADIO);
//overkill here, trying to find some way to upate the toolbar
toolbar.update();
parent.update();
parent.layout(true);
parent.getParent().update();
parent.getParent().layout(true);
coolbar.layout(true);
}
//PerspectiveListener callback
#Override
public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
fill(new CoolBar(page.getWorkbenchWindow().getShell(), SWT.HORIZONTAL), -1);
if (page.getWorkbenchWindow() instanceof WorkbenchWindow){
//this non-API call doesn't help either
((WorkbenchWindow) page.getWorkbenchWindow()).updateActionBars();
}
}
...
}

Enable/disable an ordinary button on Form2 from Form1

I need some help. I've been reading this site for days, and have read a lot of tips about controlling for example a button's property from another form. There's even a video on Youtube, which works to me as stand alone, but when I implenet it in my application it throws a NullReferenceException.
Let's say that I have a toolstrip menu on Form1. A click on the Kalibracio option opens the second form (also called Kalibracio - not Form2). Then, click on Proba in the menu should disable an ordinary button on the Kalibracio form which propery is set to public. The code on Form1 is as follows:
private void kalibracioToolStripMenuItem_Click(object sender, EventArgs e)
{
Kalibracio Kalibr = new Kalibracio(this);
Kalibr.Owner = this;
Kalibr.Show();
}
private void probaToolStripMenuItem_Click(object sender, EventArgs e)
{
if (Application.OpenForms.OfType<Kalibracio>().Any())
(this.Owner as Kalibracio).button1.Enabled = false;
// the above line throws a NullReferenceExcteption if Kalibracio form is open (Kalibracio is null)
}
What am I missing?
LoL just had to declare globaly an instance of Kalibracio, open it and then access it's properties from all other methods.
I tried this approach at first, but my problem was that I was creating and instance locally, then I had to create another one in some other method because I couldn't address the former one created locally, and ofc it didn't work...

DevExpress RibbonPage added programatically does not show

I've a RibbonControl in a mdiform and another RibbonControl added at design time in a MDIChildForm. Then in runtime, I add a RibbonPage, with a RibbonGroup and a BarButtonItem. Like this:
private void MDIChildForm_Load(object sender, EventArgs e) {
BarButtonItem btn = ribbonControl1.Items.CreateButton("Test Button");
RibbonPageGroup group1 = new RibbonPageGroup("Test Group");
group1.ItemLinks.Add(btn);
RibbonPage page1 = new RibbonPage("Test Page");
page1.Groups.Add(group1);
ribbonControl1.Pages.Add(page1);
}
The "Test Page" isn't visible in the MdiParent. But, when I change the active mdi child form, and the ribbon do the merge, the page appears!
It looks like the page isn't merged until I change the active mdi child form.
Am I missing something?
I've found a solution, but I think is not the most elegant way to solve it:
mainRibbon.UnMergeRibbon();
mainRibbon.MergeRibbon(mdiChildForm.ChildRibbon);
A public property to access the child Ribbon was needed.

How do you rebuild the GWT History stack?

I have a larger application that I'm working with but the GWT History documentation has a simple example that demonstrates the problem. The example is copied for convenience:
public class HistoryTest implements EntryPoint, ValueChangeHandler
{
private Label lbl = new Label();
public void onModuleLoad()
{
Hyperlink link0 = new Hyperlink("link to foo", "foo");
Hyperlink link1 = new Hyperlink("link to bar", "bar");
Hyperlink link2 = new Hyperlink("link to baz", "baz");
String initToken = History.getToken();
if (initToken.length() == 0)
{
History.newItem("baz");
}
// Add widgets to the root panel.
VerticalPanel panel = new VerticalPanel();
panel.add(lbl);
panel.add(link0);
panel.add(link1);
panel.add(link2);
RootPanel.get().add(panel);
History.addValueChangeHandler(this); // Add history listener
History.fireCurrentHistoryState();
}
#Override
public void onValueChange(ValueChangeEvent event)
{
lbl.setText("The current history token is: " + event.getValue());
}
}
The problem is that if you refresh the application, the history stack gets blown away. How do you preserve the history so that if the user refreshes the page, the back button is still useful?
I have just tested it with Firefox and Chrome for my application and page refresh does not clear the history. Which browser do you use? Do you have the
<iframe src="javascript:''" id='__gwt_historyFrame' style='position:absolute;width:0;height:0;border:0'></iframe>
in your HTML?
GWT has catered for this problem by providing the History object. By making a call to it's static method History.newItem("your token"), you will be able to pass a token into your query string.
However you need to be aware that any time there is a history change in a gwt application, the onValueChange(ValueChangeEvent event){} event is fired, and in the method you can call the appropriate pages. Below is a list of steps which i use to solve this problem.
Add a click listener to the object that needs too call a new page. In handling the event add a token to the history.(History.newItem("new_token").
Implement the ValueChangeHandler in the class that implements your EntryPoint.
Add onValueChangeHandler(this) listener to the class that implements the EntryPoint. Ensure that the line is add in the onModuleLoad() method (it is important it is added in this method) of the class that implements the EntryPoint(pretty obvious ha!)
Finally implement onValueChange(ValueChangeEvent event){ //call a new page } method.
That's it