Results 1 to 8 of 8
Thread: Threading GUI still doesn't work
- 04-06-2012, 08:30 PM #1
Member
- Join Date
- Mar 2012
- Posts
- 21
- Rep Power
- 0
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(); } }
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); } }
Java Code:public class SimpleTester { void runTest(){ theTest(); } void theTest(){ SimpleFrame sf = new SimpleFrame(); sf.sb.hilite(); } }
- 04-06-2012, 10:01 PM #2
Re: Threading GUI still doesn't work
see what works and what doesn't.
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.
-
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. } });
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 } }
Last edited by Fubarable; 04-06-2012 at 10:15 PM.
- 04-06-2012, 10:32 PM #4
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.
If you don't understand my response, don't ignore it, ask a question.
- 04-06-2012, 10:59 PM #5
Member
- Join Date
- Mar 2012
- Posts
- 21
- Rep Power
- 0
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.
-
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.
- 04-06-2012, 11:54 PM #7
Member
- Join Date
- Mar 2012
- Posts
- 21
- Rep Power
- 0
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.
- 04-06-2012, 11:56 PM #8
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
-
Why doesn't this work?
By mailman in forum Java AppletsReplies: 5Last Post: 01-10-2012, 02:01 PM -
Jar doesn't work
By mad72584 in forum New To JavaReplies: 35Last Post: 08-07-2011, 06:22 PM -
why this doesn't work?
By hitesh_public in forum New To JavaReplies: 5Last Post: 08-09-2010, 09:07 AM -
Why doesn't this work?
By Corder10 in forum New To JavaReplies: 1Last Post: 07-04-2009, 11:33 PM -
Synchronization Doesn't seem to work
By sherinpearl in forum Threads and SynchronizationReplies: 1Last Post: 04-23-2008, 07:30 PM
Bookmarks