How do I stop the action event of Button2 and more runs after Button1.
Button1 need to do only Button1 Action Event and stop then.
Please Help me, thank you
public void actionPerformed(ActionEvent ae) {
if (ae.getSource().equals(button1)){
System.out.println("Button 1");
}
if (ae.getSource() == button2){
System.out.println("Button 2!");
}
edit:
sorry, wrong code
in main:
Button1.addActionListener(this);
jPanel1.add(Button1);
Button2.addActionListener(this);
jPanel1.add(Button2);
not in main:
public void actionPerformed(ActionEvent ae) {
Object Button1 = null;
if (!ae.getSource().equals(Button1)){
System.out.println("Oben");
}
Object Button2 = null;
if (ae.getSource() == (Button2)){
System.out.println("Links");
}
}
if i press my Button1, i get "Oben"
if i press my Button2 i get "Oben", too
why i dont get "Links"
There are two problems in your code:
You are setting Button1 and Button2 to null
Your if-statements are layed out in such a way that more than one of them can run in a single invocation of actionPerformed
Try this:
public void actionPerformed(ActionEvent ae) {
if(ae.getSource().equals(this.Button1)) {
System.out.println("Button 1");
} else if (ae.getSource().equals(this.Button2)) {
System.out.println("Button 2");
}
}
This code assumes that Button1 and Button2 are members of the class that the actionPerformed method belongs to.
Take another look at your (edited) code.
Object Button1 = null;
if (!ae.getSource().equals(Button1)){
System.out.println("Oben");
}
So what you're saying here is the following, which is going to evaluate true in both cases.
if (ae.getSource() != null)
This is why the result is always Oben.
If you are intending to compare against a different Button1, make sure to reference the correct the object. Without seeing the rest of the code it's hard to say, but you may mean to use (this.Button1);
public void actionPerformed(ActionEvent ae) {
Object Button1 = null;
if (!ae.getSource().equals(Button1)){
System.out.println("Oben");
}
Object Button2 = null;
if (ae.getSource() == (Button2)){
System.out.println("Links");
}
}
I'm afraid the above code make's little sense, and doesn't conform to usual practice. Firstly, buttons that perform different actions should have different listeners, except in special cases. This is not one of those special cases. Split up your code into:
public void actionPerformed(ActionEvent e)
{
System.out.println("Oben");
// This is the actionPerformed method for button 1.
}
public void actionPerformed(ActionEvent e)
{
System.out.println("Links");
// This is for button 2.
}
Then simply bind to the relevant buttons.
Related
Ok, so I'm doing a Java window (a JFrame, doesn't really matter what it is for) and I have a button on it. What I want to approach is when the button is clicked, it changes its text, then the app does something, and when it's finished the button gets its initial text back.
Something like this...
JButton myButton = new JButton("Initial");
myButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
((JButton) e.getSource()).setText("New");
//Do other things
//Do more other things
((JButton) e.getSource()).setText("Initial");
}
});
That's what I've tried so far, but I know it doesn't work as expected (all the code executes. I'm not really an expert and I'm doing this things to learn, so I have no clue if there's a way to do it or not.
I've already looked for a solution to this in the web but I've not found anything (maybe I didn't search properly), so I hope there's someone who can help me with this!
PS: Sorry if my English is not perfect, I know about it. Ask me if something isn't clear about the question. Thanks to all!
Kevin.
EDIT: The app is a sudoku solver, so it takes a while //doing other things. Thats why I'm trying to change the solve button text (so it sais it is solving and when it finished it says solved).
Your logic is not wrong! Take a look at my example below:
public class MainFrame extends JFrame {
public MainFrame() {
setMinimumSize(new Dimension(200, 100));
JButton myButton = new JButton("Initial");
add(myButton);
myButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
final JButton triggerBtn = (JButton) e.getSource();
final String originalValue = triggerBtn.getText();
triggerBtn.setText("New");
JOptionPane.showMessageDialog(null, "Speak softly and carry a big stick and you will go far.");
triggerBtn.setText(originalValue);
}
});
}
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MainFrame mainFrame = new MainFrame();
mainFrame.setVisible(true);
}
});
}
}
If you run this you will see that the button is changed. If you were to change the showMessageDialog line to Thread.sleep(10*1000), you would not see a change! This is because you're running the event on the dispatcher thread and the text, even though it is changed, will not allow the change event to be triggered until your method finishes.
Consider the following alternative if the work you're doing is on the same thread:
myButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
final JButton triggerBtn = (JButton) e.getSource();
final String originalValue = triggerBtn.getText();
triggerBtn.setText("New");
SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>() {
protected Void doInBackground() throws Exception {
Thread.sleep(10*1000);
return null;
}
#Override
protected void done() {
triggerBtn.setText(originalValue);
}
};
sw.execute();
}
});
This sets the text, and launches a SwingWorker to run the job asynchronously. Once finished, the dispatcher thread will update the text without requiring the dispatcher thread to be tied up waiting for it to finish (and so events are therefore handled properly).
Let me know if that works for you!
Have you tried with:
JButton myButton = new JButton("Initial");
myButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
myButton.setText("New");
//Do other things
//Do more other things
myButton.setText("Initial");
}
});
In your example you're missing actionPerformed and you're not accessing button directly (I can't say what's e in your example)
Just save your current text in a local variable and set it back after you've performed your other actions.
You should also make sure it's really the button that you clicked or at least check instanceof JButton before casting.
final JButton myButton = new JButton("Initial");
myButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == myButton) {
String initialText = myButton.getText();
myButton.setText("New");
// Do other things
// Do more other things
myButton.setText(initialText);
}
}
});
You were also missing out on your actionPerformed method, the code in the question won't compile - I guess you just wrote it in the editor.
I had 9 hunks of form-identical code such as this:
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
btnExitActionPerformed(evt);
}
});
...with 9 corresponding linked hunks of code like this:
private void btnExitActionPerformed(ActionEvent evt) {
// some code *********************
}
... and a large number of similar repeated hunks of code
for FocusListener and MouseListener.
I tried to cut down the number of lines of code by assigning
the button's text to its action command and using this:
public void actionPerformed(ActionEvent e)
{
String c = e.getActionCommand();
switch (c) {
case "Clear output": btnClearOutputActionPerformed(e); break;
case "Search": btnSearchActionPerformed(e); break;
case "Exit": btnExitActionPerformed(e); break;
...
}
}
It works, but that's not a lot better. Still repetitive. Looking for elegant.
I can't believe the following method even compiles, but it doesn't work because doClick() calls the method recursively. I was naively hoping doClick() would execute the method btnPatternMouseClickedActionPerformed().
public void actionPerformed(ActionEvent e){
Component[] c ;
c = theFrame.getComponents();
JButton b;
for(Component x: c)
{
if(x instanceof JButton)
{
b = (JButton) x;
if(b.getText().equals(e.getActionCommand()))
{
b.doClick(); // want it to execute code elsewhere
return;
}
}
}
}
At first I thought the above method was close. Now I'm about to give up.
I have three questions:
(1) Is there a way to cut down on such repeated hunks of code as shown in the first two paragraphs?
(1a) Is the last method above close? Can it be easily fixed?
(2) Would a technique similar to the actionPerformed method above (the one that uses switch) to replace hunks of code for FocusListener and MouseListener be a waste of time to implement?
You could change this:
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
btnExitActionPerformed(evt);
}
});
...with 9 corresponding linked hunks of code like this:
private void btnExitActionPerformed(ActionEvent evt) {
// some code *********************
}
to this:
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// same code that was in the btnExitActionPerformed method.
}
});
But perhaps even better still would be to separate your "control" code, the code in the listeners, from your "view" code, your GUI, but how to do this will depend on your problem and current code base.
Edit
You ask:
I will blame Swing GUI builder for that (bad?) habit.
It's not so bad, and is certainly a lot better than having your GUI classes implement listener interfaces.
Why does Swing do that?? Why does Swing do a LOT of what it does!!
I'm not sure what specifically you meant here.
So about "even better": are you saying to separate the listeners into another class file? And are you suggesting that coconuts migr~~...
Yes, and yes. In fact the control -- the listener part could be composed of several classes, but they all might be used in a single master control class.
I mean, that I should abandon the last method in my question?
Yes.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class Example implements ActionListener{
JButton buttons[] = new JButton[12];
public Example(){
for(int c=0; c<buttons.length; c++){
buttons[c]=new JButton("I am button"+c);
buttons[c].addActionListener(this);
}
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == buttons[0]){}
if(e.getSource() == buttons[1]){}
if(e.getSource() == buttons[2]){}
if(e.getSource() == buttons[3]){}
if(e.getSource() == buttons[4]){}
if(e.getSource() == buttons[5]){}
if(e.getSource() == buttons[6]){}
if(e.getSource() == buttons[7]){}
//....
}
}
This is not enough elegant for you code?
Something other:
If for example you have buttons that are in the same Team, for example:
It's a good idea to have one class(java Object) and then take objects and make buttons.
public class TVButton implements ActionListener{
public TVButton(String name,String whatever){
}
#Override
public void actionPerformed(ActionEvent e){
//actionFor this button
}
}
As i have seen many answers are too obscure for a entry level student like me.
i am following the steps by first addActionListner(this) to my JTextField.
what i am trying to do next and confuses the most is under:
public void actionperformed(Actionevent ae){
if(ae.getSource() == "Enter pressed")
{
outArea.setText(result);
}
}
which does not work because i feel like the code ae.getSource() == "Enter presses" is not working correctly and even i replaced the action i took under actionPerformed by a simple print line command like System.out.println("working"), it won't execute.
here is what i do if a button is pressed.
public void actionperformed(Actionevent ae){
if(ae.getSource() == "JButton")
{
System.out.println("JButton was pushed");
}
}
no matter how, lets say i have a GUI with a piece of given code like these:
public static void main(string[] args){
new myProg();
}
public myProg(){
....
buildTheGUI();
...}
}
//GUI Objects
...
JTextField input = new JTextField(10);
...
//method building the GUI
public void buildTheGUI(){
...
input.addActionListner(this);
...
//a method called actionPerformed
public void actionperformed(Actionevent ae){
}
i am now trying to detect the enter key by actionListner not by any other method because it's given.
Firstly, actionPerformed is triggerd by an action event, typically on most systems, this is triggered by the Enter key (with context to the JTextField)...so you don't need to check for it.
Secondly, the source of the ActionEvent is typically the control that triggered it, that would be the JTextField in this case.
Thirdly, String comparison in Java is done via the String#equals method...
if ("Enter presses".equals(someOtherString)) {...
Your actionPerformed method for the Button is wrong, try better this:
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() instanceof JButton) {
JButton button = (JButton) e.getSource();
System.out.println("This button was pushed: " + button.getText());
}
}
And your for KeyListener try this to learn how it works:
#Override
public void keyPressed(KeyEvent e) {
System.out.println(e.getKeyChar());
System.out.println(e.getKeyCode());
}
Dont forget to let your class implement ActionListener and KeyListener.
I was working on something in which I need to call the actionlistner of a disabled jbutton from another function. How it can be done?
Make a new method which will be called by the disabled jbutton, write all the code there which will be executed when you click the button. You can not call the actionlistiner in other way.
...
JButton disButton = new JButton("Disabled");
disButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
//do not write any statement here
doSomething();
}
});
...
private void doSomething() {
//all action event execution code here
System.out.println("I am in the action listener");
}
....
//in the other method or another button click event call doSomething()
//even button is disables like
JButton Button = new JButton("Submit");
Button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
doSomething();
}
});
//or from another method
public void method() {
doSomething();
}
You cannot call/do actions on disabled GUI controls.That is what actually disable means
What you can do is create a separate common method like doClick() and call where ever you need.
I have a JButton, two action listeners are registered for it. Listener1 will be executed first because it is registered first.
So, what i need is, In a condition matches in the Listener1 then the code of Listener2 should not be executed.
Would you please help me, how to prevent execution of Listener2 if condition matches in Listener1.
JButton jbtn=new JButton();
jbtn.addActionListener(new ActionListener() {
//Listener1
public void actionPerformed(ActionEvent e)
{
if(condition==true){
//do not execute the code of listner2
//stop further executeion of current action
}
}
});
jbtn.addActionListener(new ActionListener() {
//Listener2
public void actionPerformed(ActionEvent e)
{
//some code
}
});
It looks to me as if you may be over-complicating things. Why not simply use one ActionListener or AbstractAction and nest the if block inside:
jbtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(condition) { // no need for the == true part!
myMethod1();
} else { // condition is false
myMethod2();
}
}
});
It's easy. AbstractButton has the method getActionListeners(). So you can remove any listener, added before. Then you can create your listener, which can call the another listener (which was removed from the button).
Something like this:
public class MyActionListener implements ActionListener {
private ActionListener anotherListener;
public MyActionListener(ActionListener another) {
anotherListener = another;
}
public void actionPerformed(ActionEvent ae) {
doSomething();
if (myCondition) {
anotherListener.actionPerformed(ae);
}
}
}
Depending on the exact event you are firing, sometimes you can use consume() / isConsumed(). (e.g. java.awt.event.InputEvent)
Your listeners check for isConsumed() before doing anything, and call consume().
In this way, only one listener will get the event, assuming that they all follow this convention. So if one listener is from an outside or library class this won't help. And the order of which Listener gets the event first may not be under your control.
So #Hovercraft's option may be better. Depends on how decoupled you wish to be.