Parent Files: FXML-A & Controller-A
Child Files: FXML-B & Controller-B
I have above hierarchy structure where FXML-B is on top of FXML-A, loaded from the Controller-A using "parent_stackPane.getChildren().setAll(child_fxmlLoader_load)" kind of a way. So FXML-A is the parent of FXML-B.
Is there anyway that I can change the text of the label in parent FXML-A from the child Controller-B?
Define a StringProperty in ControllerB:
public class ControllerB {
private StringProperty text = new SimpleStringProperty();
public StringProperty textProperty() {
return text ;
}
public final String getText() {
return textProperty().get();
}
public final void setText(String text) {
textProperty().set(text);
}
// other code as before ...
}
When you load the second fxml in ControllerA, bind the text of the label to the textProperty:
public class ControllerA {
#FXML
private Label label ;
#FXML
private StackPane parentStackPane ;
#FXML
private void someHandlerMethod() throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("FxmlFileB.fxml"));
Parent rootB = loader.load();
ControllerB controllerB = loader.getController();
label.textProperty().unbind();
label.textProperty().bind(controllerB.textProperty());
parentStackPane.getChildren().setAll(rootB);
}
// other code as before...
}
Now when you call setText(...) in ControllerB, it will update the text in the label.
Related
I have the following main class:
public class JavaFXApplication4 extends Application {
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Add to the list");
TextArea peopleList = new TextArea();
String name = "name";
String surname = "surname";
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Person p = new Person(name, surname);
}
});
StackPane root = new StackPane();
root.getChildren().addAll(btn, peopleList);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("People list");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
I want that the constructor of the class Personadds name and surname into the TextArea peopleList into the main class.
public class Person {
public String name, surname;
public Person(String n, String s){
}
}
How can I access elements of the main class from other classes?
Make those variables either instance variables or class variables , Since local variable can be accessed only inside the function in which they are declared .
if you use instance variable make them private and Use getters and setters to access them
private TextArea peopleList = new TextArea();
public TextArea getPeopleList(){ // getter to access
return peopleList;
}
public void setPeopleList(TextArea peopleList){
this.peopleList=peopleList;
}
Made the object of MainClass in other class and use them using getters and setters.
Or Made them static/class variables in Main class so can be accesed with the name of Main Class.
static TextArea peopleList = new TextArea();
and in Other class
MainClass.peopleList
how already stated here i am currently trying to get into gwt editors.
I figured i was missing a backing list to hold the data i manipulate.
I tried to assign that backing list with a setValue call from the parent view. Now the compiler complains it is missing the getter for groupList.
I understand that by convention the groupList property is derived by naming the Editor groupListEditor. What would be the right way to attach the lists? It seems i need to somehow call setValue with a list or else it does not seem to work. What would be the right way to do it?
My Editor looks like this:
public class GroupListEditor extends Composite implements
IsEditor<ListEditor<String, GroupItemEditor>> {
private static StringListEditorUiBinder uiBinder = GWT
.create(StringListEditorUiBinder.class);
interface StringListEditorUiBinder extends
UiBinder<Widget, GroupListEditor> {
}
#UiField
FlowPanel pWidget;
#UiField
PushButton bAdd;
#UiField
FlowPanel pList;
private class StringItemEditorSource extends EditorSource<GroupItemEditor> {
#Override
public GroupItemEditor create(final int index) {
GroupItemEditor subEditor = new GroupItemEditor();
pList.insert(subEditor, index);
subEditor
.addDeleteHandler(new EditorDeleteEvent.EditorDeleteHandler() {
public void onEditorDeleteEvent(EditorDeleteEvent event) {
remove(index);
}
});
return subEditor;
}
#Override
public void dispose(GroupItemEditor subEditor) {
subEditor.removeFromParent();
}
#Override
public void setIndex(GroupItemEditor editor, int index) {
pList.insert(editor, index);
}
}
private ListEditor<String, GroupItemEditor> editor = ListEditor
.of(new StringItemEditorSource());
public GroupListEditor() {
initWidget(uiBinder.createAndBindUi(this));
}
#UiHandler("bAdd")
void onBAddClick(ClickEvent event) {
Log.debug("Add button clicked");
add();
}
private void add() {
String s = "";
//TODO: Problem is there is no backing list, FIx this
editor.getList().add(s);
}
#Override
public ListEditor<String, GroupItemEditor> asEditor() {
return editor;
}
private void remove(final int index) {
editor.getList().remove(index);
}
}
The Editor is used as a sub-editor in a editor widget like this:
I tried to set the backing list:
public class ContainerEditorDialogPresenterWidget extends PresenterWidget<ContainerEditorDialogPresenterWidget.MyView> implements
ContainerEditorDialogUiHandlers {
private final PlaceManager placeManager;
#Inject
ContainerEditorDialogPresenterWidget(EventBus eventBus,
MyView view, PlaceManager placeManager) {
super(eventBus, view);
getView().setUiHandlers(this);
this.eventBus = eventBus;
this.placeManager = placeManager;
}
/**
* {#link LocalDialogPresenterWidget}'s PopupView.
*/
public interface MyView extends PopupView, ContainerEditView<ContainerDto>, HasUiHandlers<ContainerEditorDialogUiHandlers> {
}
private ContainerDto currentContainerDTO = null;
private DeviceDto currentDeviceDTO = null;
private final EventBus eventBus;
private SimpleBeanEditorDriver<ContainerDto, ?> driver;
public ContainerDto getCurrentContainerDTO() {
return currentContainerDTO;
}
public void setCurrentContainerDTO(ContainerDto currentContainerDTO) {
this.currentContainerDTO = currentContainerDTO;
}
public void setCurrentDeviceDTO(DeviceDto currentDeviceDTO) {
this.currentDeviceDTO = currentDeviceDTO;
}
#Override
public void onReveal() {
super.onReveal();
driver.edit(currentContainerDTO);
}
#Override
protected void onBind() {
super.onBind();
driver = getView().createEditorDriver();
}
#Override
public void updateContainer() {
ContainerDto dev = driver.flush();
eventBus.fireEvent(new ContainerUpdatedEvent(dev));
}
}
I tried to assign the backing list (just an empty string list) in the view:
public class ContainerEditorDialogView extends
PopupViewWithUiHandlers<ContainerEditorDialogUiHandlers> implements
ContainerEditorDialogPresenterWidget.MyView, Editor<ContainerDto> {
interface Binder extends UiBinder<PopupPanel, ContainerEditorDialogView> {
}
public interface Driver extends SimpleBeanEditorDriver<ContainerDto, ContainerEditorDialogView> {
}
#UiField
TextBox uuid;
#UiField
TextBox name;
#UiField
TextBox groups;
//#UiField
//TextBox device;
//public TextBox getDevice() {
// return device;
//}
#UiField
GroupListEditor groupListEditor;
#UiField
TextBox imei;
#UiField
TextBox type;
#UiField
TextBox user;
#UiField
Button okButton;
#UiField
Button cancelButton;
#Inject
ContainerEditorDialogView(Binder uiBinder, EventBus eventBus) {
super(eventBus);
initWidget(uiBinder.createAndBindUi(this));
ListEditor<String, GroupItemEditor> ed = null;
groupListEditor.asEditor().setValue(new ArrayList<String>());
}
#Override
public SimpleBeanEditorDriver<ContainerDto, ?> createEditorDriver() {
Driver driver = GWT.create(Driver.class);
driver.initialize(this);
return driver;
}
//Should this handled by a presenter?
#UiHandler("okButton")
void okButtonClicked(ClickEvent event) {
getUiHandlers().updateContainer();
hide();
}
#UiHandler("cancelButton")
void cancelButtonClicked(ClickEvent event) {
hide();
}
}
Thank you!
Update:
A version of the GroupListEditor without a separate ArrayList would look like this and is what i started with:
public class GroupListEditor extends Composite implements
IsEditor<ListEditor<String, GroupItemEditor>> {
private static StringListEditorUiBinder uiBinder = GWT
.create(StringListEditorUiBinder.class);
interface StringListEditorUiBinder extends
UiBinder<Widget, GroupListEditor> {
}
#UiField
FlowPanel pWidget;
#UiField
PushButton bAdd;
#UiField
FlowPanel pList;
private class StringItemEditorSource extends EditorSource<GroupItemEditor> {
#Override
public GroupItemEditor create(final int index) {
GroupItemEditor subEditor = new GroupItemEditor();
pList.insert(subEditor, index);
subEditor
.addDeleteHandler(new EditorDeleteEvent.EditorDeleteHandler() {
public void onEditorDeleteEvent(EditorDeleteEvent event) {
remove(index);
}
});
return subEditor;
}
#Override
public void dispose(GroupItemEditor subEditor) {
subEditor.removeFromParent();
}
#Override
public void setIndex(GroupItemEditor editor, int index) {
pList.insert(editor, index);
}
}
private ListEditor<String, GroupItemEditor> editor = ListEditor
.of(new StringItemEditorSource());
public GroupListEditor() {
initWidget(uiBinder.createAndBindUi(this));
}
#UiHandler("bAdd")
void onBAddClick(ClickEvent event) {
Log.debug("Add button clicked");
add();
}
private void add() {
String s = "Stuff";
editor.getList().add(s);
}
#Override
public ListEditor<String, GroupItemEditor> asEditor() {
return editor;
}
private void remove(final int index) {
editor.getList().remove(index);
}
}
Since i declare the Editor as
#UiField
GroupListEditor groupListEditor;
Should the required getter of ContainerDto not be named getGroupList() ?
You refer to DeviceDto, which is just carried around and should not interfere with the editor.
Since the GroupListEditor implements
IsEditor<ListEditor<String, GroupItemEditor>>
it should expect a List, right?
My ContainerDto has the field
protected ArrayList<String> groupList;
So that should be fine, i guess. This was my starting point before trying to manually call setValue.
When i that, i get this error, when clicking the "Add" button.
Caused by: java.lang.NullPointerException: null at
testproject.client.application.containers.editor.GroupListEditor.add(GroupListEditor.java:81)
at testproject.client.application.containers.editor.GroupListEditor.onBAddClick(GroupListEditor.java:76)
which refers to editor.getList().add(s) which means there is no list...
Update 2:
I changed the declaration of the UIField to:
#UiField
#Path("groupList")
GroupListEditor groupListEditor;
But i still get the NullPointerException when trying to add stuff to the list like before: editor.getList().add(s);
You don't have to manually call setList to pass the list to your SubEditor. That should be taken care of for you by the parent/container Editor.
However the Editor will use the UiField name to match the corresponding getter in your backing DTO.
In your above example this will only work if your DeviceDTO has a getGroupListEditor() getter that returns the type that your ListEditor expects (beacuse of #UiField GroupListEditor groupListEditor;).
If your DeviceDTO doesn't contain the corresponding getter you can do 3 things:
Rename your #UiField GroupListEditor groupListEditor; (i.e. groupItems)
Rename the getter in your DeviceDTO to getGroupListEditor
add Path('groupItems') to your #UiField GroupListEditor groupListEditor;
Solution 3 is usually the way to go:
#UiField
#Path('groupItems')
GroupListEditor groupListEditor;
Note: Change groupItems has to match the getter in your DeviceDTO that returns the group items.
Update:
This is how your DeviceDTO looks like and how you use Path to point your editor to the correct getter. As long as your groupList class variable is initialized to an empty ArrayList everything should work fine.
class DeviceDTO {
protected List<String> groupList = new ArrayList<String>();
public List<String> getGroupList() {
return groupList;
}
}
public class ContainerEditorDialogView extends
PopupViewWithUiHandlers<ContainerEditorDialogUiHandlers> implements
ContainerEditorDialogPresenterWidget.MyView, Editor<ContainerDto> {
....
#UiField
#Path("groupList")
GroupListEditor groupListEditor;
}
i have been trying to implement datagrid in my project , the problem is that the data grid does not show data , the data is there but is not visible , i tried to inspect the html page and with adding some height and width to the inner divs inside the datagrid parent div the data is displayed perfectly , i can do this using css and its done , but if there is another solution or in other words anyone knows whats wrong with datagrid?
public class DataGridTest implements EntryPoint, ClickHandler {
private ListDataProvider<TestObject> listProvider;
public void onModuleLoad() {
List<TestObject> list = new ArrayList<TestObject>();
list.add(new TestObject("Amer",22));
list.add(new TestObject("Essa",25));
list.add(new TestObject("Asem",29));
DataGrid<TestObject> dataGrid = new DataGrid<TestObject>();
dataGrid.setStyleName("dataGridTest");
TextColumn<TestObject> nameColumn = new TextColumn<TestObject>(){
#Override
public String getValue(TestObject object) {
return object.getName();
}
};
dataGrid.addColumn(nameColumn,"Name");
TextColumn<TestObject> ageColumn = new TextColumn<TestObject>(){
#Override
public String getValue(TestObject object) {
return object.getAge()+"";
}
};
dataGrid.addColumn(ageColumn,"Age");
listProvider = new ListDataProvider<TestObject>();
listProvider.addDataDisplay(dataGrid);
listProvider.setList(list);
LayoutPanel layoutPanel = new LayoutPanel();
layoutPanel.add(dataGrid);
RootPanel.get().add(layoutPanel);
layoutPanel.forceLayout();
Button btn = new Button("lala");
btn.getElement().getStyle().setPosition(Position.ABSOLUTE);
RootPanel.get().add(btn);
btn.addClickHandler(this);
}
public class TestObject {
private String name;
private int age;
public TestObject(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
#Override
public void onClick(ClickEvent event) {
listProvider.getList().add(new TestObject("lala", 10));
}
}
You are mixing RootPanel and LayoutPanel, which doesn't work.
You must use RootLayoutPanel instead.
The DataGrid has to be put in a LayoutPanel and there must an unbroken chain up to the RootLayoutPanel.
Alternatively you have to specify explicit dimensions (height, width) on the parent container of your DataGrid or use a CellTable instead.
RootLayoutPanel.get().add(layoutPanel) should fix your issue.
I am trying to build a view in my RCP application, the view just contains a TreeViewer.
The tree can contain folders or leafs, a folder can contain folders and leafs. when I add a folder to the back-end data model of the root folder, the UI is updated automatically, but if I add a folder to any branch folder, the UI will not be updated automatically. please tell me what's wrong with my code.
The model class:
public class TreeNode extends BindableObject {
private Folder parent;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
super.firePropertyChange("name", this.name, this.name = name);
}
public Folder getParent() {
return parent;
}
public void setParent(Folder parent) {
this.parent = parent;
}
}
public class Folder extends TreeNode {
private List<TreeNode> children = new ArrayList<TreeNode>();
public List<TreeNode> getChildren() {
return children;
}
public void setChildren(List<TreeNode> children) {
this.children = children;
}
public void add(TreeNode node){
children.add(node);
}
}
the view :
public class ExplorerView extends ViewPart {
private WritableList data;
private TreeViewer treeViewer;
public WritableList getData() {
return data;
}
public TreeViewer getViewer(){
return treeViewer;
}
public ExplorerView() {
// TODO Auto-generated constructor stub
}
#Override
public void createPartControl(Composite parent) {
parent.setLayout(new FillLayout(SWT.HORIZONTAL));
treeViewer = new TreeViewer(parent, SWT.BORDER);
treeViewer.setContentProvider(new ObservableListTreeContentProvider(new ExplorerObservableFactory(), new ExploerTreeStructureAdvisor()));
treeViewer.setLabelProvider(new ExplorerTreeLabelProvider());
ArrayList<TreeNode> list = new ArrayList<TreeNode>();
list.add(new ExplorerDataModel().getElements()[0]);
data = new WritableList(list, TreeNode.class);
treeViewer.setInput(data);
}
#Override
public void setFocus() {
}
}
the ObservableFactory:
public class ExplorerObservableFactory implements IObservableFactory {
#Override
public IObservable createObservable(Object target) {
System.out.println(target.getClass().getName());
if(target instanceof WritableList){
return (WritableList)target;
}
else if(target instanceof Folder){
List<TreeNode> children = ((Folder)target).getChildren();
return new WritableList(children, TreeNode.class);
}
return null;
}
}
the TreeStructureAdvisor:
public class ExploerTreeStructureAdvisor extends TreeStructureAdvisor {
#Override
public Object getParent(Object element) {
return ((TreeNode)element).getParent();
}
#Override
public Boolean hasChildren(Object element) {
if(element instanceof Folder){
return true;
}else{
return false;
}
}
}
the data :
public class ExplorerDataModel {
public TreeNode[] getElements() {
Folder f1 = new Folder();
f1.setName("Database Connections");
Folder f11 = new Folder();
f11.setName("Credit Test");
TreeNode t1 = new TreeNode();
t1.setName("bank#localhost");
f11.add(t1);
t1.setParent(f11);
TreeNode t2 = new TreeNode();
t2.setName("credit#localhost");
f11.add(t2);
t2.setParent(f11);
Folder f12 = new Folder();
f12.setName("Credit Product");
TreeNode t3 = new TreeNode();
t3.setName("nbcbcredit#localhost");
f12.add(t3);
t3.setParent(f12);
TreeNode t4 = new TreeNode();
t4.setName("nbcbcredit_bak#localhost");
f12.add(t4);
t4.setParent(f12);
f1.add(f11);
f11.setParent(f1);
f1.add(f12);
f12.setParent(f1);
return new TreeNode[] { f1 };
}
}
the test command handler:
public Object execute(ExecutionEvent event) throws ExecutionException {
ExplorerView v =(ExplorerView) HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().findView("com.amarsoft.dmp.explorer.explorerView");
Folder f = new Folder();
f.setName("ODA Flat Files");
v.getData().add(f);
Folder f1 = (Folder) v.getData().get(0);
f1.setName("Database Connections (3)");
Folder f2 = new Folder();
f2.setName("Report Test");
f1.add(f2);
return null;
}
if I execute above command, the added folder "ODA Flat Files" will appear in the tree immediately, but the added folder "Report Test" will not be there, if call TreeViewer#refresh() everything is ok, but I want to know why.
Modifying your model does not notify your tree. Refresh is one way of telling the tree that the data has changed and it needs to update. If you go through the java doc for jface viewers in eclipse you will find the following quote
To handle structural changes, use the refresh methods instead.
It seems you misconfigured the data binding...
Have a look at the official snippets:
With a List Factory
With a Set Factory
With a more than a list as Factory
Have fun! (without any refresh ;-) )
ps. for EMF just look at this: http://tomsondev.bestsolution.at/2009/06/08/galileo-emf-databinding-%E2%80%93-part-3/
In your ExplorerObservableFactory replace
... else if(target instanceof Folder){
List<TreeNode> children = ((Folder)target).getChildren();
return new WritableList(children, TreeNode.class);
}
by following
else if(target instanceof Folder){
return BeansObservables.observeList(target, "children");
}
If you return WritableList here, the contentProvider's listener is registered on it (it should be registered on the Folder bean instead)
I have a cell table in one of my GWT screen. Now requirement is that there will be some button on the screen clicking on which one editable row will be inserted into the cell table. if I am not wrong this is called inline editing.
Can somebody please help me with that? I have just started working in GWT.
Here is very simple example of adding new editable row to the celltable. I hope I understand what you meant :)
public class Test
implements EntryPoint
{
public void onModuleLoad()
{
//create and attach table
final CellTable<A> table = new CellTable<A>();
RootPanel.get().add(table);
//add editable cell
table.addColumn(new Column<A, String>(new TextInputCell())
{
#Override
public String getValue(
A object)
{
return object.getA() == null ? "" : object.getA();
}
});
//put some data
ListDataProvider<A> dataProvider = new ListDataProvider<A>(
Arrays.asList(new A("AAA"), new A("BBB"), new A("CCC")));
dataProvider.addDataDisplay(table);
//add button with click handler
RootPanel.get().add(new Button("add new", new ClickHandler()
{
#Override
public void onClick(
ClickEvent event)
{
//add new object to visible items
List<A> data = new ArrayList<A>(table.getVisibleItems());
A newOne = new A();
data.add(newOne);
table.setRowData(data);
}
}));
}
class A
{
String a;
public A(
String a)
{
super();
this.a = a;
}
public A()
{
super();
}
public String getA()
{
return a;
}
public void setA(
String a)
{
this.a = a;
}
}