Here is my ButtonListener class in my GUI. I have several buttons within it, that when clicked, I want to call a certain method for each one, for instance:
public class ButtonListener implements ActionListener{
public void actionPerformed( ActionEvent event ){
if (event.getSource( ) == buttonA)
If button A is selected, I want to call a method and have its return statement displayed.
(If I understand you correctly)
You could have
public void actionPerformed(ActionEvent e) {
if (e.getSource() == buttonA)
{
ButtonAImpl x = new ButtonAImpl();
x.myMethod();
}
if (e.getSource() == buttonB)
{
ButtonBImpl y = new ButtonBImpl();
y.myMethod();
}
}
You may want to look at some design patterns to help in this scenaro...
MVC - http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
MVP - http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter
I think it's good practise to use a switch in this case because you've said you have several buttons.
public void actionPerformed(ActionEvent e) {
switch (e.getSource())
case buttonA:
buttonACode();
break;
case buttonB:
buttonBCode();
break;
default:
someDefaultAction();
break;
}
If you would like to display the returned result you can replace buttonACode(); with System.out.println(buttonACode());
If I understand it, you should do the following (just an example):
class X{
JButton firstButton;
JButton secondButton;
public X(){
firstButton=new JButton("first");firstButton.setActionCommand("FB");
secondButton=new JButton("second");secondButton.setActionCommand("SB");
}//constructor closing
public void method1(){}
public void method2(){}
class EventHandler extends ActionListener{
public void ActionPerformed(ActionEvent e){
String action=e.getActionCommand();
if(action.equals("FB"))method1();
else if(action.equals("SB"))method2();
}//
}//inner-class closing
}//calss closing
Related
How to check from a class ModalDialog extends JDialog implements ActionListener if actionPerformed(ActionEvent e) method ocurred in another class (Connect extends JFrame implements ActionListener)? And one step further, how to check which of two buttons that I have in ModalDialog fired ActionPerformed method? (I know about event.getSource, but I need to check it from another class).
public ModalDialog()
{
btn8 = new Button("human");
btn8.setMaximumSize(new Dimension(60,40));
btn8.addActionListener(this);
btn9 = new Button("robot");
btn9.setMaximumSize(new Dimension(60,40));
btn9.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
}
class Connect extends JFrame implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
ModalDialog md = new ModalDialog();
if(md.ActionPerformed(e)....)...something like that...
}
}
How to check from a class ModalDialog extends JDialog implements ActionListener if actionPerformed(ActionEvent e)
This is a basic problem of how to return information from one class to another. The simple answer is to provide a getter method, which returns the selected value.
Start by defining the value to be returned, here I used a enum, as it clearly defines what could be returned
public enum Option {
HUMAN, ROBOT;
}
Update your ModalDialog to provide a getter to return the selected value
public class ModalDialog extends JDialog implements ActionListener {
private Option selection;
public ModalDialog() {
setModal(true);
Button btn8 = new Button("human");
btn8.addActionListener(this);
Button btn9 = new Button("robot");
btn9.addActionListener(this);
setLayout(new GridBagLayout());
add(btn8);
add(btn9);
pack();
}
public Option getSelection() {
return selection;
}
public void actionPerformed(ActionEvent e) {
//...
}
}
When the dialog is closed, the caller can now call getSelection to get the selected value (or null if the user closed the dialog via the [X] button
And one step further, how to check which of two buttons that I have in ModalDialog fired ActionPerformed method?
This is not an uncommon problem, and there a number of ways you might implement it. Since you've already implemented ActionListener at the class level, you could just make use of the actionCommand support available in buttons, which defaults to the text of the button
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
switch (cmd) {
case "human":
selection = Option.HUMAN;
break;
case "robot":
selection = Option.ROBOT;
break;
}
setVisible(false);
}
So now, when the dialog is closed, you can just request the selected value...
ModalDialog dialog = new ModalDialog();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
Option selection = dialog.getSelection();
System.out.println("You choose " + selection);
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.
So I want to remove a listener from a button after the button has been pressed 3 times.
So far I have this
class Q5
{
JFrame frame;
JButton button;
int clickCount = 0;
public static void main (String[] args)
{
Q5 example = new Q5();
example.go();
}
public void go()
{
frame = new JFrame();
button = new JButton ("Should I do it");
button.addActionListener(new ButtonPressListener());
button.addActionListener(new AngelListener());
button.addActionListener(new DevilListener());
button.addActionListener(new ConfusedListener());
frame.getContentPane().add(BorderLayout.CENTER, button);
frame.setVisible(true);
frame.setSize(400,150);
// set frame properties here
}
class ButtonPressListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
clickCount++;
}
}
class AngelListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("Don't do it, you might regret it!");
}
}
class DevilListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("Go on, do it!");
}
}
class ConfusedListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if(clickCount > 3)
{
for(ConfusedListener conf : button.getActionListeners())
{
button.removeActionListener(conf);
}
}
else
System.out.println("I don't know!");
}
}
The way I read online was do a for loop, as I tried above, however I get a type mismatch. Most of the examples I could find were about removing all of the listeners, however I only want to remove the ConfusedListener from the button. Other than the for loop above, I don't have any ideas of how to do it.
The getActionListeners() method returns all the listeners of the button. And they're not all instances of ConfusedListener. The only sure thing we know is that they're instances of ActionListener. That's why your code doesn't compile.
Now, why would you need a loop to remove a given listener? You simply need to remove the ConfusedListener that is being invoked. So you just need
public void actionPerformed(ActionEvent event)
{
if(clickCount > 3)
{
button.removeActionListener(this);
}
else
System.out.println("I don't know!");
}
You could try:
if(clickCount > 3)
{
for(ActionListener listener : button.getActionListeners())
{
if (listener instanceOf ConfusedListener) {
button.removeActionListener(conf);
}
}
}
else
System.out.println("I don't know!");
You could also save the instance of the ConfusedListener when adding it and remove it via
button.removeActionListener(confusedListenerInstance);
Just store an instance of the listener itself and use it to remove the correct listener:
final ConfusedListener confusedListener = new ConfusedListener();
button.addActionListener(confusedListener);
button.removeActionListener(confusedListener);
Of if you are removing the listener from inside a method of ConfusedListener itself just pass this:
button.removeActionListener(this);
Perhaps I am going about this the wrong way. Let me know
Using Swing and AWT, I have several buttons set up on a frame and they each have an ActionListener corresponding to their specific function I.E.
JButton foo_button = new JButton("Foo-Me");
foo_button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//Fancy schmancy code work
}
})
JButton bar_button = new JButton("Bar None");
bar_button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//Fancy schmancy code work
}
})
So each of these buttons do their own thing. However, what if I want all the buttons to do a certain thing (the same exact method for each), in my case, clear a label, before they do their own thing.
Obviously I could add whatever_label.setText("") to each actionPerformed() but that entails a lot of duplication, something I'm not so much a fan of.
Oh Java and Swing gurus come to my aid.
You can subclass your own implementation of ActionListener:
private static abstract class MyListener implements ActionListener {
#Override
final public void actionPerformed(ActionEvent evt) {
theSameTask();
uniqueTask(evt);
}
private void theSameTask() {
// the identical task
}
public abstract void uniqueTask(ActionEvent evt);
}
And then, the new listeners will look like this:
JButton bar_button = new JButton("Bar None");
bar_button.addActionListener(new MyListener() {
#Override public void uniqueTask(ActionEvent evt) {
//Fancy schmancy code work
}
});
Another possibility is to use the 'Decorater' pattern, and write an ActionListener decorator for the common behavior. Your code would then be of the form
bar_button.addActionListener(new MyActionListenerDecorator( new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//Fancy schmancy code work
} }) );
I think the best way to do this is to use Action. That way all the listeners always do the same thing.