1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> 2 <HTML> 3 <HEAD> 4 <TITLE>Using the Multiplexing Look and Feel</TITLE> 5 </HEAD> 6 7 <BODY BGCOLOR="#FFFFFF" TEXT="#000000"> 8 9 <b> 10 <font size=+3> 11 Using the Multiplexing Look and Feel 12 </font> 13 </b> 14 15 <blockquote> 16 <hr> 17 <p> 18 <i> 19 This document is based on an article 20 originally published in 21 <a href="http://www.oracle.com/technetwork/java/javase/tech/articles-jsp-139072.html" target="_top"><em>The Swing 22 Connection</em></a>. 23 </i> 24 </p> 25 <hr> 26 </blockquote> 27 28 <p> 29 The Multiplexing look and feel lets 30 you supplement an ordinary look and feel 31 (called the <em>default</em> look and feel) 32 with one or more <em>auxiliary</em> look and feels. 33 For example, you could 34 simultaneously provide text-to-speech and Braille outputs, 35 in addition to the ordinary visual output that a Swing-based 36 application generates, 37 by adding 38 two auxiliary look and feels (one for text-to-speech, 39 the other for Braille) 40 to the default look and feel. 41 The default look and feel can be any ordinary look and feel -- 42 the Java or Windows look and feel, for example -- 48 This document has the following sections: 49 <ul> 50 <li> <a href="#overview">Overview</a> 51 <li> <a href="#howtouse">How to Use Auxiliary Look and Feels</a> 52 <li> <a href="#howtowrite">Tips for Writing an Auxiliary Look and Feel</a> 53 <ul> 54 <li> <a href="#dosanddonts">Dos and Don'ts</a> 55 <li> <a href="#uidefaults">Extending UIDefaults</a> 56 <li> <a href="#defaultui">Examining Other UI Objects</a> 57 </ul> 58 <li> <a href="#implementation">How the Multiplexing Look and Feel is 59 Implemented</a> 60 <li> <a href="#custom">How to Provide a Custom Multiplexing 61 Look and Feel</a> 62 </ul> 63 64 <p> 65 Before reading further, you should be familiar 66 with the concept of pluggable look and feels. 67 For basic information, see 68 <a href="https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html">How to Set the Look and Feel</a>, 69 a section in 70 <em>The Java Tutorial</em>. 71 For architectural details, you can read 72 <a 73 href="http://www.oracle.com/technetwork/java/architecture-142923.html#pluggable">Pluggable look-and-feel architecture</a>, a section within 74 a <em>Swing Connection</em> article. 75 </p> 76 77 <p> 78 <a name="overview"></a> 79 <hr width=100% align=LEFT size=2> 80 <b> 81 <font color="#000080" size="+2">Overview</font> 82 </b> 83 84 85 <p> 86 87 The classes in the 88 <code>javax.swing.plaf.multi</code> package 89 implement a 90 <i>multiplexing look and feel</i>. 91 A multiplexing look and feel transparently creates -- and 92 simultaneously supports -- UI objects from several different look and feels 93 in response to a component requesting its UI object 94 (with the <code>getUI</code> method). 95 96 <p> 97 Without a multiplexing look and feel, a 98 developer who wanted to enhance a particular look and feel would 99 need to extend the classes supporting that look and feel. For example, to 100 add text-to-speech support to the Java look and feel without using a multiplexing 101 look and feel, the developer would need to create a group of 102 classes that extend those of 103 the Java look and feel, and add text-to-speech support to the new classes. 104 If the developer also wanted to add text-to-speech support to other look 105 and feels, 106 such as Motif or Windows, the developers would need to create subclasses 107 of those classes as well. 108 </p> 109 110 <p> 111 This approach has at least two shortcomings: 112 <ul type="DISC"> 113 <li>First, each subclass must use what is 114 essentially a copy of the same code, potentially creating a difficult 115 support situation for the developer.<br></li> 116 <li>Second, and more significantly for the 117 end user, some application developers might force a 118 particular look and feel to be used. When this approach is used, 119 the end user can't even use the enhanced look and feel.</li> 120 </ul> 121 122 <p> 123 A multiplexing look and feel 124 both these problems simultaneously because it allows multiple look 125 and feels to be combined. 126 The first problem (having to use what amounts to a second copy of the same 127 code) is solved because the developer can create a specialized look 128 and feel that can then be combined with other look and feels. 129 </p> 130 131 <p> 132 The second problem (having to force the use of 133 a particular look and feel) is solved because a specialized look and feel 134 can be used with whatever default look and feel the 135 application may have locked in place. 136 </p> 137 138 <p> 139 The default multiplexing look and feel implementation, 140 represented by the <code>MultiLookAndFeel</code> class 141 in the <code>javax.swing.plaf.multi</code> package, 142 is called (unsurprisingly) 143 the Multiplexing look and feel. 144 145 <p> 146 <a name="howtouse"></a> 147 <hr width=100% align=LEFT size=2> 148 <b> 149 <font color="#000080" size="+2">How to Use Auxiliary Look and Feels</font> 150 </b> 151 152 153 <p> 154 It's easy to use auxiliary look and feels with Swing. To instruct 155 Swing to use the Multiplexing look and feel, all an application 156 has to do is modify the <code>$JDKHOME/conf/swing.properties</code> 157 file to include a definition of the <code>swing.auxiliarylaf</code> 158 property. Swing treats the <code>swing.auxiliarylaf</code> 159 property as a comma-separated list of <code>LookAndFeel</code> 160 subclasses that specify what auxiliary look and feels should be 161 used in addition to the default look and feel. If at least one valid 162 <code>LookAndFeel</code> 163 subclass is specified in the <code>swing.auxiliarylaf</code> 164 property, Swing automatically uses the Multiplexing look and feel 165 to load and support the default and auxiliary look and feels. 166 </p> 167 168 <p> 169 For example, let's assume that an application 170 makes use of a look and feel that supports text-to-speech feedback, and also 171 uses an look and feel that adds support for a device 182 could simply add the following line to the <code>$JDKHOME/conf/swing.properties</code> file: 183 </p> 184 185 <p> 186 <code> 187 swing.auxiliarylaf=com.myco.TextTalkerLookAndFeel,<br> 188 com.smellco.OlfactoryLookAndFeel</code> 189 </p> 190 191 <p> 192 This statement tells Swing to obtain a component's UI from the Multiplexing 193 look and feel automatically, instead of obtaining it directly from 194 the default look and feel. The resulting multiplexing UI is a small 195 delegate that obtains and maintains UIs from the default and auxiliary 196 look and feels. As a result, when a method is invoked in a multiplexing 197 UI object, the multiplexing UI invokes the same method on each 198 of the UIs obtained from the default and auxiliary look and feels. 199 </p> 200 201 <p> 202 <a name="howtowrite"></a> 203 <hr width=100% align=LEFT size=2> 204 <b> 205 <font color="#000080" size="+2">Tips for Writing an Auxiliary Look and Feel</font> 206 </b> 207 208 209 <p> 210 An auxiliary look and feel is like any other look and feel, 211 except that it doesn't have to provide the complete support 212 that a default look and feel must. For 213 example, an auxiliary look and feel that supports just text-to-speech feedback 214 doesn't need to provide any code for painting. 215 Also, it might not need to support all components -- 216 <code>JSeparator</code>s, for example, might be ignored. 217 218 <p> 219 Auxiliary look and feels tend to be simple, 220 so developing one can be easier than developing a visual 221 look and feel. 222 The developer can concentrate solely 223 on providing the specialized functionality. 224 225 <p> 226 Because the primary purpose of an auxiliary look and feel is to enhance the 227 default look and feel, auxiliary look and feels tend 228 be nonvisual. Since an auxiliary look and feel is a genuine 229 look and feel, however, there is nothing to prevent it 230 from rendering information on the display. 231 </p> 232 233 <p> 234 Just like for any other look and feel, you 235 implement an auxiliary look and feel 236 by writing a subclass of <code>javax.swing.LookAndFeel</code> 237 and creating subclasses of the 238 <code><em>Foo</em>UI</code> classes defined in 239 the <code>javax.swing.plaf</code> package. 240 </p> 241 242 <p> 243 <br> 244 <a name="dosanddonts"> 245 <font color="#000080" size="+1"><b>Dos and Don'ts</b></font> 246 </a> 247 </p> 248 249 <p> 250 The following paragraphs provide some general recommendations for developing 251 auxiliary look and feels. 252 </p> 253 254 <p> 255 <font color="#000080"><b>Use the <code>installUI</code> method 256 to perform all initialization, 257 and the <code>uninstallUI</code> method 258 to perform all cleanup.</b></font> 259 </p> 260 <blockquote> 261 The <code>installUI</code> and <code>uninstallUI</code> 262 methods are invoked when a component's look and feel is set. 263 The <code>installUI</code> method gives the new UI object 264 a chance to add listeners on the component and its data model. 265 Similarly, the <code>uninstallUI</code> method 266 lets the previous UI object remove its listeners. 267 </blockquote> 268 <p> <font color="#000080"><b>Don't extend 269 visual look and feels.</b></font></p> 270 <blockquote> 271 We recommended that you <i>don't</i> implement 272 UI classes of an auxiliary look and feel as subclasses of the 273 UI classes of a visual look and feel. Why not? Because they might 274 accidentally inherit code that installs listeners on a component 275 object or renders the component on the display. As a result, 276 your auxiliary look and feel would compete with the default look 277 and feel rather than cooperating with it.<br> 278 <br> 279 Instead, we recommend that the UI classes of an auxiliary look 280 and feel directly extend the abstract UI classes in the <code>javax.swing.plaf</code> 281 package. By using this strategy, the developer of an auxiliary 282 look and feel can avoid competing with the default look and feel. 283 </blockquote> 284 <p> <font color="#000080"><b>Override all UI-specific methods 285 your UI classes inherit.</b></font> 286 </p> 287 <blockquote> 288 We recommend that each UI class of 289 an auxiliary look and feel override the methods 290 defined in the <code>javax.swing.plaf</code> 291 UI classes it descends from 292 The reasons for this recommendation are similar 293 to those for not extending a visual look and feel. 294 For example, the <code>ComponentUI</code> 295 class, from which all UI classes descend, 296 provides a default implementation for the <code>update</code> 297 method. This default implementation paints on the display 298 if the 299 component is opaque. If a UI class from a non-visual auxiliary 300 look and feel does not override this method, all 301 opaque components appear as blank areas on the screen! 302 </blockquote> 303 <p> 304 305 <br> 306 <a name="uidefaults"> 307 <font color="#000080" size="+1"><b>Extending UIDefaults</b></font> 308 </a> 309 310 <p>In many cases, you 311 might want an auxiliary look and feel to be "incomplete." That 312 is, you might not need to support the complete set 313 of components. 314 For example, an auxiliary look and feel might choose 315 to provide a <code>ButtonUI</code> subclass but no 316 <code>LabelUI</code> subclass. 317 This 318 option is allowed, and the multiplexing look and feel gracefully 319 handles such situations.</p> 320 <p>By default, however, Swing issues an error message when it asks 321 a look and feel for a UI object and the look and feel does not 322 support that UI. This message can be annoying, especially to auxiliary 323 look-and-feel developers who don't want to support a particular 324 component.</p> 325 <p>Fortunately, you can prevent this error 326 message by creating a subclass of the <code>UIDefaults</code> 327 class and returning an instance of it from the 328 <code>getDefaults</code> method 329 of your <code>LookAndFeel</code> class. 330 For example: 331 </p> 332 <p><code>public class MyAuxLookAndFeel 333 extends LookAndFeel {<br> 334 ...<br> 335 public UIDefaults getDefaults() {<br> 336 <b>UIDefaults table = <br> 337 338 new MyAuxUIDefaults();<br> 339 </b> Object[] uiDefaults = {<br> 340 "ButtonUI", "MyAuxButtonUI",<br> 341 ...<br> 342 }<br> 343 table.putDefaults(uiDefaults);<br> 344 return table;<br> 345 }<br> 346 }<br> 347 <br> 348 <b>class MyAuxUIDefaults extends UIDefaults {<br> 349 protected void getUIError(String msg) {<br> 350 //System.err.println<br> 351 // ("An 352 annoying message!");<br> 353 }<br> 354 }</b></code></p> 355 356 <p> 357 In the preceding example, an auxiliary look and feel named <code>MyAux</code> 358 creates a <code>UIDefaults</code> subclass 359 that overrides the <code>getUIError</code> 360 method. The <code>getUIError</code> 361 method is the method that is invoked when Swing cannot find a UI 362 object in a look and feel. By merely doing nothing in this method, 363 you can avoid the error message.</p> 364 <p> 365 366 <br> 367 <a name="defaultui"> 368 <b><font color="#000080" size="+1">Examining Other UI Objects</font></b> 369 </a> 370 371 <p>In 372 rare instances, a UI object from an auxiliary look and feel 373 may be interested in the default UI object used by the component. In 374 these cases, the UI object from auxiliary look and feel can obtain 375 the UI from a component by calling its <code>getUI</code> 376 method. The returned UI is an instance of one of the multiplexing 377 look and feel UI classes (for example, <code>MultiButtonUI</code>). 378 The UI object from the auxiliary look and feel can call the <code>getUIs</code> 379 method of the returned object to obtain an array containing a complete list 380 of all UI objects handled by the multiplexing UI. The first element 381 is guaranteed to be the UI created from the default look and feel. 382 </p> 383 384 <p> 385 <a name="implementation"></a> 386 <hr width=100% align=LEFT size=2> 387 <font color="#000080" size="+2"><b>How the Multiplexing Look and Feel 388 Is Implemented</b></font> 389 390 <p> 391 The Multiplexing look and feel 392 (represented by 393 <code>javax.swing.plaf.multi.MultiLookAndFeel</code>) 394 is meant to be transparent to 395 all developers and users. It should "just work" -- and 396 it is used only when the user tells Swing to use an auxiliary look 397 and feel.</p> 398 399 <p> 400 When the Multiplexing look and 401 feel is in use, the type of the UI object 402 associated with each component 403 depends on whether 404 any of the auxiliary look and feels currently in use 405 support the component. 406 If so, the component's UI object is 407 an instance of a multiplexing UI. 408 If only the default look and feel supports the component, 409 then the component gets 410 a UI object from the default look and feel, 411 just as if no auxiliary look and feels were installed. 412 413 <p> 414 A multiplexing UI object 415 obtains and maintains UI objects 416 from the default and auxiliary look 417 and feels, 418 referring to these UIs in the following manner: 419 420 <ul type="DISC"> 421 <li> The UI object from the default look 422 and feel is always the first to be created. After that, a UI object 423 is created from each auxiliary look and feel in the order 424 they are specified in the <code>swing.auxiliarylaf</code> 425 property.<br><br></li> 426 427 <li> When a method that requests information 428 from a UI object is invoked, the multiplexing UI object 429 invokes the method on all the UI objects, but returns 430 only the results from the UI for the default look and feel. 431 For example, when the <code>getPreferredSize</code> 432 method is invoked on a multiplexing UI, the UI returns only the 433 results of invoking <code>getPreferredSize</code> 434 on the UI obtained from the default look and feel. 435 The <code>getPreferredSize</code> method 436 is also invoked on the UI object for each auxiliary look and feel, 437 but the return values are ignored. 438 <br><br></li> 439 440 <li> When a method that does not request information 442 invokes that method on all UIs -- 443 on the UI object obtained from the default look 444 and feel 445 and on all the UIs obtained from the auxiliary look and feels, 446 as well. 447 For example, invoking the <code>installUI</code> 448 method on a multiplexing UI causes the multiplexing UI to invoke 449 <code>installUI</code> 450 on the UI obtained from the default look and feel and the UIs obtained from 451 the auxiliary factories.</li> 452 </ul> 453 <p> In all cases, the UI object obtained from 454 the default look and feel is acted upon first, and then the auxiliary 455 look and feels are acted upon in the order they are specified in 456 the <code>swing.auxiliarylaf</code> 457 property. 458 </p> 459 460 <p> 461 462 <a name="custom"></a> 463 <hr width=100% align=LEFT size=2> 464 <font color="#000080" size="+2"><b>How to Provide a Custom Multiplexing Look 465 and Feel</b></font> 466 467 <p>While 468 we hope the behavior of the Multiplexing look and feel is 469 flexible enough not to require an alternative multiplexing look 470 and feel, Swing allows the user to specify another multiplexing look 471 and feel to use. 472 </p> 473 474 <p> To do that, all the user has to do is modify 475 the <code>$JDKHOME/conf/swing.properties</code> 476 file to include a definition of the <code>swing.plaf.multiplexinglaf</code> 477 property. Swing then treats the <code>swing.plaf.multiplexinglaf</code> 478 property as a <code>LookAndFeel</code> 479 subclass that supports multiplexing. 480 </p> 481 <p> For example, if a user has a multiplexing 482 look and feel represented by <code>com.myco.SuperMultiLookAndFeel</code> 483 that is a better match for their needs than the Multiplexing 484 look and feel 485 (<code>javax.swing.plaf.multi.MultiLookAndFeel</code>), 486 the user could include the following line in <code>$JDKHOME/conf/swing.properties</code>: 487 </p> 488 489 <p> 490 <code>swing.plaf.multiplexinglaf = com.myco.SuperMultiLookAndFeel</code> 491 </p> 492 493 <p> 494 This statement instructs Swing to use <code>com.myco.SuperMultiLookAndFeel</code> 495 instead of <code>javax.swing.plaf.multi.MultiLookAndFeel</code>. But 496 if you use this kind of statement, be careful, because the suppliers 497 of auxiliary look and feels will most likely have developed and 498 tested against our Multiplexing look and feel. 499 </p> 500 501 </BODY> 502 </HTML> | 1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta charset="utf-8"/> 5 <title>Using the Multiplexing Look and Feel</title> 6 </head> 7 <!-- 8 Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. 9 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10 11 This code is free software; you can redistribute it and/or modify it 12 under the terms of the GNU General Public License version 2 only, as 13 published by the Free Software Foundation. Oracle designates this 14 particular file as subject to the "Classpath" exception as provided 15 by Oracle in the LICENSE file that accompanied this code. 16 17 This code is distributed in the hope that it will be useful, but WITHOUT 18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 version 2 for more details (a copy is included in the LICENSE file that 21 accompanied this code). 22 23 You should have received a copy of the GNU General Public License version 24 2 along with this work; if not, write to the Free Software Foundation, 25 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26 27 Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28 or visit www.oracle.com if you need additional information or have any 29 questions. 30 --> 31 32 <body> 33 34 <h1>Using the Multiplexing Look and Feel</h1> 35 36 <blockquote> 37 <hr> 38 <p> 39 <i> 40 This document is based on an article 41 originally published in 42 <a href="http://www.oracle.com/technetwork/java/javase/tech/articles-jsp-139072.html" 43 target="_top"><em>The Swing Connection</em></a>. 44 </i> 45 </p> 46 <hr> 47 </blockquote> 48 49 <p> 50 The Multiplexing look and feel lets 51 you supplement an ordinary look and feel 52 (called the <em>default</em> look and feel) 53 with one or more <em>auxiliary</em> look and feels. 54 For example, you could 55 simultaneously provide text-to-speech and Braille outputs, 56 in addition to the ordinary visual output that a Swing-based 57 application generates, 58 by adding 59 two auxiliary look and feels (one for text-to-speech, 60 the other for Braille) 61 to the default look and feel. 62 The default look and feel can be any ordinary look and feel -- 63 the Java or Windows look and feel, for example -- 69 This document has the following sections: 70 <ul> 71 <li> <a href="#overview">Overview</a> 72 <li> <a href="#howtouse">How to Use Auxiliary Look and Feels</a> 73 <li> <a href="#howtowrite">Tips for Writing an Auxiliary Look and Feel</a> 74 <ul> 75 <li> <a href="#dosanddonts">Dos and Don'ts</a> 76 <li> <a href="#uidefaults">Extending UIDefaults</a> 77 <li> <a href="#defaultui">Examining Other UI Objects</a> 78 </ul> 79 <li> <a href="#implementation">How the Multiplexing Look and Feel is 80 Implemented</a> 81 <li> <a href="#custom">How to Provide a Custom Multiplexing 82 Look and Feel</a> 83 </ul> 84 85 <p> 86 Before reading further, you should be familiar 87 with the concept of pluggable look and feels. 88 For basic information, see 89 <a href="https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html"> 90 How to Set the Look and Feel</a>, a section in <em>The Java Tutorial</em>. 91 For architectural details, you can read 92 <a 93 href="http://www.oracle.com/technetwork/java/architecture-142923.html#pluggable"> 94 Pluggable look-and-feel architecture</a>, a section within 95 a <em>Swing Connection</em> article. 96 </p> 97 98 <p> 99 <a id="overview"></a> 100 <hr> 101 <h2>Overview</h2> 102 103 <p> 104 105 The classes in the 106 <code>javax.swing.plaf.multi</code> package 107 implement a 108 <i>multiplexing look and feel</i>. 109 A multiplexing look and feel transparently creates -- and 110 simultaneously supports -- UI objects from several different look and feels 111 in response to a component requesting its UI object 112 (with the <code>getUI</code> method). 113 114 <p> 115 Without a multiplexing look and feel, a 116 developer who wanted to enhance a particular look and feel would 117 need to extend the classes supporting that look and feel. For example, to 118 add text-to-speech support to the Java look and feel without using a multiplexing 119 look and feel, the developer would need to create a group of 120 classes that extend those of 121 the Java look and feel, and add text-to-speech support to the new classes. 122 If the developer also wanted to add text-to-speech support to other look 123 and feels, 124 such as Motif or Windows, the developers would need to create subclasses 125 of those classes as well. 126 </p> 127 128 <p> 129 This approach has at least two shortcomings: 130 <ul> 131 <li>First, each subclass must use what is 132 essentially a copy of the same code, potentially creating a difficult 133 support situation for the developer.<br></li> 134 <li>Second, and more significantly for the 135 end user, some application developers might force a 136 particular look and feel to be used. When this approach is used, 137 the end user can't even use the enhanced look and feel.</li> 138 </ul> 139 140 <p> 141 A multiplexing look and feel 142 both these problems simultaneously because it allows multiple look 143 and feels to be combined. 144 The first problem (having to use what amounts to a second copy of the same 145 code) is solved because the developer can create a specialized look 146 and feel that can then be combined with other look and feels. 147 </p> 148 149 <p> 150 The second problem (having to force the use of 151 a particular look and feel) is solved because a specialized look and feel 152 can be used with whatever default look and feel the 153 application may have locked in place. 154 </p> 155 156 <p> 157 The default multiplexing look and feel implementation, 158 represented by the <code>MultiLookAndFeel</code> class 159 in the <code>javax.swing.plaf.multi</code> package, 160 is called (unsurprisingly) 161 the Multiplexing look and feel. 162 163 <p> 164 <a id="howtouse"></a> 165 <hr> 166 <h2>How to Use Auxiliary Look and Feels</h2> 167 168 <p> 169 It's easy to use auxiliary look and feels with Swing. To instruct 170 Swing to use the Multiplexing look and feel, all an application 171 has to do is modify the <code>$JDKHOME/conf/swing.properties</code> 172 file to include a definition of the <code>swing.auxiliarylaf</code> 173 property. Swing treats the <code>swing.auxiliarylaf</code> 174 property as a comma-separated list of <code>LookAndFeel</code> 175 subclasses that specify what auxiliary look and feels should be 176 used in addition to the default look and feel. If at least one valid 177 <code>LookAndFeel</code> 178 subclass is specified in the <code>swing.auxiliarylaf</code> 179 property, Swing automatically uses the Multiplexing look and feel 180 to load and support the default and auxiliary look and feels. 181 </p> 182 183 <p> 184 For example, let's assume that an application 185 makes use of a look and feel that supports text-to-speech feedback, and also 186 uses an look and feel that adds support for a device 197 could simply add the following line to the <code>$JDKHOME/conf/swing.properties</code> file: 198 </p> 199 200 <p> 201 <code> 202 swing.auxiliarylaf=com.myco.TextTalkerLookAndFeel,<br> 203 com.smellco.OlfactoryLookAndFeel</code> 204 </p> 205 206 <p> 207 This statement tells Swing to obtain a component's UI from the Multiplexing 208 look and feel automatically, instead of obtaining it directly from 209 the default look and feel. The resulting multiplexing UI is a small 210 delegate that obtains and maintains UIs from the default and auxiliary 211 look and feels. As a result, when a method is invoked in a multiplexing 212 UI object, the multiplexing UI invokes the same method on each 213 of the UIs obtained from the default and auxiliary look and feels. 214 </p> 215 216 <p> 217 <a id="howtowrite"></a> 218 <hr> 219 <h2>Tips for Writing an Auxiliary Look and Feel</h2> 220 221 <p> 222 An auxiliary look and feel is like any other look and feel, 223 except that it doesn't have to provide the complete support 224 that a default look and feel must. For 225 example, an auxiliary look and feel that supports just text-to-speech feedback 226 doesn't need to provide any code for painting. 227 Also, it might not need to support all components -- 228 <code>JSeparator</code>s, for example, might be ignored. 229 230 <p> 231 Auxiliary look and feels tend to be simple, 232 so developing one can be easier than developing a visual 233 look and feel. 234 The developer can concentrate solely 235 on providing the specialized functionality. 236 237 <p> 238 Because the primary purpose of an auxiliary look and feel is to enhance the 239 default look and feel, auxiliary look and feels tend 240 be nonvisual. Since an auxiliary look and feel is a genuine 241 look and feel, however, there is nothing to prevent it 242 from rendering information on the display. 243 </p> 244 245 <p> 246 Just like for any other look and feel, you 247 implement an auxiliary look and feel 248 by writing a subclass of <code>javax.swing.LookAndFeel</code> 249 and creating subclasses of the 250 <code><em>Foo</em>UI</code> classes defined in 251 the <code>javax.swing.plaf</code> package. 252 </p> 253 254 <a id="dosanddonts"> 255 <h3>Dos and Don'ts</h3> 256 </a> 257 258 <p> 259 The following paragraphs provide some general recommendations for developing 260 auxiliary look and feels. 261 </p> 262 263 <p> 264 <h4>Use the <code>installUI</code> method 265 to perform all initialization, 266 and the <code>uninstallUI</code> method 267 to perform all cleanup.</h4> 268 269 <blockquote> 270 The <code>installUI</code> and <code>uninstallUI</code> 271 methods are invoked when a component's look and feel is set. 272 The <code>installUI</code> method gives the new UI object 273 a chance to add listeners on the component and its data model. 274 Similarly, the <code>uninstallUI</code> method 275 lets the previous UI object remove its listeners. 276 </blockquote> 277 <h4><b>Don't extend visual look and feels.</b></h4> 278 <blockquote> 279 We recommended that you <i>don't</i> implement 280 UI classes of an auxiliary look and feel as subclasses of the 281 UI classes of a visual look and feel. Why not? Because they might 282 accidentally inherit code that installs listeners on a component 283 object or renders the component on the display. As a result, 284 your auxiliary look and feel would compete with the default look 285 and feel rather than cooperating with it.<br> 286 <br> 287 Instead, we recommend that the UI classes of an auxiliary look 288 and feel directly extend the abstract UI classes in the <code>javax.swing.plaf</code> 289 package. By using this strategy, the developer of an auxiliary 290 look and feel can avoid competing with the default look and feel. 291 </blockquote> 292 <h4><b>Override all UI-specific methods your UI classes inherit.</b></h4> 293 294 <blockquote> 295 We recommend that each UI class of 296 an auxiliary look and feel override the methods 297 defined in the <code>javax.swing.plaf</code> 298 UI classes it descends from 299 The reasons for this recommendation are similar 300 to those for not extending a visual look and feel. 301 For example, the <code>ComponentUI</code> 302 class, from which all UI classes descend, 303 provides a default implementation for the <code>update</code> 304 method. This default implementation paints on the display 305 if the 306 component is opaque. If a UI class from a non-visual auxiliary 307 look and feel does not override this method, all 308 opaque components appear as blank areas on the screen! 309 </blockquote> 310 311 <a id="uidefaults"></a> 312 <h3>Extending UIDefaults</h3> 313 314 <p>In many cases, you 315 might want an auxiliary look and feel to be "incomplete." That 316 is, you might not need to support the complete set 317 of components. 318 For example, an auxiliary look and feel might choose 319 to provide a <code>ButtonUI</code> subclass but no 320 <code>LabelUI</code> subclass. 321 This 322 option is allowed, and the multiplexing look and feel gracefully 323 handles such situations.</p> 324 <p>By default, however, Swing issues an error message when it asks 325 a look and feel for a UI object and the look and feel does not 326 support that UI. This message can be annoying, especially to auxiliary 327 look-and-feel developers who don't want to support a particular 328 component.</p> 329 <p>Fortunately, you can prevent this error 330 message by creating a subclass of the <code>UIDefaults</code> 331 class and returning an instance of it from the 332 <code>getDefaults</code> method 333 of your <code>LookAndFeel</code> class. 334 For example: 335 </p> 336 <p><code>public class MyAuxLookAndFeel 337 extends LookAndFeel {<br> 338 ...<br> 339 public UIDefaults getDefaults() {<br> 340 <b>UIDefaults table = <br> 341 342 new MyAuxUIDefaults();<br> 343 </b> Object[] uiDefaults = {<br> 344 "ButtonUI", "MyAuxButtonUI",<br> 345 ...<br> 346 }<br> 347 table.putDefaults(uiDefaults);<br> 348 return table;<br> 349 }<br> 350 }<br> 351 <br> 352 <b>class MyAuxUIDefaults extends UIDefaults {<br> 353 protected void getUIError(String msg) {<br> 354 //System.err.println<br> 355 // ("An 356 annoying message!");<br> 357 }<br> 358 }</b></code></p> 359 360 <p> 361 In the preceding example, an auxiliary look and feel named <code>MyAux</code> 362 creates a <code>UIDefaults</code> subclass 363 that overrides the <code>getUIError</code> 364 method. The <code>getUIError</code> 365 method is the method that is invoked when Swing cannot find a UI 366 object in a look and feel. By merely doing nothing in this method, 367 you can avoid the error message.</p> 368 <p> 369 370 <a id="defaultui"></a> 371 <h3>Examining Other UI Objects</h3> 372 373 <p>In 374 rare instances, a UI object from an auxiliary look and feel 375 may be interested in the default UI object used by the component. In 376 these cases, the UI object from auxiliary look and feel can obtain 377 the UI from a component by calling its <code>getUI</code> 378 method. The returned UI is an instance of one of the multiplexing 379 look and feel UI classes (for example, <code>MultiButtonUI</code>). 380 The UI object from the auxiliary look and feel can call the <code>getUIs</code> 381 method of the returned object to obtain an array containing a complete list 382 of all UI objects handled by the multiplexing UI. The first element 383 is guaranteed to be the UI created from the default look and feel. 384 </p> 385 386 <p> 387 <a id="implementation"></a> 388 <hr> 389 <h2>How the Multiplexing Look and Feel Is Implemented</h2> 390 391 <p> 392 The Multiplexing look and feel 393 (represented by 394 <code>javax.swing.plaf.multi.MultiLookAndFeel</code>) 395 is meant to be transparent to 396 all developers and users. It should "just work" -- and 397 it is used only when the user tells Swing to use an auxiliary look 398 and feel.</p> 399 400 <p> 401 When the Multiplexing look and 402 feel is in use, the type of the UI object 403 associated with each component 404 depends on whether 405 any of the auxiliary look and feels currently in use 406 support the component. 407 If so, the component's UI object is 408 an instance of a multiplexing UI. 409 If only the default look and feel supports the component, 410 then the component gets 411 a UI object from the default look and feel, 412 just as if no auxiliary look and feels were installed. 413 414 <p> 415 A multiplexing UI object 416 obtains and maintains UI objects 417 from the default and auxiliary look 418 and feels, 419 referring to these UIs in the following manner: 420 421 <ul> 422 <li> The UI object from the default look 423 and feel is always the first to be created. After that, a UI object 424 is created from each auxiliary look and feel in the order 425 they are specified in the <code>swing.auxiliarylaf</code> 426 property.<br><br></li> 427 428 <li> When a method that requests information 429 from a UI object is invoked, the multiplexing UI object 430 invokes the method on all the UI objects, but returns 431 only the results from the UI for the default look and feel. 432 For example, when the <code>getPreferredSize</code> 433 method is invoked on a multiplexing UI, the UI returns only the 434 results of invoking <code>getPreferredSize</code> 435 on the UI obtained from the default look and feel. 436 The <code>getPreferredSize</code> method 437 is also invoked on the UI object for each auxiliary look and feel, 438 but the return values are ignored. 439 <br><br></li> 440 441 <li> When a method that does not request information 443 invokes that method on all UIs -- 444 on the UI object obtained from the default look 445 and feel 446 and on all the UIs obtained from the auxiliary look and feels, 447 as well. 448 For example, invoking the <code>installUI</code> 449 method on a multiplexing UI causes the multiplexing UI to invoke 450 <code>installUI</code> 451 on the UI obtained from the default look and feel and the UIs obtained from 452 the auxiliary factories.</li> 453 </ul> 454 <p> In all cases, the UI object obtained from 455 the default look and feel is acted upon first, and then the auxiliary 456 look and feels are acted upon in the order they are specified in 457 the <code>swing.auxiliarylaf</code> 458 property. 459 </p> 460 461 <p> 462 463 <a id="custom"></a> 464 <hr> 465 <h2>How to Provide a Custom Multiplexing Look and Feel</h2> 466 467 <p>While 468 we hope the behavior of the Multiplexing look and feel is 469 flexible enough not to require an alternative multiplexing look 470 and feel, Swing allows the user to specify another multiplexing look 471 and feel to use. 472 </p> 473 474 <p> To do that, all the user has to do is modify 475 the <code>$JDKHOME/conf/swing.properties</code> 476 file to include a definition of the <code>swing.plaf.multiplexinglaf</code> 477 property. Swing then treats the <code>swing.plaf.multiplexinglaf</code> 478 property as a <code>LookAndFeel</code> 479 subclass that supports multiplexing. 480 </p> 481 <p> For example, if a user has a multiplexing 482 look and feel represented by <code>com.myco.SuperMultiLookAndFeel</code> 483 that is a better match for their needs than the Multiplexing 484 look and feel 485 (<code>javax.swing.plaf.multi.MultiLookAndFeel</code>), 486 the user could include the following line in <code>$JDKHOME/conf/swing.properties</code>: 487 </p> 488 489 <p> 490 <code>swing.plaf.multiplexinglaf = com.myco.SuperMultiLookAndFeel</code> 491 </p> 492 493 <p> 494 This statement instructs Swing to use <code>com.myco.SuperMultiLookAndFeel</code> 495 instead of <code>javax.swing.plaf.multi.MultiLookAndFeel</code>. But 496 if you use this kind of statement, be careful, because the suppliers 497 of auxiliary look and feels will most likely have developed and 498 tested against our Multiplexing look and feel. 499 </p> 500 501 </body> 502 </html> |