Reset JComponent to default value - java

For example, if component is a checkbox it must set to false, or it is a textfield it must be clear the text. I am trying to write a method for reset all components in a JPanel. It must work like reset function in HTML forms.
How to reset a JComponent to the default value?

As a good developer, you probably have a nice separation between view and model. When the model gets updated, those changes are then reflected in the view.
If you have such structure, you could simply reset your model to a default state, and that reset-ed state then become visible in the UI (which means the UI is reset to its default state)

One possible workaround would be to create a custom reset function. Reinitialize the panel ( your form).
For e.g.
void reset(){
//recreate the form panel.
formPanel = new FormPanel();
}
Create a custom class FormPanel to store the form fields and their listeners.
Re initializing the panel components would result in an overhead of reassigning the listeners as #Robin suggested.

There is no reset function in Swing. The best way to do this is to create a method with the values you want to reset and set everything here e.g. :
public void resetWindow(){
checkBox.setSelected(false);
textField.setText("");
}
The advantage of using this way is that you can just reuse this method whenever you want to reset and also when the class loads.
The other way you could do it is by creating another instance of your Panel and throwing away the original. That way everything would be in the start state.

Write a method which sets the initial values of all elements on start. Then you can reuse this initialization method to "reset" the values.

there is no reset sort of method for swing component, your code should handle it.

Related

How to update a panel which shows details of an object

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.

How can I reference a variable in one JFrame from another JFrame?

I have a JFrame with buttons and when I click one of the buttons an integer decreases by 1. I am trying to show the integer in another JFrame but when I reference it I get an error saying non static variable cannot be referenced in a static context. How can I make this a non static variable?
Here is the code from when a button is clicked.
private void DietPepsiBTNActionPerformed(java.awt.event.ActionEvent evt) {
MessageLBL.setText("Enjoy your Diet Pepsi!");
credit -= 1.00;
stCredit = Double.toString(credit);
CreditAMT.setText("$" + stCredit);
Refresh();
dietPepsi -= 1;
Provide some kind accessor in the master frame (to allow other components to read the value) (something like getValue() for example).
When ever the value is changed, fire some kind of event. You could cheat and use a PropertyChange event which would require you not to add any additional code, or you could fire something like a change event that notifies the other frame that the value has changed.
The second frame would then use the getValue method to read the value.
This would require the second frame to have a reference to the master (so it can get the value).
Better yet, just create a model, allow the model to fire events and share the model.
Have a look at Observer Pattern for more details
Brendon's answer is close. Ideally what you do what he suggests, create a separate object and pass it in to each frame. The frames then share the objects. Since the frames themselves will have references to the object, you don't need any kind of global reference.
YourModel model = new YourModel();
Frame1 frame1 = new Frame1(yourModel);
Frame2 frame2 = new Frame2(yourModel);
Additionally, you implement the PropertyChangeListener idiom to where each frame subscribes to the property changes in YourModel.
That way, when Frame1 makes changes to YourModel, Frame2 will be notified of them and can keep itself up to date automatically.
Then the game becomes a matter wiring together objects and their listeners. After that, it's almost magic how it all works together.
Ref: http://docs.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html
Make a third object and pass a reference to both jframes. This shared object can store any properties that you need

Listeners in forms with JComponents

Right now, when I have a form with many JComponents, mainly JTextFields, JTextAreas, JComboboxes, JCheckBoxes and JButtons and want to control their behaviour, for instance the change of focus after a certain key was released, I do the following:
I put all my components in a JComponent[] and cycle through it, adding the appropriate listener. When an event is registered by said listener, I check with "instanceof" what kind of JComponent fired the event and assign the proper reaction.
I use this method for instance to cycle with VK_ENTER through the form, or to "firePropertyChange(..)" after a DocumentListener fires, or to add UndoRedoListeners and so on.
My question : is there a better way to do this and if yes, can you explain to me the benefits ?
but my question refers to the general practice of putting all
JComponents in an array and cycling through them for every listener
and every fired event. It works fine enough, but it feels a bit
"uneconomic",so I wanted to know if it is recommended practice, or if
there is a better way of doing it.
I usually write a custom listener (often as an anonymous class) per type/ instance if I have type/ instance specific behavior so that I can avoid instanceof and other other checks.
You'll want to customise the focus tranfersal system.
Take a look at How to Use the Focus Subsystem, in particular Customizing Focus Traversal

How to not render a component in wicket

I have table of player in html: [table]
How I can hide or not render this table when it is empty? I try to add if conditional in java code and add this table to the page only if there is some value but then wicket throws an exception that he cant find component with this id. So how I can do this?
It throws the exception because the html markup expects the component to exist. Ie you must add it.
If it's an entire panel you want to hide then using EmptyPanel is the will hide the entire panel.
You can also use component.setVisible(false) to hide it if its only one component in the panel.
You can override the isVisible() function and return false if no date is available. But, this function will be called a few times, so if determining if data is available(like, hitting a database) you can call the setVisible(boolean) function.
Another option is to exchange the Repeater with an EmptyPanel if no data is available.
You can use the same condition you already use in java, but instead of not adding the table to the page, use table.setVisible(false).
Another way to do it would be to override the setVisible() and isVisible() methods, but i don't think it is recommended (see here)
Hope this helps
As the other users have pointed out, overriding isVisible() is not recommended because this function is called many times before component is rendered.
You should instead override onConfigure() and put inside it the code that decides if your table must be visible or not. onConfigure() is called just once per request.

Add PropertyChangeListener to to multiple JComboBoxes

i have a Table with JComboBoxes and want to add aPropertyChangeListener to every single JComboBox, because some selections of ComboBoxes have to change the selectables of other JComboBoxes.
I can't add all those listeners manually because there are very much of them.
I'm initializing the ComboBoxes with an array, so i already tried to add the listener when I create the JComboBox like this:
comboBox[i].addPropertyChangeListener(new PropertyChangeListener()
But it didnt work because the field variable i is not final and I need this variable.
How can I store this variable in the comboBox or is there a other possibility to solve this Problem?
If you can create all those comboboxes, then you can also add 'all those listeners' manually. There are several options:
You create a new listener each time you create a new combobox, and pass that index i to that listener (either by anonymous class, inner class, or fully fledged class) or by making a final copy as Francis Upton suggested in his answer
If you need that i only to retrieve the combobox from which the event originated, you can also call event#getSource (which is available on both the ActionEvent as well as on the PropertyChangeEvent since your question is not clear about the type of listener). In this case you can either create the listener only once, or create one listener for each combobox
You can extend JComboBox and init what you want in constructor
In your loop you can copy i to another final variable, and refer to that final variable in your ActionListener.
Instead of using an anonymous class, make a real class that implements the interface you care about. That way you can pass the combobox index (or even the combobox instance if that is all you need).

Categories