I'm using the card layout to create my app,
2 of my cards are shearing the same information (in one you enter data to textarea and in the other the data is printed).
The data is been saved in the Frame.
I have added a refresh function to the second card that get the value and print it, But I don't know how to trigger it.
Is there any event that can be bind to this function?
Or any other way to get to the card functions from the frame (so I can trigger it every time I show the card)?
Thanks'
There are generally two ways of achieving what you are after. Either you update/refresh the output card whenever it is displayed, like you suggested. This can be done by adding a ComponentListener to the Component that you use as your output card. This way you can override the componentShown method so that it calls your custom refresh method. See the accepted answer for this question.
The second alternative is to call refresh whenever any of the data is changed - always keeping it up to date, even when it is not actually visible. Depending on how your application looks this might be done in different ways. If you have a dedicated data model then you could use the Observer / Observable pattern to notify changed from an internal model, or you could hard-code the model to call refresh whenever it is changed. If you just want to get the data directly from the input fields on the first card, then you could just add that code into their respective change listeners etc.
Related
I'm dealing with a WebApp (Vaadin19) and stuck now in the question, how to share an object-state change from one component to another. There is one object instance in two or more components. After changing an attribute of the object in one component and going back to another component, I want to see the changed attribute.
Let me explain, what I mean:
There is a grid with some lines of data. The grid shows only a subset of the data to respect the clarity.
A click on the grid opens a detailed view in "read mode". The data is structured (contains sub-objects itself).
A click on the "read mode"-view opens then a dialog with tabs. The activated tab depends on the sub-object, that was clicked before.
After changing an element in the sub-object and closing the dialog, I want that the UI will reload/revalidate it's content. I think it's clear, that I use there the same object-instance.
Is there an event I have to submit to the UI?
Or:
What is the best approach for this?
The actual refresh is easy: theGrid.getDataProvider().refreshAll(), or refreshItem instead if you have access to the item that has been changed and it has a good implementation of equals and hashCode.
How to hook things up so that the dialog notifies the grid is then really depending on your architecture.
If they are already close to each other in the code, then you could e.g. store a reference to the Grid in an instance field and just reference that in the dialog handler.
If you want to decouple, then you need some kind of event bus. You can use the regular Spring event mechanisms as long as you ensure that the event stays within the UI scope. Alternatively, you can use ComponentUtil::addListener and ComponentUtil::fireEvent to use e.g. UI.getCurrent as a simple event bus.
I have a panel, let's call it detailsPanel, which holds a Person reference and displays its field values in the following manner:
Name: person.getName ();
Surname: person.getSurname ();
Emain: person.getEmail ();
.... .......
.... .......
And so on. I will use JLabels (correctly aligned using a GridBagLayout) to show each (fieldName, fieldValue). I have a lot of fields to display.
The problem is that the panel which shows the details must be always visible, i.e it will not be shown in a modal JDialog, so that i could create the panel by simply reading my Person object fields at the panel creation.
The panel must always be visible, and its Person reference will change when the user selects a different row in a Person list. This means i will call a method to update its state, something like:
detailsPanel.setPerson (aPerson);
Now, i'm wondering how i should update all the fields. Should i keep a reference to all the JLabels which show the values, and use setText(value) on each of them when i update the panel, or would it be better to override getText() method for every label, returning the correct field value, so that in the update method i would only repaint the panel, and the text would automatically change when the getter method is used on a different Person object?
Any suggestion is appreciated!
Since this is UI stuff which is usually called almost never (relative to how often things are called in other computation) you don't need to worry about efficiency at all. Just do what you think is the most elegant solution. There are three options That quickly come to my mind. They are ordered from quick and static to elegant and reusable:
Quick and dirty: create your constructor and make everything look nice. Then move everything from the constructor to a separate init() method and every time the entities change, you just call removeAll(); and then init() again.
As you suggested, keep a reference to all labels and use the setPerson() method to update all panels. Then call this method in the constructor (this is arguably the most common solution).
As you suggested, build your own extension of JLabel. This new class should either have an update() method which is to be called when things change, or have it set its own listeners to ensure that it gets notified of any relevant change.
If you are planning to create a single panel which is supposed to display all kinds of objects, you could have those object implement an interface called Displayable which gives you generic access to all its values and maybe even listeners to each value. An alternative to the Displayable interface is to use reflection and use annotations to allow the panel to get its values for display.
Please note that the most elegant solution is - contrary to what some people may tell you - not always the best for any situation. How much maintenance do you expect there to be in the future? How big is the application? Will you ever hand off the code to someone else? All these and more need to be considered to decide how "nice" you want your solution to be.
I have 5 JFrames in my application and I want the values from all 5 JFrames to be sent to a single JFrame. And it is a process where I have to go one frame to another and the value entered previously should not be lost and must be visible at the end of the process.
Easy example is,
I key in my name in the first frame,
then I key in my Address in the second frame,
then my mobile number in the third frame
and so on till the last frame where I want my keyed in details in the previous forms to be in the final frame to display my data in JTextfields. Is this possible? Because if it is a single form, I know how to do it. But when it is multiple forms in this situation I am lost. Please help.
This has nothing to do with Swing or JFrames and all to do with the general issue of getting information from one object into another. Yes it's possible -- give the classes that you wish to extract information from "getter" methods, and then call them when you want the information. If you want to gather this information in an event-dependent fashion, then you will need to have one class listening for state changes brought on by events in the other classes. A PropertyChangeListener can work well for this.
Or if you use modal JDialog windows instead of JFrames, you will always be notified when the dialog has returned and is no longer visible, since the calling code's program flow resumes from right after where it told the dialog to become visible.
Next we can discuss whether having 5 separate JFrames is a good idea or not. I'm guessing you know my opinion on this, else I wouldn't have mentioned the subject.
In my application user gets to choose "distribution type" for a few parameters and then I create Graph and show it to him. There are 3 different types of these distributions with each of them having its own parameters ( like alpha, beta, probabilities, etc). Each parameter can have either of those distributions.
Here is the screenshot to make it clear, what I'm trying to describe:
Distribution options are contained in CardLayout, that is controlled by combobox.
When user presses the button, I need to instantiate proper domain objects for distributions. Right now, I'm just passing ComboBox item (which is enum) and CardLayouted panel to factory that chooses proper subpanel and instantiates correct object. But it seems wrong to pass around gui objects, also makes factory useless for any other situation.
But I can't think of a better way to instantiate correct object. Probably just one idea:
Let CardLayouted panel decide which panel is ontop and instantiate
proper object on request. I wouldnt need any factories for this one. But is it ok for gui object to do this kind of logic? How can I delegate to domain in a proper way?
All suggestions will be appreciated a lot!
Swing has generally good support for MVC and pushing or pulling data from a domain object to input / display controls. What I'd do is:
Instantiate the panels you put into the CardLayout with a "blank" domain object as its GUI model. (Or some sort of locator that can retrieve the model from another layer.) Then hook up change notifications on your input components that will update the domain object when the values in the input change.
Then, when it comes to persisting the domain object, just retrieve it from the form panel.
If you need to show the same model value in two controls, they should share the same model. If you need to do updates to an object being displayed from lower layers of the code, you should perform the update on the model instead of / in addition to the domain object.
I am trying the save the state of a previous frame and then carry it over to the other frame. More like saving the data of the textfields and areas so that when i press next button some text fields,and variables will be initialized in the next forms Labels and when you press back your previous data will still remain in your form inteface.Pls help
More like data binding but across different forms
You can use any varible for that, and pass it as parameter to every JFrame you create.
But it sounds more like you want to use a CardLayout for your JFrame and use different cards that can be shown for the user. See How to use CardLayout.
If you are trying to create a wizard like UI, you should look up Sun(oracle)tutorial here.
Use something like Java's XMLEncoder.