Results 1 to 8 of 8
Like Tree1Likes
  • 1 Post By Norm

Thread: Threading GUI still doesn't work

  1. #1
    devdon is offline Member
    Join Date
    Mar 2012
    Posts
    21
    Rep Power
    0

    Default Threading GUI still doesn't work

    I have boiled this problem down to three self contained files: All you have to do is run one test (marked in the code) then comment that line out, uncomment the next line and run it again to see what works and what doesn't. In short, a polygon button will hilite when called externally from the file in which it is created, but the SAME call will not work when called from another file (method). Maybe there is some Java prohibition I don't know about, or maybe I have the threading wrong, but I need the capability that right now doesn't work in this test. Any help is greatly appreciated.
    FILE: SimpleFrame.java
    Java Code:
    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.border.EmptyBorder;
    import javax.swing.JButton;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    
    public class SimpleFrame extends JFrame {
    
    
    	private static final long serialVersionUID = 7477801276425604981L;
    	private JPanel contentPane;
    	public JPanel panel;
    	public SimpleButton sb;
    
    	/**
    	 * Launch the application.
    	 */
    	public static void main(String[] args) {
    		EventQueue.invokeLater(new Runnable() {
    			public void run() {
    				try {
    					SimpleFrame frame = new SimpleFrame();
    					frame.setVisible(true);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		});
    	}
    
    	public SimpleFrame() {
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setBounds(100, 100, 450, 300);
    		contentPane = new JPanel();
    		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    		contentPane.setLayout(new BorderLayout(0, 0));
    		setContentPane(contentPane);
    		
    		sb = new SimpleButton();
    		contentPane.add(sb, BorderLayout.CENTER);
    		
    		JButton test = new JButton("test");
    		test.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				SimpleTester st = new SimpleTester();
    				// st.runTest();  // why doesn't this test work...
    				 runTest();  // and this test does. They call the same routine.
    			}
    		});
    		contentPane.add(test, BorderLayout.SOUTH);
    	}
    
    	public void runTest(){
    		sb.hilite();
    	}
    	
    }
    FILE: SimpleButton.java
    Java Code:
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Polygon;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import javax.swing.JComponent;
    import javax.swing.SwingUtilities;
    
    public class SimpleButton extends JComponent {
    
    	private static final long serialVersionUID = 1L;
    	Polygon poly;
    	Color statusColor = Color.blue;
    	Color currentColor = Color.blue;
    	Color hiliteColor = Color.red;
    
    	public SimpleButton(){
    		int[] xs = new int[] { 0,14,14,23,23,0,0 };
    		int[] ys = new int[] { 0,0,88,88,138,138,0 };
    		int np = 6;
    		poly = new Polygon(xs, ys, np);
    		addMouseListener(new MouseAdapter() {
    
    			public void mouseEntered(MouseEvent e)
    			{
    				hilite();
    			}
    
    			public void mouseExited(MouseEvent e)
    			{
    				unhilite();
    			}
    
    		});
    		setBounds(poly.getBounds());
    	}
    
    
    
    	void hilite(){
    		if (SwingUtilities.isEventDispatchThread()) {
    			doHilite();
    		} else {
    			SwingUtilities.invokeLater(new Runnable() {
    				@Override
    				public void run() {
    					doHilite();
    				}
    			});
    		}
    	}
    
    	public void doHilite() {
    		currentColor = hiliteColor;
    		repaint();
    	}
    
    
    	void unhilite(){
    		if (SwingUtilities.isEventDispatchThread()) {
    			doUnHilite();
    		} else {
    			SwingUtilities.invokeLater(new Runnable() {
    				@Override
    				public void run() {
    					doUnHilite();
    				}
    			});
    		}
    	}
    
    	public void doUnHilite() {
    		currentColor = statusColor;
    		repaint();
    	}
    
    
    	public void paintComponent(Graphics g){
    		Graphics2D g2 = (Graphics2D) g;
    		super.paintComponent(g2);
    		g2.translate(-poly.getBounds().x, -poly.getBounds().y);
    		g2.setColor(currentColor);
    		g2.fillPolygon(poly);
    		g2.setColor(Color.black);
    		g2.drawPolygon(poly);
    	}
    
    }
    FILE: SimpleTester.java
    Java Code:
    public class SimpleTester {
    	
    	void runTest(){
    		theTest();
    	}
    	
    	void theTest(){
    		SimpleFrame sf = new SimpleFrame();
    		sf.sb.hilite();
    	}
    }

  2. #2
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,883
    Rep Power
    25

    Default Re: Threading GUI still doesn't work

    see what works and what doesn't.
    What is supposed to happen? I get a frame with a rectangular shape on the left that changes colors from blue to red as the cursor is moved over the frame.

    When I swap the commenting out of the two method calls, the same thing happens.

    What is "works" and "doesn't work"?
    Last edited by Norm; 04-06-2012 at 10:04 PM.
    If you don't understand my response, don't ignore it, ask a question.

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

    Default Re: Threading GUI still doesn't work

    It all has to do with references. When you call theTest() in your SimpleTester object, you create a *new* SimpleFrame object, one that is completely distinct from the SimpleFrame that is being displayed. You can call all the methods you'd like on this new SimpleFrame object but it won't have an effect on the displayed SimpleFrame. One bad solution is to use static variables. A better solution is to pass a reference of the current SimpleFrame into your SimpleTester object.

    i.e.,

    Java Code:
          test.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                
                // pass the current SimpleFrame object into SimpleTester
                SimpleTester st = new SimpleTester(SimpleFrame.this);
                st.runTest(); // why doesn't this test work...
                // runTest(); // and this test does. They call the same routine.
             }
          });
    and

    Java Code:
    class SimpleTester {
       private SimpleFrame sf;
       
       public SimpleTester(SimpleFrame sf) {
          this.sf = sf; // get the reference to SimpleFrame and store it
       }
    
       void runTest() {
          theTest();
       }
    
       void theTest() {
          // SimpleFrame sf = new SimpleFrame();
          sf.sb.hilite(); // use the stored reference
       }
    }
    By the way, your issue has nothing to do with threading and all to do with using the appropriate references.
    Last edited by Fubarable; 04-06-2012 at 10:15 PM.

  4. #4
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,883
    Rep Power
    25

    Default Re: Threading GUI still doesn't work

    When you have these kinds of problems you can get a clue to what is happening by adding println statements to all of the constructors and methods. With this program you would have seen that there two calls to the SimpleFrame and SimpleButton class constructors but only one set was visible. Then as you clicked the test button the number of printlns would expand as more and more instances were created.
    Fubarable likes this.
    If you don't understand my response, don't ignore it, ask a question.

  5. #5
    devdon is offline Member
    Join Date
    Mar 2012
    Posts
    21
    Rep Power
    0

    Default Re: Threading GUI still doesn't work

    You've most definitely given me the answer. In my program it turns out I wrestled with a similar problem and came up with a hideous workaround that your elegant solution will also fix. Thank you very much for solving my problem even though it wasn't a thread issue. I greatly appreciate it... I just couldn't get past it alone.

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

    Default Re: Threading GUI still doesn't work

    You're quite welcome. Please also take Norm's suggestions to heart. Learning to debug is as important as learning to program.

  7. #7
    devdon is offline Member
    Join Date
    Mar 2012
    Posts
    21
    Rep Power
    0

    Default Re: Threading GUI still doesn't work

    "When you have these kinds of problems you can get a clue to what is happening by adding println statements to all of the constructors and methods."

    Yes, and thank you for your advice. I had added some of this in but in my mind I had it set (wrongly) that the problem was one of screen redraw/refresh because my println statements were working but the key wasn't being redrawn. What Fubarable told me was not on my radar. But your advice is wise. Thanks again.

  8. #8
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,883
    Rep Power
    25

    Default Re: Threading GUI still doesn't work

    An unexpected call to a constructor should make you wonder: why did that happen?

    Sometimes with large, complicated, interconnected classes the creation of an unused/not visible class object will be hard to detect without the simple use of a few printlns.
    Last edited by Norm; 04-06-2012 at 11:59 PM.
    If you don't understand my response, don't ignore it, ask a question.

Similar Threads

  1. Why doesn't this work?
    By mailman in forum Java Applets
    Replies: 5
    Last Post: 01-10-2012, 02:01 PM
  2. Jar doesn't work
    By mad72584 in forum New To Java
    Replies: 35
    Last Post: 08-07-2011, 06:22 PM
  3. why this doesn't work?
    By hitesh_public in forum New To Java
    Replies: 5
    Last Post: 08-09-2010, 09:07 AM
  4. Why doesn't this work?
    By Corder10 in forum New To Java
    Replies: 1
    Last Post: 07-04-2009, 11:33 PM
  5. Synchronization Doesn't seem to work
    By sherinpearl in forum Threads and Synchronization
    Replies: 1
    Last Post: 04-23-2008, 07:30 PM

Tags for this Thread

Posting Permissions

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