I would like to have a Java GUI library allowing something like this:
Window window1 = new Window();
window1.show();
Window window2 = new Window();
window2.show();
...
But a JavaFX window needs to be started within its own class extending Application and cannot be instantiated several times.
Why can a JavaFX window not be instanciated like other classes? Why is it called Application and not Window or Frame? Why does JavaFX breaks OOP? Why do we have to use singletons mixed with reflection? I want no magic, I want an OOP-behaving window object appearing on the screen.
But a JavaFX window needs to be started within its own class extending Application and cannot be instantiated several times.
This statement is wrong, there are restrictions on when you can invoke the constructor on the Window class, but they are not related to extending the Application class.
Why can a JavaFX window not be instanciated like other classes?
The constructor of the Window class is protected, so it can be "used only within the package and in sub-classes outside the package".
Instead, in your application, instantiate a class which is a sub-class of Window. The appropriate class to use is Stage. The constructors of Stage are public rather than protected like Window.
So, to show two stages (which are windows), you can write:
Stage stage1 = new Stage();
stage1.show();
Stage stage2 = new Stage();
stage2.show();
Why is it called Application and not Window or Frame?
An application is called Application because that what it represents. Within an application, you might have multiple Stages (which are instances of Windows), so it would not make sense to call an Application a Window. Anyway, an Application has a different purpose: It's main purpose is to implement the Application lifecycle interface and processing as described in the Application javadoc.
Why does JavaFX breaks OOP?
It doesn't. It uses a protected modifier on Window to enforce encapsulation, which is a key hiding technique of OOP. It provides subclasses of Windows via inheritance for different purposes such as Stages, which are your standard application windows, and PopupWindows, which are specialized window subsets helping with tasks such as creation of popup lists for context menus and combo boxes. It implements Separation of Concerns by differentiating between Application and Window functionality within separate class structures.
Your other questions and statements make no sense to me.
Related
I'm working on a Qt application and I need to create windows dynamically. Each window consists of QObject-based c++ backend and qml-based interface. Each window needs to be connected to the bunch of signals emitted by core classes.
Current solution is to derive window from QQuickView, connect signals to it and load qml using setSource(). Is it a right way or there is a better way?
Is it better to use one QQmlEngine for all windows (and use this engine as parent for every window) or create new engine for each new window?
For this I would expose a c++ model to the QML code.
Since this model would be dynamic (elements can be added or removed), I'd use a QAbstractItemModel derived model that can inform the views that some elements are added/removed. Using something else like a QList<QObject*> would mean that you'd have to tell the view that the entire model should be reloaded after each change.
Instead of implementing the model from scratch, you could use a class like QQmlObjectListModel from Qt QML Tricks, it exposes a QList-like API from c++ but is a QAbstractItemModel exposing the QObject properties as roles under the scene.
Another solution that you could use if you don't want to use QObjects is benlau's QSyncable (I've actually used this in a similar situation to yours, where I expose my screens in a model and instantiate a Window displaying a taskbar for each).
Then, I'd use a QQmlApplicationEngine and expose the model to it with setContextProperty. A QQuickView is already a window, so I don't think you want to use that, better to manage your windows manually in the QML code.
Then in your QML code, use an Instantiator as your root object, set your model, and use Window as its delegate :
Instantiator {
model: yourModel
Window {
/* ... */
}
}
An FXML newbie question. I have a JavaFX Application class which does not do a whole lot (anymore) other than setting up the scene, and a controller class which gets instantiated when the FXML file is loaded and where I moved much of the logic (because seemingly the main class and the controller class are not really aware of one another).
However, I have a method which sets up setOnDragDropped on the scene. Normally, my main app would handle drag events, but because of FXML, that logic needs to be in the controller now (for File->Open for example). I have not found a way to setup DragDrop from the controller because the "scene" is only known in the main class. And since I don't instantiate the controller directly (indirectly instantiated when FXML file is loaded), I can't pass it object references easily.
How can I link the main and controller so I can have a bit more flexibility in where I put the logic? Or how can I migrate the scene dragDrop handler to the controller?
Thanks
Actually I want to switch from one scene to another scene on particular event. So i can do that by setting scene of the stage without binding but i want to bind my stage with scene as soon as a flag changes my scene will change automatically....pls help
The JavaFX Demos and Samples Downloads contains an application called FXML-LoginDemo. It demonstrates how to change scenes in a stage. The important part happens in the method replaceSceneContent. As for automatically changing the stage when a flag in your application is updated, there are several ways to do that. I recommend using a PropertyChangeListener or using JavaFX withCDI and then using CDI events. I used the latter approach in my application and it works really well.
I would like to know what the established procedure is for initializing the controls within a Qt custom dialog box. In the code I am writing, the dialog would present a QListView containing directories from an object passed (by reference) to the dialog class during construction. When the dialog is displayed, I obviously want the list to display the directories currently configured in the object.
Where should this be done though? Perhaps in the overridden showEvent() method?
Background: I used to do a lot of MFC programming back in the day, and would have done this sort of stuff in the OnCreate method, or some such, once the window object had been created.
Thankfully Qt doesn't require you to do any hooking to find the moment to create things (unless you want to). If you look over the Qt examples for dialogs, most do all the constructing in the constructor:
http://doc.qt.io/archives/qt-4.7/examples-dialogs.html
The tab dialog example--for instance--doesn't do "on-demand" initializing of tabs. Although you could wire something up via the currentChanged signal:
http://doc.qt.io/archives/qt-4.7/qtabwidget.html#currentChanged
Wizard-style dialogs have initializePage and cleanupPage methods:
http://doc.qt.io/archives/qt-4.7/qwizardpage.html#initializePage
http://doc.qt.io/archives/qt-4.7/qwizardpage.html#cleanupPage
But by and large, you can just use the constructor. I guess the main exception would be if find yourself allocating the dialog at a much earlier time from when you actually display it (via exec), and you don't want to bear the performance burden for some part of that until it's actually shown. Such cases should be rare and probably the easiest thing to do is just add your own function that you call (like finalizeCreationBeforeExec).
I'm trying to implement a popup window (NativeWindowType.UTILITY) in an AIR 2.7 application that uses Swiz for dependency injection.
I have followed the Swiz guidelines that I've been able to find, and implemented ISwizAware on the class that creates the window, and I am calling _swiz.registerWindow() before opening the window, and dependency injection works fine on the window itself after this.
However, the problem I am running into is that I have a child view within that window, and I have a mediator that uses the [ViewAdded] and [ViewRemoved] tags. Neither the view added nor view removed functions are triggering. I'm thinking the issue is either:
The child view is not correctly registering with Swiz.
The swiz instance doesn't know about the beans (I have tried manually adding the bean however, which didn't have any effect).
The ViewAdded and ViewRemoved metadata tags simply aren't working because each NativeWindow object has its own stage instance.
Anyone know more about this?
Popups are a special case since they don't get added under the same display tree as your application. Under Stage (the main wrapper for Flash Player), you'll have Application where your code resides for Swiz, but Popup is in a separate layer above Application. Since they're siblings, Swiz cannot listen in for when the popup is being added to the Stage.
The way around this is to either set the properties of the popup manually (which is normally the easiest way) or manually add the popup to Swiz's awareness. For this you'll have to look at the documentation since I haven't touched Swiz in a long time.