Sorry for the poor title of the question, I am at a standstill about the cause of this error and do not know how to formulate this question.
I am learning basic Swing and doing this exercise from the online book Introduction to Java Programming.
I did not follow the instructions for the letter and instead try to do this:
- there is a window that shows a visual representation of two cubes
- when you click on one of the dice, it "rolls" and shows a new value
My implementation:
- a very simple JDie object that extends JPanel
- overridden paintComponent method for painting matrix views
- change the color of the matrix every time the value changes only for visual cues
- added a listener to “roll” the dice when the mouse is pressed and then
repaint
Bug fixed:
- Run the main DieTest method
- Resize the window to fit the two stamps.
- Click on the second die to collapse it.
- Now click on the first die to collapse it
- The second die value returns to its original value.
- If you resize the window, the second matrix value will also change.
If I click on the cubes to collapse them, until I resize the window, the error will not appear ...
I suppose I'm making a basic mistake somewhere that just disguised itself as this weird behavior.
I tried to destroy the code as hard as I could, it took a long time when an error occurred and when it did not:
import java.awt.*; import java.awt.event.*; import javax.swing.*; class JDie extends JPanel { private Color color; private int value; JDie(){ value = getValue(); color = Color.BLACK; //add listener addMouseListener(new MouseAdapter(){ @Override public void mousePressed(MouseEvent arg0) { value = getValue(); //'roll' the die repaint(); } }); } /*private helper methods */ private int getValue(){ int v =(int)(Math.random()*6) + 1; //change color just to show that the //value has changed color = getRandomColor(); return v; } private Color getRandomColor(){ float r = (float)Math.random(); float g = (float)Math.random(); float b = (float)Math.random(); return new Color(r, g, b); } //draws the pips for the die @Override public void paintComponent(Graphics g){ super.paintComponent(g); g.setColor(color); //draw pips //set pip size int pip_side = 10; switch(value){ case 1: g.fillRect(3*pip_side, 3*pip_side, pip_side, pip_side); break; case 2: g.fillRect(5*pip_side, pip_side, pip_side, pip_side); g.fillRect(pip_side, 5*pip_side, pip_side, pip_side); break; case 3: g.fillRect(5*pip_side, pip_side, pip_side, pip_side); g.fillRect(pip_side, 5*pip_side, pip_side, pip_side); g.fillRect(3*pip_side, 3*pip_side, pip_side, pip_side); break; case 4: g.fillRect(pip_side, pip_side, pip_side, pip_side); g.fillRect(5*pip_side, 5*pip_side, pip_side, pip_side); g.fillRect(5*pip_side, pip_side, pip_side, pip_side); g.fillRect(pip_side, 5*pip_side, pip_side, pip_side); break; case 5: g.fillRect(pip_side, pip_side, pip_side, pip_side); g.fillRect(5*pip_side, 5*pip_side, pip_side, pip_side); g.fillRect(5*pip_side, pip_side, pip_side, pip_side); g.fillRect(pip_side, 5*pip_side, pip_side, pip_side); g.fillRect(3*pip_side, 3*pip_side, pip_side, pip_side); break; case 6: g.fillRect(pip_side, pip_side, pip_side, pip_side); g.fillRect(5*pip_side, 5*pip_side, pip_side, pip_side); g.fillRect(5*pip_side, pip_side, pip_side, pip_side); g.fillRect(pip_side, 5*pip_side, pip_side, pip_side); g.fillRect(pip_side, 3*pip_side, pip_side, pip_side); g.fillRect(5*pip_side, 3*pip_side, pip_side, pip_side); break; } } } public class DieTest extends JFrame{ DieTest(){ setLayout(new GridLayout()); add(new JDie()); add(new JDie()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //if I set the size smaller than the JDie is displaying //and resize the window before 'rolling' the dice //then the bug appears...?! setSize(80, 80); //setting the size larger than both JDie //and it works fine whether you resize or not // setSize(200, 200); setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable(){ @Override public void run() { new DieTest(); } }); } }
-------------- EDIT -----------------
Running the code again, I noticed that this does not happen in 100% of cases, but the error still exists. Here's the gif I just took from it, this might show the problem better:

You can clearly see the original value when the original color is redrawn, when I click on the first stamp again. When I resize the window, the second matrix value goes back to the previous value it had ... I really don't understand this ...
--------------- EDIT 2 ---------------------
- I tried the same code on another computer (mac), but could not replicate the problem.
- Compiled and ran the code on my computer outside of Eclipse, could not replicate the problem.
- Edit the code that Eclipse compiled from the command line, only received the problem once, could not reproduce it today.
- Having run the code from Eclipse, am I still having a problem with 1 5-10 times? If he does not appear on the first "passage", as it were, does not appear at all. Gif illustrates this well.
So, it seems that my computer is configured and affected, details:
- Windows 7 64 bit
- Eclipse Kepler Service Release 1
- Java Update 7 51
- Java SE Development Kit 7 Update 3 (64 bit)
This is complicated because I know that I know longer if it calls my code or some other program. Like newb, how can I find out if any future problems are the result of my poor programming or something else ... disappointment.
---------- EDIT 3 -----------
Like a quick exploration of the sides of concurrency: I set all instance fields to volatile I set all the methods, including paintComponent, for synchronization I deleted the Math.random () call (although I read another thread that said it was a stream implementation) and instead replaced an instance of random objects
Unfortunately, I still get a visual outage.
Another thing that I noticed is that it seems to occur much less frequently about 1 time in 10 times. I continue to hope that this is fixed, and then retry again. In my original program that I worked on, it was like 1 out of 3 (I completely changed this program, so I don't have it in my hands).
-------- EDIT 4 --------- I came up with a slightly more truncated version that no longer uses any random values and still produces a visual shutdown. This seems to be happening more often with this code:
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ColorPanelsWindow extends JFrame{ class ColorPanel extends JPanel {
A few observations:
- afaict panels must first overlap.
- if I use the layout of the stream, increase the size of the window, or in any way that first overlaps the overlap panels, then I don’t see to get the problem (or maybe it happens much less often?)