Java swing - same handler for multiple controls - java

I was wondering whether there is any other way to handle and event coming from any of N controls, which would read the ActionCommand value and act based on that. So far I basically have a defitinion of ActionListener which I add to each of the controls individually. For instance, if I have 50 checkboxes, I would like to write a method like
void process(){
getCommandValueAndDoSth();
}
but rather than instantiate ActionListener for all the checkboxes, I would like just to control all the checkboxes.

You can have one listener for all of your components.
ActionListener al = new ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// either do it like this
process(e.getActionCommand());
// or like this to distinguish between the controls
if (e.getSource() == firstElement) processChangeInFirstElement();
else if (e.getSource() == secondElement) processChangeInSecondElement();
// etc
}
}
Component firstElement = new JCheckBox("asdf");
firstElement.addActionListener(al);
Component secondElement = new JTextField();
secondElement.addActionListener(al);
If you need to have multiple types of listeners (ChangeListener, MouseListener, ActionListener, KeyListener, ...), then you have one instance of each of those listener types and apply them to the corresponding components.

You can attach the same ActionListener to multiple components (e.g. to all your Checkboxes). The handler just needs to be able to derive all the required information from the ActionEvent (if required it can get to the component using event.getSource()).

In my case I just wanted to know if any control in the window had been changed and should allow the user to "apply" those changes. You can actually add them pretty easily with lambdas. Below are examples for JCheckBox, JComboBox<>, and JXDatePicker. Both JTextField/JTextArea are a little more complicated and require document listeners.
chckbx.addItemListener(e -> process()); //Check box itemListeners don't trigger when hovering
comboBox.addActionListener(e -> process()); //Triggered when selection changes
datePicker.addActionListener(e -> process()); //When date changes
addChangeListener(txtField, e -> process()); //Text field needs a documentListener
The code for the text field's document listener addChangeListener.

Related

How to determine is a certain kind of GUI object caused event?

I have a simple GUI and want to handle events from a certain specific JComboBox and several JCheckBox objects. In the code below, I first check if the event was caused by the specific combo box (called senderId).
If not, I want to see it was caused by ANY of several check box objects. That's the part I need help with. How do I test the ItemEvent object to see if it was caused by any check box?
#Override
public void itemStateChanged(ItemEvent e) {
Object itemChanged = e.getItemSelectable();
if (itemChanged==gui.senderId) { // Looking for a SPECIFIC JComboBox here.
// Do stuff for this specific JComboBox here
} else if(THE EVENT WAS CAUSED BY ANY JCheckBox) {
// Do stuff for any JCheckBox
}
}
Withdraw the question. Found instanceof

JList - selecting option

how do i go do this, based on input in textfield, you get some results inside jlist, after you select option in jlist you then get an action, code examples would be appreciated... this is what i got so far:
final DefaultListModel<String> locations = new DefaultListModel<String>();
getTextFieldSearch().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for(int i=0;i<10;++i) {
locations.add(i, "blah");
}
}
});
JList<String> list_racentRaces = new JList<String>(locations);
Start by taking a look at How to Use Lists, which has lots of awesome code examples.
The basic idea would be to...
When your actionPerformed method is triggered, create a new DefaultListModel, assuming you don't have your own implementation, fill it with all the new items you need and apply it to the instance of list_racentRaces
If you want to maintain what was previously in the list, you should consider starting with a DefaultListModel and simply add the new items to it as you need to...
Then, attach a ListSelectionListener to list_racentRaces and when the valueChanged event is triggered, find the selected item(s) and do what ever you need to based on these result(s)
You can find more details and examples through How to Write a List Selection Listener

How to Check(Marked as checked) buttons in a program(or a checkbox) from just one Button?

Here is my question.Lets say that somebody made a checkbox in java and he is using it in a GUI interface so that the user can select a variety of options.Then the programmer wants to create a button inside the checkbox so that when the user checks that button all the other options will be checked as well.And when he unchecks that button of course all the other buttons will be unchecked.How is that possible in java?
Example :
o1 = new JCheckBox("Option 1");
o2 = new JCheckBox("Option 2");
o3 = new JCheckBox("Option 3");
All = new JCheckBox("All");
.....
CheckBoxHandler listener = new CheckBoxHandler();
All.addItemListener(listener);
......
Lets assume that the following code is on a class that was created as it implements ItemListener
public class CheckBoxHandler implements ItemListener
{
public void itemStateChanged(ItemEvent e)
{
if (e.getSource()==All)
if (e.getStateChange()==ItemEvent.SELECTED)
{
.... <------ (!!!)Here inside I am currently stack and I do not know how to
add the correct code in order to have all the other buttons checked.
}
}
}
Any help provided is really appreciated :)
Make use of the concept of array.
JCheckBox[] checkboxes = new JCheckBox[10];
When you need to apply some operation to all checkboxes, iterate over the array:
for( JCheckbox cb : checkboxes )
cb.doStuff();
You can call setSelected() on the JCheckbox (inherited from AbstractButton):
...
o1.setSelected(true); // or false
...
As #Juvanis mentions, instead of having three different references for o1, o2 and o3, you should use an array. Then, you can do something like
for( JCheckbox cb : checkboxes ) {
cb.setSelected(true);
}
to set all checkboxes in the array as checked.
CheckBoxes can have ActionListeners. Why not add an ActionListener to all the checkboxes that then checks if the one selected is checked or not and calls setSelected(true) or setSelected(false) on each one?
If you have a known small number of checkboxes (such as the 3 you talked about), you may just want to hard code it. However, if you need to make it modular or have a large number of check boxes, you can always store them in a data structure (as Juvanis said, an array would probably work nicely) and loop it

