Results 1 to 17 of 17
Like Tree2Likes
  • 1 Post By Norm
  • 1 Post By jashburn

Thread: How do I call Action listener automatically and without someone doing it manually?

  1. #1
    WORKPETER is offline Member
    Join Date
    May 2014
    Posts
    9
    Rep Power
    0

    Default How do I call Action listener automatically and without someone doing it manually?

    Heya,

    My aim
    I'm not a java developer, i'm a tester. I am currently testing a java swing application and to do that I have to automate how its used. IE I have to write code which will press buttons for me rather than depending on an end user to do this. I have managed to reverse engineer the entire application (hooray for me), however I am struggling to work out how to invoke methods that would typically be kicked off by a user pressing a button.

    Question
    Please look at the code below. Please can you tell me how to I can call actionPerformed(ActionEvent ae) method which sits in the ATMMainPanel class?
    I will be calling it from inside another method which is the equivalent of the main() method. Please note, I am not a java developer, so I would be really appreciative if someone could write out the line of code so i can copy and paste it in my script.



    Java Code:
    public class ATMMainPanel extends JPanel implements ActionListener {
    [declarations here]
    
     
      //here  - User is pressing the Enter button after putting in pin.
      public void actionPerformed(ActionEvent ae) {
      	
        [code performed when button is pressed]  
    
    
      }

  2. #2
    gimbal2 is offline Just a guy
    Join Date
    Jun 2013
    Location
    Netherlands
    Posts
    4,014
    Rep Power
    6

    Default Re: How do I call Action listener automatically and without someone doing it manually

    a) create your own ActionEvent object
    b) call the actionPerformed method

    Java does not have scripts, its a compiled program. You can't hide behind the "I'm a tester" facade, you have to learn and understand the tools you're using before you can do this job.
    "Syntactic sugar causes cancer of the semicolon." -- Alan Perlis

  3. #3
    WORKPETER is offline Member
    Join Date
    May 2014
    Posts
    9
    Rep Power
    0

    Default Re: How do I call Action listener automatically and without someone doing it manually

    Thanks for the reply. I am using a testing tool which works in a similiar way as an IDE, and so it compiles the java code on the fly. I have copied all the applications .class files into the tools interface and I have a main action() which runs when the script is run and I from that main action I can call whatever method I want. This is how I automate the testing on the various methods.
    Please understand that as a tester I work with dozens of different applications and protocols which stretch far beyond Java, so unfortuently I cannot be an expert at everything. I understand the principles behind what you are saying but I dont know the code, nor do I have the luxury of learning Java in great detail as time is money. I have being trying to work this out for myself for a day now, but my time is limited. :)

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,009
    Rep Power
    20

    Default Re: How do I call Action listener automatically and without someone doing it manually

    Can I suggest using one of the available tools for testing a Swing app?

    Doing this by hand is a little like not using Selenium (or similar) for doing web front end testing.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  5. #5
    WORKPETER is offline Member
    Join Date
    May 2014
    Posts
    9
    Rep Power
    0

    Default Re: How do I call Action listener automatically and without someone doing it manually

    Quote Originally Posted by Tolls View Post
    Can I suggest using one of the available tools for testing a Swing app?

    Doing this by hand is a little like not using Selenium (or similar) for doing web front end testing.
    Well I am doing performance testing and the tool we need to use (LoadRunner) doesn't seem to allow me to simply "record" the JDBC communication between the java swing app and the database, so I am reverse engineering it instead which is the next logical step. Its not really a big issue for me, as I have done this with more simple java apps using different protocols, but i've hit a roadblock with calling Action Events. I know the code is quite straight forward in principle, but i'd rather ask here than spend the next 3 days playing around with it lol.

    There are other tools on the market, but they have their limitations and don't meet our specific needs. Having the ability to reverse engineer and not rely on "recording" has its advantages. I like to get down an dirty lol. :)

    Either way, I dont want this topic to get overly confusing. Could someone share the code please? :)
    Last edited by WORKPETER; 05-16-2014 at 01:13 PM.

  6. #6
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,009
    Rep Power
    20

    Default Re: How do I call Action listener automatically and without someone doing it manually

    But the testing frameworks should allow you to do that.
    Take UISpec4J.
    This lets you write Unit test like things that can trigger button clicks.
    Which strikes me as the sort of thing you want to do.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  7. #7
    jashburn is offline Senior Member
    Join Date
    Feb 2014
    Posts
    219
    Rep Power
    1

    Default Re: How do I call Action listener automatically and without someone doing it manually

    Without knowing how your testing tool actually works (e.g., does it actually display the GUI, or does it run the underlying code without GUI?), I can only point you to a few options.

    An Internet search using the search term "java programmatically press button" will give you relevant results. E.g., the page at Programmatically clicking a GUI button in Java Swing - Stack Overflow mentions 3 options:
    1. Directly call AbstractButton's doClick() method. JButton (as well as JMenuItem and JToggleButton, should you need to do the same for these components in the future) extends AbstractButton, and so you can call this method to simulate clicking on the button. I believe this can help avoid needing to create specific ActionEvent objects, which otherwise you'll need to create yourself using the correct settings (e.g., source, id, command and modifier.) This also has the advantage of automatically taking care of the case where there can be more than 1 ActionListeners listening to the button, as well as help make your tests more robust. E.g., your test code would be immune to changes in the ActionEvent settings.
    2. Use a Robot to move the mouse pointer to the button and click it. This obviously will need the GUI to be displayed.
    3. Create an ActionEvent object, and call the button listener's actionPerformed() method. Code example is available in the Stack Overflow page referenced above, but note the possibility of your test breaking should the developer change details of the ActionEvent object or add/change the ActionListeners that listen to the button click.

  8. #8
    WORKPETER is offline Member
    Join Date
    May 2014
    Posts
    9
    Rep Power
    0

    Default Re: How do I call Action listener automatically and without someone doing it manually

    Quote Originally Posted by Tolls View Post
    But the testing frameworks should allow you to do that.
    Take UISpec4J.
    This lets you write Unit test like things that can trigger button clicks.
    Which strikes me as the sort of thing you want to do.
    yes i would agree with you in regards to a more simpler overall approach, however i must stress that I have been unable to record my interactions with the application. A recording in theory may produce a more simple script and invoke methods which trigger buttons etc, however for one reason or another I have been unable to get it this feature to work. Plus the supporting documentation is rather limited. The approach I am taking may seem more difficult, but it gives me more control and is something id like to master too. Besides the framework in this tool isnt really designed to interact with java swing apps on the presentation layer from what i can tell, whereby you can just write a line of code to press a button. The recording feature is likely to record the client-server communication and ignore how its invoked.

    Quote Originally Posted by jashburn View Post
    Without knowing how your testing tool actually works (e.g., does it actually display the GUI, or does it run the underlying code without GUI?), I can only point you to a few options.

    An Internet search using the search term "java programmatically press button" will give you relevant results. E.g., the page at Programmatically clicking a GUI button in Java Swing - Stack Overflow mentions 3 options:
    1. Directly call AbstractButton's doClick() method. JButton (as well as JMenuItem and JToggleButton, should you need to do the same for these components in the future) extends AbstractButton, and so you can call this method to simulate clicking on the button. I believe this can help avoid needing to create specific ActionEvent objects, which otherwise you'll need to create yourself using the correct settings (e.g., source, id, command and modifier.) This also has the advantage of automatically taking care of the case where there can be more than 1 ActionListeners listening to the button, as well as help make your tests more robust. E.g., your test code would be immune to changes in the ActionEvent settings.
    2. Use a Robot to move the mouse pointer to the button and click it. This obviously will need the GUI to be displayed.
    3. Create an ActionEvent object, and call the button listener's actionPerformed() method. Code example is available in the Stack Overflow page referenced above, but note the possibility of your test breaking should the developer change details of the ActionEvent object or add/change the ActionListeners that listen to the button click.

    Ok let me spend a few minutes playing with ideas 1 and 3. Because my tool compiles and run all the original code, a GUI is shown and i should be able to interact with the objects.

    EDIT:

    Ah yes I did see that stackoverflow page you mentioned, however embarrassingly I couldnt quite figure out how to convert the example into my needs. ><
    Last edited by WORKPETER; 05-16-2014 at 02:53 PM.

  9. #9
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,009
    Rep Power
    20

    Default Re: How do I call Action listener automatically and without someone doing it manually

    Quote Originally Posted by WORKPETER View Post
    yes i would agree with you in regards to a more simpler overall approach, however i must stress that I have been unable to record my interactions with the application. A recording in theory may produce a more simple script and invoke methods which trigger buttons etc, however for one reason or another I have been unable to get it this feature to work. Plus the supporting documentation is rather limited. The approach I am taking may seem more difficult, but it gives me more control and is something id like to master too. Besides the framework in this tool isnt really designed to interact with java swing apps on the presentation layer from what i can tell, whereby you can just write a line of code to press a button. The recording feature is likely to record the client-server communication and ignore how its invoked.
    I'm simply reacting to your original post:
    "I am currently testing a java swing application and to do that I have to automate how its used. IE I have to write code which will press buttons for me rather than depending on an end user to do this."

    Nothing about recording.
    And that's what the framework I linked to does. It allows you to write test cases representing pressing a button, or sequence of buttons.

    This particular framework may not be precisely what you need, but there's a dozen out there (if you have the budget).

    As I said before, it's a bit like not using Selenium because...well...because.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  10. #10
    WORKPETER is offline Member
    Join Date
    May 2014
    Posts
    9
    Rep Power
    0

    Default Re: How do I call Action listener automatically and without someone doing it manually

    Well hmm I had a think about the suggestions offered an couldn't quite work out how to apply it to my example, however I have a slightly different approach!!
    Let me know what you think. (btw my interpretation of the code might be slightly wrong as i am not a developer)

    Looking at the code below it seems to be using the ActionEvent as a means to determine the text of the object the user has interacted with, then it uses this information to decide which conditional statement to execute. other than that, the ActionEvent object "ae" is no longer referenced.
    I am thinking I can modify this method to instead take a string as a parameter rather than an action event. Then I can simply call the method, and pass a string parameter to it such as "Enter" which is the text of the button. The method would then read the string "Enter" and invoke the conditional statement I want it to.
    I think the advantage of this is I can explicitly chose which part of the method I want to invoke for when i want to press different buttons.
    Ofcourse ill have to change how String btntext acquires its value.


    Java Code:
    public void actionPerformed(ActionEvent ae) {
      	
      
        String btntext = ((JButton) ae.getSource()).getText();
        switch(display.getState()) {
          case Display.PIN: {
            String text = display.getPINInputLabel().getText();
            if (btntext.equals("Enter")) {
              try {
                customer = new Customer(connection, Integer.parseInt(text.trim())); //ref1 
                display.setCustomer(customer);
                display.setState(Display.ACCOUNTS);
              }
              catch (Exception e) {
                e.printStackTrace();
                text = "Bad PIN";
              }
            }
       //more else if statements here based on the text in the button

  11. #11
    WORKPETER is offline Member
    Join Date
    May 2014
    Posts
    9
    Rep Power
    0

    Default Re: How do I call Action listener automatically and without someone doing it manually

    OK solved :)

    Basically what I did was create a new method called pressButton and then stripped all the code out of the ActionPerformed function and put it into the pressButton method. (I had to keep a ActionPerformed method within the class otherwise i would get a compile error)

    the difference between pressButton and ActionPerformed is that pressButton accepts a string as a parameter rather than an Action Event. I could then pass string values to the method when calling it to invoke the conditional statments within the method I want. The ActionPerformed method was written in a way that it determined which button was pressed by reading its string display value.

    New Code
    Java Code:
      //here  - User pressing buttons
      public void pressButton(String btntext) {
      
      //String btntext = ((JButton) ae.getSource()).getText();
        switch(display.getState()) {
          case Display.PIN: {
            String text = display.getPINInputLabel().getText();
            if (btntext.equals("Enter")) {
              try {
                customer = new Customer(connection, 1234);
            	//customer = new Customer(connection, Integer.parseInt(text.trim())); //ref1
                display.setCustomer(customer);
                display.setState(Display.ACCOUNTS);
              }
    How I am calling it
    Java Code:
        	
    ATMMainPanel autoUser =new ATMMainPanel("jdbc:odbc:ATMCustomers");
    autoUser.pressButton("Enter");

  12. #12
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,409
    Rep Power
    25

    Default Re: How do I call Action listener automatically and without someone doing it manually

    modify this method to instead take a string as a parameter rather than an action event
    That would remove the existing method as an ActionListener which would give a compiler error.
    If you want to pass a String so the given method gets it as text from a JButton, create a new JButton with the desired text and use it to build the ActionEvent object. Then the above code will work without mods.
    WORKPETER likes this.
    If you don't understand my response, don't ignore it, ask a question.

  13. #13
    WORKPETER is offline Member
    Join Date
    May 2014
    Posts
    9
    Rep Power
    0

    Default Re: How do I call Action listener automatically and without someone doing it manually

    Quote Originally Posted by Norm View Post
    That would remove the existing method as an ActionListener which would give a compiler error.
    If you want to pass a String so the given method gets it as text from a JButton, create a new JButton with the desired text and use it to build the ActionEvent object. Then the above code will work without mods.
    Yeah that does sound like a more elegant solution. just need to figure out the code to do it. I essentially want to create a basic how-to guide after this project with some elegant solution that require leaving the original code alone. If i start suggesting to modify the original methods people will shy away from it.
    Last edited by WORKPETER; 05-16-2014 at 05:04 PM.

  14. #14
    jashburn is offline Senior Member
    Join Date
    Feb 2014
    Posts
    219
    Rep Power
    1

    Default Re: How do I call Action listener automatically and without someone doing it manually

    I agree with Norm. I don't see why you need to go through the trouble of modifying the actionPerformed() method. See example below.
    Java Code:
    import java.awt.event.ActionEvent;
    
    import javax.swing.JButton;
    
    public class TestButton {
    
    	void testEnter() {
    		JButton enterButton = new JButton("Enter");
    		// ActionEvent's id and command not used, so set to 0 and "".
    		ActionEvent enterEvent = new ActionEvent(enterButton, 0, "");
    		actionPerformed(enterEvent);
    	}
    
    	public void actionPerformed(ActionEvent ae) {
    		String btntext = ((JButton) ae.getSource()).getText();
    		if (btntext.equals("Enter")) {
    			System.out.println("Enter pressed");
    		}
    	}
    
    	public static void main(String[] args) {
    		TestButton test = new TestButton();
    		test.testEnter();
    	}
    }
    Quote Originally Posted by WORKPETER View Post
    Basically what I did was create a new method called pressButton and then stripped all the code out of the ActionPerformed function and put it into the pressButton method.
    Is the actionPerformed() method part of your own test code, or is it part of the GUI code (that you're supposed to test)? If the latter, how is it possible that you're free to modify it?

  15. #15
    WORKPETER is offline Member
    Join Date
    May 2014
    Posts
    9
    Rep Power
    0

    Default Re: How do I call Action listener automatically and without someone doing it manually

    Ah nice. Let me get my head around your example and see if i can get working :)

    I am able to modify it, because i've duplicated all the application code and put it into my test tool. I can then change little things around like method names etc, but I am not gonna continue with this approach. The ideal solution would be for me to leave all the methods alone and then just create code that invokes the methods im testing. I am replicating end user actions here and trying to keep the original code intact.

  16. #16
    jashburn is offline Senior Member
    Join Date
    Feb 2014
    Posts
    219
    Rep Power
    1

    Default Re: How do I call Action listener automatically and without someone doing it manually

    I am able to modify it, because i've duplicated all the application code and put it into my test tool. I can then change little things around like method names etc, but I am not gonna continue with this approach. The ideal solution would be for me to leave all the methods alone and then just create code that invokes the methods im testing. I am replicating end user actions here and trying to keep the original code intact.
    Yes, do not continue with this approach. It is not sustainable as you'd need to rewrite all your tests every time there is code change in the application. Functional test automation is great for regression testing but very expensive to maintain, and so you'd want to make it as robust as possible.

    Here's another example, this time of option #1 mentioned in my previous post:
    Java Code:
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    
    public class TestButtonReal {
    
    	private DummyApplication app;
    
    	public TestButtonReal() {
    		app = new DummyApplication();
    	}
    
    	void testEnter() {
    		app.getEnterButton().doClick();
    	}
    
    	public static void main(String[] args) {
    		TestButtonReal test = new TestButtonReal();
    		test.testEnter();
    	}
    }
    
    // Example class representing the GUI to be tested.
    class DummyApplication implements ActionListener {
    
    	private JButton enterButton;
    
    	DummyApplication() {
    		enterButton = new JButton("Enter");
    		enterButton.addActionListener(this);
    	}
    
    	// Getter method to represent some way the Test application has visibility of the button.
    	JButton getEnterButton() {
    		return enterButton;
    	}
    
    	@Override
    	public void actionPerformed(ActionEvent ae) {
    		String btntext = ((JButton) ae.getSource()).getText();
    		if (btntext.equals("Enter")) {
    			System.out.println("Enter pressed");
    		}
    	}
    }
    See now how much simpler TestButtonReal is compared to TestButton in my last post, and that there is no need to create JButton and ActionEvent objects in TestButtonReal. This way the developer is free to to change the button's text, and TestRealButton would still work without modification.

    To digress slightly, it is not a good idea to write code that depends on a GUI component's display text, e.g., a JButton's text. The developer who wrote the GUI code will regret it when the day comes to internationalise the application so that it supports multiple languages. An action command should be used instead.
    WORKPETER likes this.

  17. #17
    WORKPETER is offline Member
    Join Date
    May 2014
    Posts
    9
    Rep Power
    0

    Default Re: How do I call Action listener automatically and without someone doing it manually

    Many thanks for these examples. I have implemented successfully :).

    Thank you all.

Similar Threads

  1. Need help with an action listener please
    By ndsmith20 in forum New To Java
    Replies: 3
    Last Post: 03-15-2013, 12:02 AM
  2. action listener
    By skuskusas in forum New To Java
    Replies: 4
    Last Post: 09-04-2012, 07:13 PM
  3. Replies: 2
    Last Post: 12-11-2011, 10:44 PM
  4. Action Listener
    By greatmajestics in forum AWT / Swing
    Replies: 8
    Last Post: 03-25-2010, 05:39 PM
  5. Call a Method Automatically
    By rhm54 in forum New To Java
    Replies: 4
    Last Post: 02-07-2008, 08:51 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •