5

I have a small java desktop application that needs to be able to add and remove fields dynamically by clicking "+" and "-" buttons respectively. I have gotten this to work by calling revalidate() and then repaint() on all the parent containers all the way up to the JFrame in the ActionListener.

This seemed to have done the trick, but occasionally it doesn't work and the JPanels don't resize correctly. This happens infrequently and seemingly at random and lead me to believe it might be a concurrency issue. I have tried launching the parent container from the event dispatch thread but this hasn't solved the problem.

Is this actually a concurrency issue or am I barking up the wrong tree? Anyone have any idea what is going on and how it can be solved?

Much appreciated

-SwingNoob

mre
  • 43,520
  • 33
  • 120
  • 170
john
  • 51
  • 1
  • 2
  • @john, a [`LayoutManager`](http://download.oracle.com/javase/tutorial/uiswing/layout/using.html) is responsible for its components. that being said, there's absolutely no reason to invoke `repaint()` or `revalidate()` when adding/removing components from a container. – mre Jun 19 '11 at 22:17
  • 1
    Intermittent errors do often suggest concurrency issues, but I don't think that anyone is going to be able to give you a solid answer based in the information presented. – Hovercraft Full Of Eels Jun 19 '11 at 22:19
  • 1
    @mre: Please clarify your comment because in my experience and from my reading, one is required to call `revalidate` and `repaint` on the Container when removing items and `revalidate` and sometimes `repaint` when adding components. – Hovercraft Full Of Eels Jun 19 '11 at 22:20
  • 1
    @Hovercraft, I retract my statement--you're in fact correct. @john, I apologize for my confusion...please neglect the comment I made above. – mre Jun 19 '11 at 22:31
  • 1
    @john, it would be helpful if you provided a small snippet of relevant code. – mre Jun 19 '11 at 22:35
  • 1
    @Hovercraft Full Of Eels, @mre hmmm 10:1 that's about invokeLater() :-) – mKorbel Jun 19 '11 at 22:51
  • @mKorbel, that's definitely a strong possibility :) – mre Jun 19 '11 at 23:00

2 Answers2

5

that isn't answer to OP's question nice example, OP's problem is maybe about LayoutManager and something unknow in OP's code

1/ if you adds a new JComponent to the Container then you have to call

validate();
repaint(); //lay with LayoutManager required that 

2/ if removes and then adds a JComponents from/to the Container then you have to call

revalidate();
repaint(); // lay with LayoutManager required that 

3/ looks like as revalidate covered validate too,

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • I'm not sure if invoking `repaint()` is necessary. I've written some sample code, and it appears that invoking `validate()` is all that is required, whether you're removing or adding components. But, of course, this could be entirely situational. :) – mre Jun 19 '11 at 23:05
  • @mre agreed if you'll removes or adds only one JComponents, if are there number of JComponents, my view you can risk with that only with strict MVC GUI's architectures, otherwise not good idea safe byteCode for one line ... :-), yes repaint very lazy to the GC, that's undescribed alchemy – mKorbel Jun 19 '11 at 23:17
  • At the 2/ case I'm looking at it's enough to simply call repaint and not revalidate and repaint – Juan C Nuno Mar 12 '20 at 21:28
2

Launching the container from the AWT/EDT thread is not enough.

You need to execute every layout change to the container on the AWT/EDT thread.

So if you make sure your add and remove are done that way, revalidate() or repaint() should not be necessary.