Results 1 to 9 of 9
  1. #1
    playwin2 is offline Member
    Join Date
    Aug 2008
    Posts
    58
    Rep Power
    0

    Default [SOLVED] ActionEvent.setSource() is failing in Swing while working in AWT

    hello,

    I have a class which works under AWT but fails under swing.
    The part fails under swing uses ActionEvent.setSource(..)....

    For ex. following code works...

    Java Code:
    public class Pad extends Panel implements ActionListener
    {
    	private Button ok = new Button("OK");
    	
    	public Pad()
    	{
    		setName("MyPad");
    		
    		setLayout(new FlowLayout());
    		add(ok);
    		
    		ok.addActionListener(this);
    	}
    	
    	public void addActionListener(ActionListener listnr)
    	{
    		ok.addActionListener(listnr);
    	}
    	
    	public void actionPerformed(ActionEvent e)
    	{
    		e.setSource(this);
    	}
    }
    Now the same code fails if I make it swing...
    Java Code:
    public class JPad extends JPanel implements ActionListener
    {
    	private JButton ok = new JButton("OK");
    	
    	public JPad()
    	{
    		setName("MyJPad");
    		
    		setLayout(new FlowLayout());
    		add(ok);
    		
    		ok.addActionListener(this);
    	}
    	
    	public void addActionListener(ActionListener listnr)
    	{
    		ok.addActionListener(listnr);
    	}
    	
    	public void actionPerformed(ActionEvent e)
    	{// [COLOR="Red"]Here is the problem I think[/COLOR]
    		e.setSource(this);
    	}
    }
    Bellow is a test code to clarify the problem...
    Java Code:
    public class JPUser extends JFrame implements ActionListener
    {
    	private JButton ok = new JButton("OK");
    	
    	private JPad swPad = new JPad();
    	private Pad awtPad = new Pad();
    	
    	public JPUser()
    	{
    		super("Test");
    		
    		setLayout(new FlowLayout());
    		add(ok);
    		add(swPad);
    		add(awtPad);
    		
    		ok.addActionListener(this);
    		swPad.addActionListener(this);
    		awtPad.addActionListener(this);
    		
    		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    		
    		pack();
    		setVisible(true);
    	}
    	
    	public void actionPerformed(ActionEvent e)
    	{
    		//System.out.println(e.getSource());
    		if(e.getSource() == swPad)
    			System.out.println("Swing Pad -- OK"); //[COLOR="Red"] I never see this line[/COLOR]
    		else if(e.getSource() == awtPad)
    			System.out.println("AWT Pad -- OK");
    		else
    			System.out.println("OK");
    	}
    	
    	public static void main(String args[])
    	{
    		EventQueue.invokeLater(new Runnable()
    		{
    			public void run()
    			{
    				new JPUser();
    			}
    		});
    	}
    }
    Please can anyone help...

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

    Default

    fails under swing
    Please post the full text of the error message.
    public void actionPerformed(ActionEvent e)
    {// Here is the problem I think
    e.setSource(this);
    }
    Why are you using set.. here? Normally you do a get... to be able to respond to the action.

    //System.out.println(e.getSource());
    Uncomment the above and What does it show you?

  3. #3
    playwin2 is offline Member
    Join Date
    Aug 2008
    Posts
    58
    Rep Power
    0

    Default

    Quote Originally Posted by Norm View Post
    Please post the full text of the error message.
    Oh! no no there are no error msgs, compiles fine runs fine.
    The problem is "design", the code fails do it's purpose under swing.
    Quote Originally Posted by Norm View Post
    Why are you using set.. here? Normally you do a get... to be able to respond to the action.
    Yes, but I don't want to respond to any action here., the calling class (in this case JPUser) will do that.
    Quote Originally Posted by Norm View Post
    Uncomment the above and What does it show you?
    It shows :
    (1)JButton as source for swPad
    (2)MyPad as source for awtPad
    (3)JButton as source for JButton OK.

    Now, see what I mean, #2 & #3 is right but #1 is wrong.
    It still shows JButton as source for swPad, means the setSource(...) method in class JPad had failed or has no effects.

    This is the question why awtPad(AWT) works while swPad(Swing) fails?:confused:

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

    Default

    I don't want to respond to any action here
    Then why implement ActionListener?

    Have you put println() statements in ALL of the actionPerformed() methods to see what is happening?

    Put println()s in all the methods, press the buttons and then copy the output here. Your editted version of what happens doesn't help much. Make sure the println() show where in the code they are and what the values of key variables are at each point.

  5. #5
    playwin2 is offline Member
    Join Date
    Aug 2008
    Posts
    58
    Rep Power
    0

    Default

    Ah! very good suggestion ... indeed actually now (after putting println()) in all actionPerformed I see a new problem... :o

    here is the output,
    Java Code:
    Pad Class
    Before setSource()
    ==============================
    java.awt.event.ActionEvent[ACTION_PERFORMED,cmd=OK,when=1219857065999,modifiers=] on button0
    Pad Class
    After setSource()
    ==============================
    java.awt.event.ActionEvent[ACTION_PERFORMED,cmd=OK,when=1219857065999,modifiers=] on MyPad
    Class JPUser
    ==================
    java.awt.event.ActionEvent[ACTION_PERFORMED,cmd=OK,when=1219857065999,modifiers=] on MyPad
    AWT Pad -- OK
    Class JPUser
    ==================
    java.awt.event.ActionEvent[ACTION_PERFORMED,cmd=OK,when=1219857068093,modifiers=Button1] on javax.sw
    ing.JButton[,5,5,51x26,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$Compou
    ndBorderUIResource@a01335,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIc
    on=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=14,bottom=2,right=14],
    paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIco
    n=,selectedIcon=,text=OK,defaultCapable=true]
    OK
    JPad Class
    Before setSource()
    ==============================
    java.awt.event.ActionEvent[ACTION_PERFORMED,cmd=OK,when=1219857068093,modifiers=Button1] on javax.sw
    ing.JButton[,5,5,51x26,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$Compou
    ndBorderUIResource@a01335,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIc
    on=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=14,bottom=2,right=14],
    paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIco
    n=,selectedIcon=,text=OK,defaultCapable=true]
    JPad Class
    After setSource()
    ==============================
    java.awt.event.ActionEvent[ACTION_PERFORMED,cmd=OK,when=1219857068093,modifiers=Button1] on MyJPad
    As you can see setSource() do working in swingPad but it's working after... :o
    What to do here .... :(

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

    Default

    The problem is the actionlisteners are NOT called in the order you expected.
    A solution: Instead of having the Panel class's addActionListener add the listener to their button, have them save its address and handle the listening themselves. When their actionPerformed method is called, change the source of the event to this and then CALL the actionListener's actionPerformed method with the modified event.

  7. #7
    playwin2 is offline Member
    Join Date
    Aug 2008
    Posts
    58
    Rep Power
    0

    Thumbs up

    Yes, exactly, so the new JPad class :
    Java Code:
    public class JPad extends JPanel implements ActionListener
    {
    	private JButton ok = new JButton("OK");
    	private ActionListener lsnr = null;
    	
    	public JPad()
    	{
    		setName("MyJPad");
    		
    		setLayout(new FlowLayout());
    		add(ok);
    		
    		ok.addActionListener(this);
    	}
    	
    	public void addActionListener(ActionListener listnr)
    	{
    		//ok.addActionListener(listnr);
    		lsnr = listnr;
    	}
    	
    	public void actionPerformed(ActionEvent e)
    	{
    		System.out.println("JPad Class\nBefore setSource()");
    		System.out.println("==============================");
    		System.out.println(e);
    		//Modify the source
    		e.setSource(this);
    		System.out.println("JPad Class\nAfter setSource()");
    		System.out.println("==============================");
    		System.out.println(e);
    		//now pass the event to calling class..
    		if(lsnr != null)
    			lsnr.actionPerformed(e);
    	}
    }
    This solves the problem. Thank you very much. :D :D :D

    Although the problem is solved, I'm curious do you have any idea why swing ver. behave differently than the AWT ver.? Is it that another "Swing is not thread safe" kind of thing?

  8. #8
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Although the problem is solved, I'm curious do you have any idea why swing ver. behave differently than the AWT ver.? Is it that another "Swing is not thread safe" kind of thing?
    No, it has nothing to do with the thread-safety bugaboo but all due to what Norm said above. One way to implement what you want is have the JPad class broadcast its own actions. I'm not sure if this is kosher, but it's cool and works:
    Java Code:
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.ArrayList;
    import java.util.List;
    
    public class JPad extends JPanel //implements ActionListener
    {
      private JButton ok = new JButton("OK");
      private List<ActionListener> listenerList = new ArrayList<ActionListener>();
      
      public JPad()
      {
        setName("MyJPad");
        
        setLayout(new FlowLayout());
        add(ok);
        
        ok.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            ActionEvent actionEvent = new ActionEvent(JPad.this, e.getID(), e.getActionCommand());
            for (ActionListener al : listenerList)
            {
              al.actionPerformed(actionEvent);
            }
          }
        });
        //ok.addActionListener(this);
      }
      
      public void addActionListener(ActionListener listnr)
      {
        //ok.addActionListener(listnr);
        listenerList.add(listnr);
      }
      
      /*
      public void actionPerformed(ActionEvent e)
      {
        e.setSource(this);
      }
      */
    }

  9. #9
    playwin2 is offline Member
    Join Date
    Aug 2008
    Posts
    58
    Rep Power
    0

    Thumbs up

    Very nice. looks much better. [thumbs up]

    If I understood it right... then I think now multiple class can use JPad ...

    istenerList.add(listnr);

    for (ActionListener al : listenerList)
    {
    al.actionPerformed(actionEvent);
    }



    Thank a lot... appreciate it.

Similar Threads

  1. Replies: 8
    Last Post: 05-28-2008, 07:00 AM
  2. [SOLVED] Actionevent problem
    By Cymro in forum New To Java
    Replies: 3
    Last Post: 04-04-2008, 07:11 AM
  3. ActionEvent example
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 03-11-2008, 11:00 PM
  4. map javax.swing.text.Element to javax.swing.text.View
    By elizabeth in forum New To Java
    Replies: 1
    Last Post: 07-30-2007, 07:02 PM
  5. Working With ANT
    By JavaForums in forum Eclipse
    Replies: 0
    Last Post: 04-26-2007, 08:16 PM

Posting Permissions

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