Add PropertyChangeListener to to multiple JComboBoxes - java

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).

Related

how to make a JTextArea have clickable buttons

As the title says I'm trying to make it so my JTextArea have some strings so that I can call other functions, like a hyperlink of sorts, can that be done?
For reference, I would like to know how the left side of any Tutorialspoint tutorial is made but in Java.
PS: I'm using a CardLayout.
EDIT: Something like this
Forget about using a JTextArea. Take a look at JList instead. This is Swing's basic list class. It supports the selection of one or more items from a list. Although often the list consists of strings, it is possible to create a list of just about any object that can be displayed.
Although a JList will work properly by itself, most of the time you will wrap a JList inside a JScrollPane, so long lists will automatically be scrollable.
A JList generates a ListSelectionEvent when the user makes or changes a selection. This event is also generated when the user deselects a n item. It is handled by implementing ListSelectionListener. This listener specifies only one method, which is called:
void valueChanged(ListSelectionEvent le)
Here, le is a reference to the object that generated the event. Although ListSelectionEvent does provide some methods of its own, often you will interrogate the JList object itself to determine what has occurred.
By default, a JList allows the user to select multiple ranges of items within the list, but you can change this behavior by calling setSelectionMode(int), which is defined by JList. The integer passed to this method must be one of the values defined by the ListSelectionModel interface:
SINGLE_SELECTION
SINGLE_INTERVAL_SELECTION
MULTIPLE_INTERVAL_SELECTION
You can obtain the selected values by calling getSelectedValuesList(), or, if you are using single selection, you can call getSelectedValue(). Once you have the selected the value(s), you can invoke the method(s) dedicated to that/those objects accordingly.
One last tip: In Java, they are called methods, not functions ;)
Happy programming!

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.

Can I call componentShown() method from a class that extends JFrame instead of JPanel ? If yes, how?

I want to show one JLabel and one JComboBox when one particular RadioButton is selected in previous frame, otherwise it should be hidden. Even when I implement ComponentListener in that class his abstract methods(componentShown(), componentHidden()) are never called.
I think that your problem can be handled pretty easily, without even getting into these event handlers. Just pass a variable from your initial frame, when the RadioButton is selected, to the new frame (maybe a boolean variable with true value). Then, in your new fame, simply show the components, based on the value of that variable.
I hope you can handle the passing of variables, by handling the constructor parameters of your new frame.
Hope this helps ! Any clarifications required, please comment.

How to automatically create buttons for each method in a class?

I want to have a list of objects with different objects.
I want a super class that has an abstract getOptions() method. Then I can create subclasses of the super class and when you select a object of the subclass it will make buttons for each option of in the subclass.
I want to be able to choose the options buttons will be made for. Like if I made a subclass that represented a file it would have two options like open and edit and the program would automatically make a open and edit button, but it also needs to support other subclasses that have different options and the program would make buttons for them instead.
It don't matter if it's a button, I just wanna know how I can get a list of all options in a subclass.
Have the child class return an instance of an Action instead. The actions can be put into a menu or toolbar as needed to form JMenuItem and JButton instances.
You can create an Option class and hold just a List<Option> variable in your entity classes like file and whatever...
But maybe I did misunderstand what you really want.
If you want list of your objects' methods or properties you can use Java Reflection. However I'm not sure if this is the best solution to implement your idea.

Reset JComponent to default value

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.

Categories