I am a total newbie with Codename One and have been studying up by watching the various tutorials etc. But there is a basic concept that I just can't seem to grasp.
When I design a form in the GUIBuilder, how do I reference the form from my code?
I.e. I designed my form in the UI Builder. Now in my main source code, I would like to add a toolbar to the form. Inside the GUIBuilder the form is called "Main", but statements such as Main.show(), Main.hide() etc do not work.
I managed to get the form "imported" for lack of a better word by using
private Form home;
...
...
home=Display.getInstance().getCurrent();
...
home.getToolbar().addCommandToOverflowMenu(edit);
Which works, but surely there must be a way of accessing the form directly without having to get the currently active instance? i.e. Something like
Main.getToolbar().addCommandToOverflowMenu(edit);
You can override the beforeShow() and postShow() of your form and just reference the parameter which represents the form.
To add commands, it's advisable that you do that in the beforeShow() method and long process like remote data fetching should be done in postShow().
For instance, let's say your form name is Main and was created in GUI Builder, you can do the following:
#Override
protected void beforeMain(final Form f) {
f.removeAllCommands();
Toolbar toolbar = new Toolbar();
f.setToolbar(toolbar);
toolbar.setTitleComponent(new Label("My Form Name", "Title"));
toolbar.addCommandToOverflowMenu(edit);
toolbar.addCommandToRightBar(backCommand);
f.setBackCommand(backCommand);
...
}
#Override
protected void postMain(final Form f) {
//fetch remote data here
...
}
Related
I am developing an Eclipse RPC application and I have an editor (MainEditor) that contains two pages. The first page (Properties) displays the data of the model using some text fields and the second page (Source) is an editor that is instantiated from a class (SourceCodeEditor) that inherits the CompilationUnitEditor class and displays the source code that contains some annotations and some code.The annotations' values should correspond to the data in the model (the data is stored in variables in the model) .The new class (SourceCodeEditor) does nothing special it only override two super functions and executes the super implementation like so :
#Override
public void doSave(IProgressMonitor progressMonitor) {
super.doSave(progressMonitor);
}
#Override
public void doSaveAs() {
super.doSaveAs();
}
So I would like to add a listener to the instance of the SourceCodeEditor variable that updates the values of the annotations to correspond to the data in the model every time this editor/page is opened. The reason for that is that when I change a text field in the "Properties" page and open the "Source" page without saving the text displays the values before the change not after. If there is a better way to bind the values of the annotations in the source code and the variables of the model,please let me know.
I have a conceptual question.( some questions ! )
Let explain it with a real project.
I have a Login swing form,it has the main method and application starts from here.
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Login().setVisible(true);
}
}); // this method is inside main Method
The Login Form contains some TextFields and Buttons,And also some methods.
( For example when I press the Enter Button some authenticatation and action perform )
After press Enter Button, if authenticate success it goes to another form named MainTabbedForm.
Now the question is about Object Oriented Programming and class loading.
I want to access the Login Form form the MainTabbedForm. For example I want to dispose the Login Form after authentications successfully, And wanna do it in the MainTabbedForm constructor. I write a method inside the Login class to connect the Login to the MainTabbedForm. In this way :
public void disappearForm(MainTabbedForm form) {
this.form=form; // I already has defined a MainTabbedForm field in top of the Login class
this.dispose(); // Dispose the Login class
}
And use it in the constructor of the MainTabbedForm, Before using just declare a Login Form as a field in MainTabbedForm;
public MainTabbedForm(Login login) {
this.login=login;
login.disappearForm(this)
}
But it gives me NullPointException because the Login has not initialize.
And if i make a new class of Login, of course it is a new class and will not DO the thing i want, because is a new instance and not the first created Login in main method.
Now I have a question, How can i connect these two class to each other?
Of course I can make a static method to do my job ! But i do not want to do that in this way.
I think because of this class loading and art of programming the frameworks and design patterns like OSGi and MVC and others has created, to mange loading and accessing services and objects and other things more dynamically, am i right?
Now the reply to these answers are really appreciate !
In Login you could do:
MainTabbedForm mtf = MainTabbedForm(); //create
//set the required information using setters
//for example set userName which is defined in Login to MainTabbedForm
mtf.setUserName(this.userName);
//....
this.dispose(); //when no longer needed
Is it possible to edit/access javaFX elements (such as Buttons, Labels, etc.) in java code which is NOT the controller class?
I have written an entire program in java and want to make a GUI for it in javaFX (using Scene Builder). Since the entire code ALREADY is written in Java classes outside the FXML-controller class, is it possible to access elements like "Labels" inside my already written classes?
All I want to do is use this code outside the FXML-controller class:
label1.setText("Something");
So it updates on the GUI.
If not, it is a very time-consuming process to implement my java code in the FXML-controller class.
So I think your solution depends on how safe you need your information to be when interfacing with the FX GUI. If you are OK providing your data directly to the controller, then I'd suggest simply passing your data object into the controller's constructor and storing a reference to it locally. You can then use any getters/setters from the data object to populate your GUI, or update the model.
public class Controller {
private Object dataObject;
public Controller(Object dataObject) {
this.dataObject = dataObject;
}
}
However, if you want to protect your data, and prevent the GUI from directly modifying or interacting with it - you'll need to use a wrapper that protects your information.
public class Wrapper {
private Object dataObject;
public Controller(Object dataObject) {
this.dataObject = dataObject;
}
// allowable function call
public Object functionOne() {
return dataObject.functionOne();
}
}
You only need to implement functions in the wrapper that are directly needed by the GUI, thus preventing calls into your data object that you think should be restricted from the GUI.
Your controller then becomes:
public class Controller {
private Wrapper dataObject;
public Controller(Wrapper dataObject) {
this.dataObject = dataObject;
}
}
Is there a way to get the xpath of different input/href/div of a page loaded in a javafx webview?
For example:
I want to be able to load google.com
Click search box
return xpath of the search box in system.out.
Well I dont have an working example, but I can give you all the neccessary hinds you need. I also used this several times to communicate between Java and Javascript. What happens next is that you specify an Java class which will be injected into the Javascript part and which acts like a bridge between the two languages. First you need a callback class, which is called whenever you want to pass something from the JavaScript side to Java
import netscape.javascript.JSObject;
JSObject window = (JSObject) webView.getEngine().executeScript("window");
window.setMember("jsCallBack", new JSCallBack());
The callback class need at least one method which can be called from the Javascript side. in this case it is the callback() method
public final class JSCallBack {
public JSCallBack() {}
public void callback(final String response) {
System.out.println(response) ; // this is the String which you passed on the JS side
}
}
Now it is possible to invoke the callback() method from the Javascript side and it is also possible to pass arguments.
On the Javascript side you can call the callback function of the previously injected object by
function myCallback(value){
jsCallBack.callback(value);
}
The next thing you need to do is to specify a listener in Javascript, which listens for mouse events. There is already an existing post which copes with the problem of assembling the xpath for a clicked elements. After the assembly you only need to pass the result to the callback. On this blog you can also find an exmaple for communicating between JavaFx and Javascrit via callbacks.
So fa I only have experience in passing Strings from JS to Java, which works perfectly, I don't know if it works for differnt kinds of objects.
I am working on a PDF Invoice generator in Vaadin 7. The code as it stands at the time of this writing can be found here. The repo includes a crude class diagram.
My question concerns the best practice of collecting the user input from the TextField and other Vaadin components to create an instance of Invoice.
Currently it works like this:
When the user clicks the button to generate the pdf, the class VaadinInvoiceGui (a Panel) calls the method createPdf(VaadinInvoiceGui gui) in the class VaadinInvoiceController.
VaadinInvoiceController calls method getInvoiceFromForm(VaadinInvoiceGui gui) in class InvoiceMapperImpl.
InvoiceMapperIml creates and returns an Invoice (POJO) by calling get methods in the VaadinInvoiceGui that gets passed to it. These getters return the values of the components in the view.
VaadinInvoiceController takes the Invoice returned by InvoiceMapperImpl and goes on to create pdf from it etc..
The getters in VaadinInvoiceGui look like this.
public String getCustomerName() {
return infoPanel.getCustomerNameTextField().getValue().toString();
}
public String getCustomerStreet() {
return infoPanel.getCustomerStreetTextField().getValue().toString();
}
public String getCustomerCity() {
return infoPanel.getCustomerCityTextField().getValue().toString();
}
...
I really don't feel like it's a good idea to pass the whole gui class to the controller and especially to the mapper, but I'm not sure what would be a better way of doing it. I could change the method createPdf(VaadinInvoiceGui gui) to something like createPdf(String customer name, String customerStreet, ...) but the number of parameters of the method would grow huge. I could do it using setters but then it would basically be doing the object mapping in the gui which doesn't seem like a very clean idea either.
What is the proper way of doing this?
Write a bean for the data to pass around as your model. Then use the FieldGroup to bind between model and form. Wrap the model as BeanItem<Model>. Binding is either done by name (convention) or by annotation #PropertyId.
master-detail-example: https://vaadin.com/wiki/-/wiki/Main/Creating+a+master-details+view+for+editing+persons
general infos: https://vaadin.com/book/vaadin7/-/page/datamodel.html
binding in forms: https://vaadin.com/book/vaadin7/-/page/datamodel.itembinding.html