Which radio button is selected in a button group

What can I do to get which radiobutton is selected on a buttongroup without doing this:
if (jRadioButton1.isSelected()) {
//...
}
if (jRadioButton2.isSelected()) {
//...
}
if (jRadioButton3.isSelected()) {
//...
}
if (jRadioButton4.isSelected()) {
//...
}
You can get the ButtonModel for the selected button via the getSelection() method of ButtonGroup. I don't know how you can avoid conditionally branching on the selected button though, unless you have some sort of ancillary data structure mapping from ButtonModel to actions to perform, for instance. If you had that, then you could just fire the action based on the returned ButtonModel.
Darryl's Select Button Group has a getSelectedButton() method.
I know the question was posted long back. Anyway, we can use the setActioncommand function. while creating the radio button, setActionCommand could be invoked to set the action command value, which could be used to refer to the radio button that was selected.
jRadioButton1.setActionCommand("jRadioButton1");
jRadioButton2.setActionCommand("jRadioButton2")
.
.
String button_name = ((JToggleButton.ToggleButtonModel)button_group.getSelection()).getActionCommand();
ButtonGroup class does not provide a method to identify the currently selected button (inherited from AbstractButton) in the group if that is your intention. It only has clearSelection() method to clear the selected state of all buttons in the group (with exception for JButton and JMenuItem which don't have select/deselect button state).
One solution I can think of is to use a special variable or field (AbstractButton, JRadioButton or JRadioButtonMenuItem if it is in a menu item) to identify which one is currently selected by updating it inside each AbstractButton's action listener method (make sure to validate user clicks since it can be triggered more than once!). Use the variable (by typecasting it - for AbstractButton only) in other method(s).
Other than that, nope...you will need to do conditional branching.
For dealing with a button group bg, you can get the buttons by calling the button group's getElements() method, and using that as the parameter for the Collections.list() method, just save the result in an arraylist. From there it is relatively simple to retrieve the correct button.
ArrayList<AbstractButton> arl = Collections.list(bg.getElements());
for (AbstractButton ab : arl) {
JRadioButton jrb = (JRadioButton) ab;
if (jrb.isSelected()) {
return jrb;
}
}

set focus for all fields

I noticed I can use getName() as part of the trick.
What is java.awt.Component.getName() and setName() used for?
But I don't really have a clue where to start. What type of listener should I use (assuming the textfield / or box is currently blinking / selected)
This is my previous question, and thank you for the help guys.
How do I use requestFocus in a Java JFrame GUI?
I realize that for each component (Textfield) that I am creating, I have to insert a statement like requestFocus (or using transferFocus).
Is it possible to apply this policy to all the fields???
I have several textfields and ComboBox. The problem I hit is that I don't want to write methods for every single field / box.
For example, I write a method like this
private JTextField getFirstNameEntry() {
.... do something
}
because my instructor writes his program like this
private JPanel getJContentPane() {
jContentPane = new JPanel();
jContentPane.setLayout(new java.awt.FlowLayout(FlowLayout.LEADING));
jContentPane.add(makeLabel(" First Name *", 100, 20));
jContentPane.add(getFirstNameEntry(), null);
jContentPane.add(makeLabel(" Middle Initial", 100, 20));
jContentPane.add(getMiddleInitialEntry(), null);
// etc
return jContentPane;
However, to save redundancy (that was my motive at first), say I have a box, I can simply add the following code inside the method above: getJContentPane()
titleBox = new JComboBox(new String[]{"Mr.","Mrs.","Ms.","Dr.","Prof.","Rev."});
jContentPane.add(titleBox);
But doing this, I still need to create a method to do addItemListener
private void setComboBoxFocus() {
titleBox.addItemListener(
new ItemListener(){
public void itemStateChanged(ItemEvent e){
if(e.getStateChange() == ItemEvent.SELECTED)
{
String titleSelected = titleBox.getSelectedItem().toString();
System.out.println(titleSelected);
titleBox.transferFocus();
}
}
});
}
However, this doesn't really save redundancy at all. If I have more than one ComboBox to be added, I would have to write another similar method. In fact, even in the case with one ComboBox (titleBox), I would still end up with writing a method for titleBox.
So my question is: is there a way to write a general method that can call focus to all (maybe one for ComboBox type)?
Thank you and sorry for the long post.
Why not take a JComboBox argument to your setComboBoxFocus() method, which allows you to set that listener to any JComboBox you may have? Like so:
private void setComboBoxFocus(JComboBox box) {
box.addItemListener(
new ItemListener(){
public void itemStateChanged(ItemEvent e){
if(e.getStateChange() == ItemEvent.SELECTED)
{
String titleSelected = box.getSelectedItem().toString();
System.out.println(titleSelected);
box.transferFocus();
}
}
});
}

Categories

Resources