If I have a massive Swing component in my application which takes a long time to initialize, and want to display this component in different places in my GUI at the same time, how would I preferably do this?
The GUI user must be able to interact with the different copies of the component
(they could, for example, work as mirrors).
Let's assume that one might want to display copies of this component dynamically, depending on the input of the GUI user (that is, we do not want pre-loading of many copies of the same component).
You need to change your components to access data in a model-view like fashion. Each component would need to point to the same model that would server up the data and do the intensive task once rather than multiple times.
Also, initialization is slowing the GUI, then it sounds like you need a splash screen or a progress bar and the task moved off the EDT.
Is there any way that you could pull the heavy-duty initialization code out, maybe into a '...Factory' class?
I would create a one instance of the component (let's say HeavyComponent) and a custom class extending e.g. JPanel and referencing the component. Let's name it MyContainer. On paintComponent() of the MyContainer I would draw original component into a BufferedImage or use heavyComponentReference.paint(g).
Then on click by the MyContainer I would swap the component replacing the panel with real instance of HeavyComponent and placing in the old location of the HeavyComponent new instance of MyContainer.
display this component in different
places in my GUI at the same time ...
without having to create a new copy of
the same component ... user must be able to interact with the different copies
No way.
Related
I have created a swing application in Netbeans environment. This application consists of four frames. Now my requirement is, after filling A frame when user clicks "Next" button then A's data should be buffered somewhere and then go to second form and so on. Finally when user lands in the last form, at this point i want the total data of all forms should be stored in database.
I am not sure how to achieve this. Can anyone suggest some useful resource or idea?
Consider having one non-GUI model class, that can be passed into the view (GUI) classes, either via a constructor parameter, or a setter parameter, i.e., public void setModel(Model model). Then all views can have the same Model instance passed into them.
When the first window has its data "submitted", it submits it into the one shared model. If you're using a Model-View-Control structure, then this is usually done by the Control, but if your program is simple, a Model-View is probably all you need. The other windows can be notified by the Model of the changed data, and then change their displays accordingly.
But as an aside, also please ask yourself, how many professional applications do you use that jump from window to window? Not many because it is a very distracting and often unpleasant experience for the user. Most use a single main application window that swaps gui views within this window and with an occasional dialog window popping up when information is needed in a modal fashion. Please have a look at The Use of Multiple JFrames, Good/Bad Practice?
In AS3, there is an event that listens for when an object is added to the stage. This is useful for cases where, for example, some variables are not set until it is added on-screen. By waiting until the object has been added, you can assure that all of those variables are set.
Is there an equivalent in swing? For example, I have a function that relies on an objects getWidth function. Obviously, if I try to call this before the object is added on screen, this function will have problems because the width will be zero. I would like this function to be called as soon as the component is added and has a width. In as3, I would do something like:
myComponent.addEventListener(Event.ADDED_TO_STAGE, myFunction).
How would I do that in Java?
Depending on your setup, a ComponentListener might be enough. There is a section in The Java Tutorials about ComponentListeners.
Another way of initializing stuff as soon as it is displayed is overriding the paintComponent method and performing the setup on the first invocation.
JavaScript is different from Java. There are no function objects in Java and hence no JavaScript-style callbacks. In Swing you can react to events related to showing/adding of components by adding ComponentListener or ContainerListenerto either component or container via addComponentListener() and addContainerListener() methods.
I basically have 1 class called ClueGame dedicated to painting the main gui using swing.
In this class, I iterate through a list of BoardCell objects, and call boardcell.draw(g) from within paintComponents(Graphics g), which draws rectangles to the board.
However, in a different class entirely, the WalkwayCell class (a child of BoardCell), I need to update the color of specific rectangles. I'm thinking something like cell.updateColor()
But obviously I need to get draw to do that some how. I don't know how to update the color of one object (rectangle) on the board because I can't call draw because I don't have a graphics object.
Hopefully that makes sense. I can post code if someone requests it.
You have any number of options...
You Could
Pass a reference of your ClueGame to the instances of WalkwayCell which would then be capable of calling repaint on the ClueGame reference directly.
The problem with this is you expose the entire ClueGame class to ever instance of WalkwayCell, which allows them to do whatever they want to it...
You Could
Use an observer pattern, to allow the ClueGame to monitor changes to the state of the WalkwayCells
This means that WalkwayCell doesn't really care, it will simply provide some kind of event notification when the state of the object changes and doesn't expose parts of your application to other parts that have no right to know about...
Swing makes use of the observer pattern for it's listener API. You could take a look at Writing Event Listeners for some more ideas...
When creating a Swing GUI, it’s important to create GUI model classes. The model classes hold the data for the GUI. Having model classes makes coding the Swing view classes so much simpler.
In your case, you would change the state of the instance of the WalkwayCell class, using a method like cell.updateColor(), as you suggested. First, you update the model instances. Then you draw the model instances on the view.
I've explained this concept in more detail with a working example in my Hangman Swing GUI article.
I have a program that uses 2-3 JFrame objects at the same time and adds components during runtime. I need one JFrame to send a message to the others and get them to repaint themselves. I'm fairly knew to java so please forgive me if I'm being an idiot and missing something simple.
Instead of multiple frames, use a single frame and as many modeless dialogs as needed. You can use a PropertyChangeListener to ensure that updates in one container are propagated to another, as shown here and here.
In my application I've a main shell window and lots of dialogs (classes extends Dialog). I use setSize(width,height) when initializing them, but I know that users constantly resize them for their taste.
What is a smarty way to get notified when the size changes so I can store/load them?
(And why don't do toolkit provide such a thing out of the box, like XUL?)
Most if not all GUI toolkits have a resize event that triggers whenever the user (or something else) resizes a given widget. Some readong for an example Moving and resizing - SWT
Take a look at java.util.prefs.Preferences. The width and height settings can be saved via putInt() and retrieved via getInt().
It would be a pretty minor task to subclass Dialog or JDialog and create a SizeRememberingDialog, or (probably better) to create a SizeRememberer(Dialog) class to set the size when constructed, listen for resize events, and save the new size whenever a resize occurs.