Facing problems with actionPerformed - java

The "username" will not be printed when the button (action) is triggered the first time. When the button is pressed the second time, the value is printed out once. On third click the value is printed out twice.. Can someone point out my mistake?
*This is my first question, do give hints on posting better questions :D
Here's the main method:
public class DMS implements ActionListener{
private static String username;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
LoginFrame login = new LoginFrame();
login.setVisible(true);
}
public DMS(JTextField textField1) {
DMS.username = textField1.getText();
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(username);
}
}
And here's the action listener, which is in a jframe:
private void cmd_loginActionPerformed(java.awt.event.ActionEvent evt) {
ActionListener actionListener = new DMS(JTextField1);
someButton.addActionListener(actionListener);
}

When the control is transferred to your action listener, you are trying to print the username that you got during the initialization - which is empty.
What you need to do is:
Keep a reference of the JTextField in your DMS class
On actionPerformed(), get the data from the component.
This will ensure that you are always fetching the latest information.
Hope that helps.

Try removing this statement from cmd_loginActionPerformed so that its not being invoked every time an ActionEvent occurs
someButton.addActionListener(actionListener);

Since you have not shown the complete code, it cannot be seen when cmd_loginActionPerformed is called, but from the described behavior, it seems you are adding an action listener every time an action happens. You need to attach an action listener only once (this will fix your incremental printing), and that has to be done before any user action occurs, i.e. do it in initialization (this will fix the non-print issue on first action).

username will assigned once at the time of DMS object creation.
public DMS(JTextField textField1) {
DMS.username = textField1.getText();
}
To get the last value from the form we need to call getText(); from the actionPerformed(ActionEvent e) method
public void actionPerformed(ActionEvent e) {
DMS.username = textField1.getText();
System.out.println(username);
}

Related

Java: How to wait for the listener to execute the next line?

I have a problem because I have the next code in my main class:
SelectCalculatorWindow selectCalculatorWindow = new SelectCalculatorWindow();
CalcWindow calcWindow;
if (selectCalculatorWindow.getOption() == SelectCalculatorWindow.BASIC_OPTION) {
calcWindow = new CalcWindow(0);
} else if (selectCalculatorWindow.getOption() == SelectCalculatorWindow.PSEUDOSCIENTIFIC_OPTION) {
calcWindow = new CalcWindow(1);
}
And, in other class (SelectCalculatorWindow), I have this:
public SelectCalculatorWindow() {
initComponents();
instantiateListener();
}
private void instantiateListener() {
acceptBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(basicCalculatorRbtn.isSelected()) {
setOption(BASIC_OPTION);
} else if (pseudoscientificCalculatorRbtn.isSelected()) {
setOption(PSEUDOSCIENTIFIC_OPTION);
}
setVisible(false);
}
});
}
So, I want that condition sentences that I wrote in the main class execute only if user click the button, and I don't know how to do it
You haven't posted a valid minimal reproducible example program yet, and so I can only guess, but having said that, my guess is that SelectCalculatorWindow creates and displays a JFrame which is a non-modal application window, which is not what you want. Instead you will want to display a modal child-window, or dialog, such as a modal JDialog. When you use this, it pauses application code flow in the calling code until the dialog has been dealt with, and so allows your program to pause waiting for the user to make their selection, and then resume the code once the selection has been made.
A JOptionPane is an example of a type of modal dialog, but using a JDialog, you can create windows as varied and flexible as a JFrame, but with the advantages noted above.

Can't get ItemListener to work for JCheckBox

I am using this code to create a JCheckBox
private final JCheckBox cbDisplayMessage = new JCheckBox("Display");
cbDisplayMessage.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if(e.getItemSelectable() == cbDisplayMessage) {
if(cbDisplayMessage.isSelected()) {
cbDisplayMessage.setSelected(false);
} else {
cbDisplayMessage.setSelected(true);
}
}
}
});
When I run this it causes an StackOverflow error on setSelected(true). Can't figure out what I am doing wrong. Any ideas appreciated....
You can try with ActionListener instead of ItemListener as shown below without causing StackOverflow error.
cbDisplayMessage.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (cbDisplayMessage.isSelected()) {
cbDisplayMessage.setSelected(false);
} else {
cbDisplayMessage.setSelected(true);
}
}
});
There is no need to check the source of the event again because you are sure that you have added this listener on the same object. This is required only if same listener is added for more components.
-- EDIT--
Now Your requirement is clear to me. If you want to toggle the state of the check box then there is no need to do it using listener because that's the default behavior of the check box.
Your listener is called every time the state changes, but you trigger a new state change from within that listener, so each state change results in that listener being called over and over again until your stack is full. Your setup has to be a bit more complicated to do something like that - if you want to change the state of the component you're listening to, you'll want to remove its listener(s), fire your programmatic state change, then re-add them.

Edit an int in actionevent

