Community
Participate
Working Groups
Build Identifier: MyEclipse 6.0.1-GA-200710 (but is also with compiled jar, so not connected to build) I dispose of a label, create a new label. The new label stays invisible as long as the Shell area doesn't change. The button "useless" is trying several maneuvers to force a real redraw, but fails. The button "pixeltrick" changes the shell area 1 pixel, and with that trick manages to force a redraw. swt library is swt-3.5.2-win32-win32-x86. Reproducible: Always Steps to Reproduce: package auge; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; public class RefreshBug { static Label label; public static void main(String[] args) { final Display display = new Display (); final Shell testshell = new Shell(display, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); final GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 1; gridLayout.marginBottom = 0; testshell.setLayout(gridLayout); final Button update = new Button (testshell, SWT.PUSH); update.setText ("&Update"); update.addSelectionListener (new SelectionAdapter () { public void widgetSelected (SelectionEvent e) { label.dispose(); label = new Label (testshell, SWT.NONE | SWT.BORDER); label.setText ("I'm invisible"); testshell.pack(); testshell.open(); } }); final Button useless = new Button (testshell, SWT.PUSH); useless.setText ("&Notworking"); useless.addSelectionListener (new SelectionAdapter () { public void widgetSelected (SelectionEvent e) { testshell.changed(testshell.getChildren()); testshell.redraw(); testshell.setModified(true); testshell.setRedraw(true); testshell.update(); testshell.pack(true); testshell.open(); } }); final Button trick = new Button (testshell, SWT.PUSH); trick.setText ("&Pixeltrick"); trick.addSelectionListener (new SelectionAdapter () { public void widgetSelected (SelectionEvent e) { if (gridLayout.marginBottom == 0) gridLayout.marginBottom = 1; else gridLayout.marginBottom = 0; testshell.setLayout(gridLayout); testshell.pack(); testshell.open(); } }); label = new Label (testshell, SWT.NONE | SWT.BORDER); label.setText ("I'm visible"); testshell.pack(); testshell.open(); while (!testshell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } }
Created attachment 175561 [details] Screenshots with visible/invisible label You see first a screenshot of the freshly started application. After the "update"-Button, which deletes and creates a label, the new label is invisible. It stays invisible even after all the operations triggered via the "Notworking"-Button. Finally, a press on the "Pixeltrick"-Button makes the label visible.
The shell is using a layout. So for the newly created label you should call testshell.layout() so that the size and location of the label can be set.
The behaviour was identical with swt-3.6-win32-win32-x86.
This is the right code: final Button update = new Button (testshell, SWT.PUSH); update.setText ("&Update"); update.addSelectionListener (new SelectionAdapter () { public void widgetSelected (SelectionEvent e) { label.dispose(); label = new Label (testshell, SWT.NONE | SWT.BORDER); label.setText ("I'm invisible"); label.getParent().layout(); // testshell.pack(); // testshell.open(); } }); Closing as not Eclipse.
(In reply to comment #4) That does in fact work. It causes a much "bigger" redraw though (flashing of whole shell area) than the pixel change... Also it's said about layout(): "You would do this after changing anything about the children that might affect their size or position" (http://www.eclipse.org/articles/article.php?file=Article-Understanding-Layouts/index.html) But in fact it only seems to be needed if size or position are *not* affected. If you change size or position (eg by giving the label a longer text) the redraw (and a much more economic one, no window flashing) *does* occur and the new label is visible. Also it's said (same place): "Note that shell.open() causes a layout to occur" which seems to be untrue (I do a shell.open() in the Update and Nonworking button event). While I accept the solution via layout(), I still feel the "softer" redraw which can be achieved with the pixel trick or otherwise triggering a minimal resize should be available *somehow* here. Also, I have an application with similar function where layout() does not suffice. I'll try to whittle it down to the relevant portions. But I gleaned from your comment, the close of this bug is due to "not being eclipse"... if this is only about eclipse, then I'm indeed wrong here, and sorry. I was under the impression this bugzilla treated swt bugs as well.
(In reply to comment #5) > (In reply to comment #4) > That does in fact work. It causes a much "bigger" redraw though (flashing of > whole shell area) than the pixel change... Yes, See Bug 103863 You can use "label.getParent().layout(new Control[] {label}, SWT.DEFER);" instead. > Also it's said about layout(): > "You would do this after changing anything about the children that might affect > their size or position" > (http://www.eclipse.org/articles/article.php?file=Article-Understanding-Layouts/index.html) > But in fact it only seems to be needed if size or position are *not* affected. No, the article is correct. > If you change size or position (eg by giving the label a longer text) the > redraw (and a much more economic one, no window flashing) *does* occur and the > new label is visible. Yes, the redraw does occur (for free). But the *layout* does not occur (for free). You need to call layout yourself. Your code failed not because you missed a redraw, the label was invisible because its size is 0,0 (size was never set in it). Calling layout in the parent container causes the layout manager to recalculate the size for the child. > Also it's said (same place): "Note that shell.open() causes a layout to occur" > which seems to be untrue (I do a shell.open() in the Update and Nonworking > button event). If you never set the size of the shell the first shell.open() will cause a resize, which will cause a layout to happen. For example: 1: shell.open();//send resize (size == preferred size) 2: shell.setSize(400, 400); //send resize (size == 400, 400) shell.open(); // does _not_ send resize 3: shell.open();//send resize (size == preferred size) shell.open(); // does _not_ send resize > While I accept the solution via layout(), I still feel the "softer" redraw > which can be achieved with the pixel trick or otherwise triggering a minimal > resize should be available *somehow* here. And it is: "label.getParent().layout(new Control[] {label}, SWT.DEFER);" > Also, I have an application with similar function where layout() does not > suffice. I'll try to whittle it down to the relevant portions. > But I gleaned from your comment, the close of this bug is due to "not being > eclipse"... if this is only about eclipse, then I'm indeed wrong here, and > sorry. I was under the impression this bugzilla treated swt bugs as well. You got it right, it treated swt bugs. I close it as not eclipse because the bugs is not in Eclipse (which SWT is part), the bug is in application code: you forgot to call parent.layout() after changing its children, that is all.