@@ -90,6 +90,129 @@ void testIconsRenderedCorrectlyAfterZoomChangeWithImageListHole() {
9090 }
9191 }
9292
93+ /**
94+ * A tool bar addresses its normal, hot and disabled image list with a single
95+ * index per item, and disposing an item frees its slot in those lists for
96+ * reuse. The remaining items must keep rendering their own icon.
97+ */
98+ @ Test
99+ void testIconsRenderedCorrectlyAfterDisposingAnotherItem () {
100+ Display display = new Display ();
101+ RGB [] colors = { new RGB (220 , 40 , 40 ), new RGB (40 , 180 , 40 ), new RGB (40 , 40 , 220 ) };
102+ Image [] icons = createIcons (display , colors );
103+ try {
104+ Shell shell = new Shell (display );
105+ shell .setLayout (new FillLayout ());
106+ ToolBar bar = new ToolBar (shell , SWT .FLAT );
107+ ToolItem [] items = createItems (bar , icons );
108+ shell .setSize (500 , 90 );
109+ shell .open ();
110+
111+ items [1 ].dispose ();
112+
113+ Set <ToolItemWithExpectedColor > itemsToCheck = Set .of (
114+ new ToolItemWithExpectedColor (items [0 ], colors [0 ]),
115+ new ToolItemWithExpectedColor (items [2 ], colors [2 ]));
116+ assertTrue (waitUntilIconsRenderOwnColor (display , () -> iconsRenderOwnColor (bar , itemsToCheck , colors ),
117+ TIMEOUT_MILLIS ), "every tool item must render its own icon after another item is disposed" );
118+ } finally {
119+ disposeAll (icons , display );
120+ }
121+ }
122+
123+ /**
124+ * Tool bars share the image lists for a given icon size, so the items of one
125+ * tool bar must not be affected by those of another tool bar using icons of the
126+ * same size.
127+ */
128+ @ Test
129+ void testIconsRenderedCorrectlyWithSecondToolBarUsingSameIconSize () {
130+ Display display = new Display ();
131+ RGB [] colors = { new RGB (220 , 40 , 40 ), new RGB (40 , 180 , 40 ), new RGB (40 , 40 , 220 ), new RGB (230 , 200 , 30 ) };
132+ Image [] icons = createIcons (display , colors );
133+ try {
134+ Shell shell = new Shell (display );
135+ shell .setLayout (new FillLayout (SWT .VERTICAL ));
136+ ToolBar firstBar = new ToolBar (shell , SWT .FLAT );
137+ ToolItem [] firstItems = createItems (firstBar , icons [0 ], icons [1 ]);
138+ ToolBar secondBar = new ToolBar (shell , SWT .FLAT );
139+ ToolItem [] secondItems = createItems (secondBar , icons [2 ], icons [3 ]);
140+ shell .setSize (500 , 180 );
141+ shell .open ();
142+
143+ Set <ToolItemWithExpectedColor > firstItemsToCheck = Set .of (
144+ new ToolItemWithExpectedColor (firstItems [0 ], colors [0 ]),
145+ new ToolItemWithExpectedColor (firstItems [1 ], colors [1 ]));
146+ Set <ToolItemWithExpectedColor > secondItemsToCheck = Set .of (
147+ new ToolItemWithExpectedColor (secondItems [0 ], colors [2 ]),
148+ new ToolItemWithExpectedColor (secondItems [1 ], colors [3 ]));
149+ assertTrue (
150+ waitUntilIconsRenderOwnColor (display ,
151+ () -> iconsRenderOwnColor (firstBar , firstItemsToCheck , colors )
152+ && iconsRenderOwnColor (secondBar , secondItemsToCheck , colors ),
153+ TIMEOUT_MILLIS ),
154+ "every tool item must render its own icon although both tool bars share the image lists" );
155+ } finally {
156+ disposeAll (icons , display );
157+ }
158+ }
159+
160+ /**
161+ * Changing the orientation moves every item's images into image lists created
162+ * for the new orientation, which must retain the assignment of items to their
163+ * icons.
164+ */
165+ @ Test
166+ void testIconsRenderedCorrectlyAfterOrientationChange () {
167+ Display display = new Display ();
168+ RGB [] colors = { new RGB (220 , 40 , 40 ), new RGB (40 , 180 , 40 ), new RGB (40 , 40 , 220 ) };
169+ Image [] icons = createIcons (display , colors );
170+ try {
171+ Shell shell = new Shell (display );
172+ shell .setLayout (new FillLayout ());
173+ ToolBar bar = new ToolBar (shell , SWT .FLAT );
174+ ToolItem [] items = createItems (bar , icons );
175+ shell .setSize (500 , 90 );
176+ shell .open ();
177+
178+ bar .setOrientation (SWT .RIGHT_TO_LEFT );
179+ bar .setOrientation (SWT .LEFT_TO_RIGHT );
180+
181+ Set <ToolItemWithExpectedColor > itemsToCheck = new HashSet <>();
182+ for (int i = 0 ; i < items .length ; i ++) {
183+ itemsToCheck .add (new ToolItemWithExpectedColor (items [i ], colors [i ]));
184+ }
185+ assertTrue (waitUntilIconsRenderOwnColor (display , () -> iconsRenderOwnColor (bar , itemsToCheck , colors ),
186+ TIMEOUT_MILLIS ), "every tool item must render its own icon after an orientation change" );
187+ } finally {
188+ disposeAll (icons , display );
189+ }
190+ }
191+
192+ private static Image [] createIcons (Display display , RGB [] colors ) {
193+ Image [] icons = new Image [colors .length ];
194+ for (int i = 0 ; i < colors .length ; i ++) {
195+ icons [i ] = solidIcon (display , 16 , colors [i ]);
196+ }
197+ return icons ;
198+ }
199+
200+ private static ToolItem [] createItems (ToolBar bar , Image ... icons ) {
201+ ToolItem [] items = new ToolItem [icons .length ];
202+ for (int i = 0 ; i < icons .length ; i ++) {
203+ items [i ] = new ToolItem (bar , SWT .PUSH );
204+ items [i ].setImage (icons [i ]);
205+ }
206+ return items ;
207+ }
208+
209+ private static void disposeAll (Image [] icons , Display display ) {
210+ for (Image icon : icons ) {
211+ icon .dispose ();
212+ }
213+ display .dispose ();
214+ }
215+
93216 private static boolean waitUntilIconsRenderOwnColor (Display display , BooleanSupplier condition ,
94217 long timeoutMillis ) {
95218 long deadline = System .currentTimeMillis () + timeoutMillis ;
0 commit comments