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

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

Related

Reverting the selection of JCombox

We are trying to implement a validation on the selections made with a JCombobox. In case of the new selection failing this validation, we are trying to revert to the previous selection.
Any idea about how could this be done?
I've created an implementation of ItemListener interface. Captured the previous value by checking for the DESELECTED event and validated the current selection after SELECTED event. But I'm not sure about where do I reset to the previous value when needed.
Can I do it from the listener itself?
Would that lead to recursive calls to my listener?
Can I do it from the listener itself ?
Yes you can. For instance:
JComboBox comboBox = new JComboBox();
comboBox.addItemListener(new ItemListener() {
Object previousSelection = null;
#Override
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.DESELECTED) {
previousSelection = e.getItem();
} else if(!isValid(e.getItem())) {
JComboBox cb = (JComboBox)e.getSource();
cb.setSelectedItem(previousSelection);
}
}
});
Where isValid(Object obj) method should validate selected item.
Would that lead to recursive calls to my listener ?
Sure but the previous selected item was valid so it will be called 2 times top:
First time when user attempts to select an invalid item.
Second time when listener sets the previous item as the selected one.

How do i add a customized CellEditorListener to my JTable?

I start typing my code:
private void addMyCellEditorListener() {
class MyCellEditorListener implements CellEditorListener
{
public MyCellEditorListener() {}
public void editingCanceled(ChangeEvent e) {}
public void editingStopped(ChangeEvent e) {
if(row == 0 && column > 0)
rechargeTableWithFindedResults(graphicTable.getValueAt(row,column));
else
dataTable.setValueAt(graphicTable.getValueAt(row,column),row,column);
}
};
.... addCellEditorListener(new MyCellEditorListener());
}
I would like my graphicTable to detect data changes into its cells by giving it a customized CellEditorListener, but I really can't understand how to add it. I tried several times with a code like the following:
DefaultCellEditor editor = new DefaultCellEditor(new JTextLabel());
editor.addCellEditorListener(new MyCellEditorListener());
this.graphicTable.setCellEditor(editor);
... or:
this.graphicTable.setCellEditor(this.graphicTable.getCellEditor().addCellEditorListener(new MyCellEditorListener()));
... however these techniques give me a NullPointerException in both cases.
I have looked around through forums to get a solution, but they are just getting me more confused.
Every hint would be appreciated.
Thanks in advance.
Your approach is incorrect. You can easily detect data changes in your TableModel, specifically in setValueAt method. Once you detected the change and reacted on it, you have to call one of the fireTable.. methods to let table and all other listeners know that data changed
There no need to assign any listeners to cell editors at all.

Java swing - same handler for multiple controls

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.

Help in automatically changing value upon ItemChange in JComboBox

I have a program in which I am using 3 things, a checkbox, a combobox and a textfield. The logic works like this if checkbox is enable then combobox and textfield are enable unless not.
Then set some value in the textfield by mulitplying it with the item in combobox.
From the frame - The value of Final Price is Price * Quantity.
Now the issue when I click purchase everything went fine. But when I change the value from Jcombobox it doesn't automatically change the value in final price and remains to be 1200 as in first case. For the value to be changed I have uncheck and then check the Checkbox.
What could be the problem. I have used ItemListner for both checkbox and combobox.
#Override
public void itemStateChanged(ItemEvent e){
Object get = e.getSource();
int multiplier;
int ftotal;
if (e.getStateChange()==ItemEvent.SELECTED){
if(get==chkbox1){
qntbox1.setEnabled(true);
size1.setEnabled(true);
multiplier = Integer.parseInt(String.valueOf(qntbox1.getSelectedItem()));
ftotal = Integer.parseInt(price1.getText()) * multiplier;
fprice1.setText(String.valueOf(ftotal));}
You have to implement ActionListener for your JComboBox:
private static final String command_cbo1 = "ComboBox1";
// ...
public class YourClass implements ItemListener, ActionListener
{
// ...
public YourClass()
{
// ...
qntbox1.addActionListener(this);
qntbox1.setActionCommand(command_cbo1);
// ...
}
// ...
public void itemStateChanged(ItemEvent e)
{
// ...
}
// ...
public void actionPerformed(ActionEvent e)
{
JComboBox cb = (JComboBox) e.getSource();
String s = (String) cb.getSelectedItem();
if(e.getActionCommand().equals(command_cbo1))
{
fprice1.setText("" + (Integer.parseInt(price1.getText()) * Integer.parseInt(s)));
}
// ...
}
// ...
}
not directly to your question
1/ JCheckBox is totally useless, that will be really needed for final calculation(s)
2/ consider that JComponents for Price and Final Price would be only JFormattedTextField, then you can pretty to forgot for Parse#Whatever
3/ consider that JComponents for Quantity would be only JSpinner, but workaround for Number Instance would be litte bit complicated as for JFormattedTextField example here
4/ for nice output put everything to the JTable
5/ for JComboBox I preferred ItemListener not ActionListener, because your problems isn't with proper Listener but with parsing Numbers correct way
Ok got it working. The ActionListner made it work (JComboBox). I guess using ItemListner for too many components made parsing a little confusing, add to that I used too many clauses in the ItemListner scope. Thanks a lot everyone for helping.
#mKorbel : I'll be using your suggestion asap :) and will check JTable and said components. have to go through them since I haven't used it.
#Eng.Fouad : Thanks man for the help.
Just one issue. When I typecast getSelectedItem() to integer it gives NumberFormatException error (runtime). So I have to first change the object to String and then parseit into integer. Any clue why direct conversion is throwing error ?
Here is the working code for the project.
public void itemStateChanged(ItemEvent e){
Object get = e.getSource();
if (e.getStateChange()==ItemEvent.SELECTED){
if(get==chkbox1){
qntbox1.setEnabled(true);
size1.setEnabled(true);
fprice1.setText(String.valueOf(Integer.parseInt(price1.getText()) * Integer.parseInt(String.valueOf(qntbox1.getSelectedItem()))));
}
#Override
public void actionPerformed (ActionEvent ae)
{
Object toggel = ae.getSource();
String check;
if (toggel == qntbox1)
{
check = (String) qntbox1.getSelectedItem();
fprice1.setText(String.valueOf(Integer.parseInt(price1.getText()) * Integer.parseInt(check)));
}

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