JavaFX Tabs and Controller Scope - java

I have a configurations pane in my JavaFX 8 application that is spread across a number of tabs within tabs. Currently I am forced to split tabs for a longer configuration process.
I know that I'll have two .fxml files for the two tabs, but I should be able to use the same controller for both. Currently, however, if I make changes to one tab, the other tab doesn't see the changes. I'm guessing it creates a separate instance of the controller. Is it possible for the two .fxml tabs to use the same instance of the controller so that the information can be shared across the two tabs?
Example for more clarification:
Tab1 contains textfield input for email, Firstname, etc.
Tab2 uses email information and generates usernames and allows user to modify other settings using the generated values.

To reuse a controller between multiple FXML loads, you can use fxmlLoader.setController() or fxmlLoader.setControllerFactory().
I don't really recommend a reused controller approach, so I won't post detailed code for it here. Rather, I recommend passing parameters.

Related

JavaFX: Identical tabs with different data

In Lazarus, there are 2 different kinds of tab elements (cf. Free Pascal docs):
TPageControl
TPageControl is a multi-page component that provides a container to hold a variety of controls per page.
TTabControl
It is a tabbed container component which looks identical to a TPageControl. However, there is a fundamental difference because the control always shows the same page whichever tab is selected. In fact, it containts only a single page. The idea behind this concept is illustrated best by an editor or viewer for text files: When the TabControl contains a TMemo then the individual tabs refer to the files loaded into the memo; whenever the active tab changes another file is loaded into the (same) memo.
In this sense, JavaFX TabPanes are quite similar to TPageControls, but I rather want to replicate a TTabControl. I know I could in fact programmatically create a new Tab(), but I want to visually design it in SceneBuilder.
Is there maybe a way to load a separate .fxml file into a new Tab() element which is then added to the TabPane? (And how could I then access a tab's children?)
I chose the easiest approach: Implementing a head-less TabPane to detect when the user switches between tabs. The elements that appear to the user as the “tab content” are actually placed outside the TabPane, and their content is dynamically changed whenever the tab is switched.

JavaFX TabPane - Change one tab, update the others

I have a TabPane with 10 tabs (each with its controller). In one of them I have a table 'categories' where the user can add / edit / delete categories.
The other tabs have the same table 'categories', smaller, in read-only mode, where the user can only select categories.
Then, when the table 'categories' is modified in the categories tab, what I want is for all other tables categories of the other tabs are updated.
What I thought is (not implemented yet), on the top panel to put a listener that detects tab changes and, when the user leaves the categories tab, check if changes have been made.
If so, call all the controllers involved to update their own tables of categories.
The question I have is, if there is a less cumbersome way to do this. Something like sending a message 'table has been changed' and all the 'listeners' tabs of the message update their tables. Similar to a locally JMS, not client-server. Is there something like this messaging service that can be employed within the same application or the solution that I raised above is the most consistent? I think the question is more Java than JavaFX.
Thanks a lot.
The easiest way would be to hold the categories in an ObservableList at some top level (say in your Application sub class) and have all the tables share a reference to that list (table.setItems(yourList)). Whenever a change is made in the categories tab, the other tabs will automatically reflect the change.

Basic MVC design: views

So there are two different views(controllers are merged into views):
View 1: Tabular view. There is a table and a number of buttons on top of the table.
View 2: Text view. There is a text area and a number of buttons which are distinct from the buttons in Tabular view.
There is one model file for two views files to link.
I also create a main.java file to declare the main window,a tabbed pane(to switch views) and bind views to it.
As a noob java developer and MVC design pattern learner, I was wondering:
1. What is the correct way to declare buttons, the table and text area?
For example, for View 1(Tabular), are its buttons and table declared in the view or in the main.java?
2. If declared in views, how are they added in the main window? Default UpdateAllViews() doesn't seem to go through the main window in main.java.
At this point, I am only aware that model should never ever have anything like JButton declared in it as model itself should not be aware about what the window and stuff looks and feels. I can see that controllers are sort of binded to a certain view componenet, but the view itself gets me very confused.
If anyone can provide a shortcut to get deeper understanding of MVC pattern, I'd be appreciated.
Please keep in your mind that you are dealing with objects. And the Model, View and Controller are categories/collections of objects.
Your model objects are instances of classes relating to your business domain. e.g. if you are making an address book, you would have an ADDRESS class.
Your View objects provide a connection to your users. e.g. SEARCHDIALOG class and ADDRESSDIALOG class.
Your Controller provides the bindings/interface into your system (the systems API). you will have one controller that represents the system, e.g. ADDRESSBOOKAPP class.
Enjoy.

Ratio of GWT Places to Activities to Screen?

I'm trying to write a GWT app that reuses the same template for every "page" (place). There are 4 main "pages" of the app:
Dashboard page (http://www.mywebapp.com/#dashboard)
Calculator page (http://www.mywebapp.com/#calc)
Configurator page (http://www.mywebapp.com/#config)
Login page (http://www.mywebapp.com/#login)
Each "page" has the same templated look-and-feel: (1) a header section that contains the logo and the navigation menu, (2) a content section that contains "page"-specific content (i.e. will be different for the #dashboard place, #login place, etc.), and (3) a footer section that contains some links. So you see, the only thing that changes from page-to-page is the content section. Just like an ordinary, templated web site.
The thing is, each "page" (place) is actually a fairly complicated UI with many different panels consisting of lots of widgets. As the user interacts with the app, these panels will come into and out of existence and the display will be changing all the time. For instance, on the #calc page, the user can select which "mode" to display a calculator in: either as Basic or as Advanced. When the user selects Advanced, several additional panels will display (in addition to the Basic panel).
It would be nice to be able to keep such actions in history, so that the user can bookmark the app in either Basic or Advanced mode, so something like:
http://www.mywebapp.com/#calc/basic; or
http://www.mywebapp.com/#calc/advanced
Here's the problem:
We already have several "levels" of activities/places going on here. At the "app"-level, we have the template that needs to be displayed to the user when the MyWebAppModule implements EntryPoint downloads. This TemplatePlace is the default/initial place that is registered with the HistoryHandler before calling:
public class MyWebAppModule implements EntryPoint {
#Override
public void onModuleLoad() {
// ...
// The first place we go to when this module downloads.
TemplatePlace templatePlace = getSomehow();
historyHandler.register(placeController, eventBus, templatePlace);
historyHandler.handleCurrentHistory();
}
}
Next, we have all the different "pages": DashboardPlace, CalculatorPlace, etc. that all have their own unique views/displays. For instance when the user clicks the Calculator link to go to CalculatorPlace, it should render a different view than when the identify that they want to use the calculator in Basic or Advanced mode.
Finally, we have the different display regions, panels, etc. inside each page/place, such as the BasicCalculatorPlace and AdvancedCalculatorPlace. This is what I mean by different "levels" of navigation:
Application-level (a template to apply to all pages/places)
Page- or place-level
Display- or panel-level
The question:
I want to achieve bookmarkable URLs (places) for when the user does all of the following:
Goes to the home page (http://www.mywebapp.com)
Goes to any of the "pages" (http://www.mywebapp.com/#calc, etc.)
Uses the pages/places which cause page-specific panel or display configurations (http://www.mywebapp.com\#calc\#advanced, etc.)
How many Activities and Places do I create? How many ActivityManagers? I guess I'm asking for how granular Activities/Places need to be for each "level" of bookmarkable UI. Thanks in advance!
I think you only need one ActivityManager and one Activity per "page". You can make your "header" and "footer" into widgets that can be reused in each page.
You can bookmark different states of the same page by using tokens. For example, you can set a token to "basic" - it would tell the CalculatorActivity to show basic calculator panel. The URL will look like:
www.myApp.com/?#Calculator:basic
When a user clicks on a widget to select an advanced option, you do
PlaceController.goTo(new CalculatorPlace("advanced"));
The CalculatorActivity will get the CalculatorView (which is already displayed), it will see that the token is set to "advanced" and it will instruct this view to show advanced panels.
Note that you can make your tokens as detailed as necessary and then parse them in Activity. For example, you can have something like
www.myApp.com/?#Calculator:option=basic&position=top&theme=pink

Cloning a frame/tab with swing components/buttons inside

OK a complete revision:
I have a JFrame with a tab that has buttons/textfields etc. inside.Buttons have events that does simple things like reading from an SQL server and filling the textfields from the received query.Pretty simple eh? And now ,I need to add more tabs to this Frame and have to have multiple tabs.In each tab I "must" have the same components/events. So what I am asking is this,how can I clone all the components/events/keylisteners etc. (whatever i have inside that tab) to another tab? I could always add the same components with different names from the code,but I need to find a way to clone the whole tab..
Why not keep the components you already have without duplicating them, and figure out a way to store all the data to be displayed in some kind of model. You could create only some buttons to simulate the tabs, and when clicking on one you display the data associated with it.

Categories