Essentially what I'm trying to do is have an int edited when an action event is performed in Java. I've been trying to figure this out for days D:. I've tried to use arrays to do it, but wasn't successful also.
The problem is that the edit int isn't necessarily edited for the whole main method because it's being edit in a separate method. What I'm trying to do is basically be able to tell if the action performed was actually performed.
If you could tell me a different way to be able to tell if an action has been performed that's better than editing an int than by all means please tell me.
oButton9.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
xButton9.setVisible(false);
oButton9.setVisible(false);
nine.repaint();
nine.add(olabel);
int x =1;
}
} );
if (x == 1) {
blah blah blah
}
You need to consider the scope of the variable. Your "x" must be an instance variable, then you will be able to use it as you want.
What you are doing now, is changing the value of the local variable i, you have to declare instance variable in your class and change its value, because only then you will be able to use it in other methods.
You have to note that after running oButton9.addActionListener(...), the if statement will run immediately, so even if you can somehow set the x from the actionPerformed, it would not be useful, because the program flow won't stop at addActionListener until the actionPerformed is called.
If you're trying to do something when the button is clicked, why just not put it in the actionPerformed function?
By the way, you can define the x variable as a field in your class, and then:
class Test {
...
public int x = 0;
public void doSomething() {
...
oButton9.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Test.this.x = 1;
}
});
...
}
public static void main(String[] args) {
new Test().doSomething();
}
}

How do I update a JComboBox's list from a Document Listener?

I'm writing a custom JComboBox and whenever the user types something I want to update the drop down menu of my JComboBox. The issue I'm having is that once my DocumentListener sees an update I get an error when I try to add an item to the list.
Here's a basic example of what isn't working:
public class InputField extends JComboBox<String> implements DocumentListener{
//when something is typed, gets suggestions and adds them to the popup
#Override
public void insertUpdate(DocumentEvent ev) {
try{
giveSuggestions(ev);
}
catch(StringIndexOutOfBoundsException e){
}
}
private void giveSuggestions(DocumentEvent ev){
this.addItem("ok");
}
This isn't actually how my program will work (I'm not just going to add OK each time someone types something), but getting this to work would allow me to implement my custom JComboBox the way it needs to work. Thanks in advance for any help.
EDIT: The error message I get is:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to mutate in notification
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
this.addItem("ok");
// I can never remember the correct way to invoke a class method
// from witin and anonymous inner class
//InputField.addItem("ok");
}
});
maybe this is what you are looking for
jComboBox2.getEditor().getEditorComponent().addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
//add your handling code here:
} });

Trigger a button when exactly 13 characters in text field

I have a text field and a Search button. If the user enters precisely 13 digits (a barcode) then I want to trigger the Search automatically.
I have a DocumentListener on the text field and am processing the insertUpdate method to determine that 13 digits have been entered. I could call the search code directly at that point (and it does work) but although the 13th character has been typed, it isn't actually displayed on the screen until the search has completed.
I would prefer instead to trigger the Search button and have tried two ways:
DocumentListener dlBarcode = new DocumentAdaptor() {
public void insertUpdate(DocumentEvent e) {
String value = jtBarcode.getText();
if (isBarcode(value)) {
ActionEvent ae = new ActionEvent((Object)jbSearch,
ActionEvent.ACTION_PERFORMED, "");
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ae);
}
}
};
The second is to use:
jbSearch.dispatch(ae);
Neither method appears to cause the ActionListener on jbSearch to be triggered. Can you please suggest what I am doing wrong?
Don't try programatically "click" the button. It's not being pressed, so why try to fool your code into thinking it is? Separating an action from the gesture that performed the action is an important principle to follow. By analogy, think of the ignition on your car. Turning the key triggers the ignition. So if I wanted to design a remote car starter, would I create a mechanical robot that physically inserts and turns a key, or should my system simply signal the ignition directly?
Simply define a method, call it performSearch or whatever, and have both your ActionListener on the button and your DocumentListener each call that method on their own.
One note: don't forget to actually register your document listener with the text control you're using.
I could call the search code directly at that point (and it does work) but although the 13th character has been typed, it isn't actually displayed on the screen until the search has completed.
Wrap the call to the search code in a SwingUtilities.invokeLater(). This will place the search at the end of the Event Dispatch Thread, so the text field will be updated before the search is started.
DocumentListener dlBarcode = new DocumentAdaptor() {
public void insertUpdate(DocumentEvent e) {
String value = jtBarcode.getText();
if (isBarcode(value)) {
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
invokeSearchMethod();
}
});
}
}
};
camickr's suggestion of using invokeLater strangely didn't work as the 13th character didn't get painted until the search had finished. Mark's comment suggesting using a SwingWorker did the trick. My DocumentListener code now looks like:
DocumentListener dlBarcode = new DocumentAdaptor() {
public void insertUpdate(DocumentEvent e) {
String value = jtBarcode.getText();
if (isBarcode(value)) {
PerformSearch ps = new PerformSearch(value);
ps.execute();
}
}
And my PerformSearch looks like:
class PerformSearch extends SwingWorker<Product, Void> {
private String key = null;
public PerformSearch(String key) {
this.key = key;
}
#Override
protected Product doInBackground() throws Exception {
return soap.findProduct(this.key);
}
protected void done() {
Product p = null;
try {
p = get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
prod = p;
if (prod != null) {
... populate text fields
}
else {
... not found dialog
}
}
Thanks for the help. Much appreciated.

Categories