Article View: borland.public.jbuilder.java.swing
Article #8838Re: UIManager.setLookAndFeel(classname) problem
From: Gus Bellingham
Date: Mon, 17 Jul 2000 00:00
Date: Mon, 17 Jul 2000 00:00
353 lines
14060 bytes
14060 bytes
Hi Rich,
I found the bug in the 1.2 JDK that is responsible for my frustrating
attempts at loading a custom LookAndFeel :
http://developer.java.sun.com/developer/bugParade/bugs/4257902.html
The first workaround given in the bug database does not work, the whole
area of class loading is a horrible mess. Ever heard of the -Xbootclasspath:
runtime option ? Also the workarounds given won't work for Applets, the
only way to do this is to use the setUI( ) method on each JComponent with
your own custom ComponentUI.
My advice, don't even go near the javax.swing.plaf classes.
Thanks !
"Rich Wilkman" <richw@formlessvoid.com> wrote in message
news:396F1E50.F14D988B@formlessvoid.com...
> Gus:
>
> I can tell you that, for an Applet, it absolutly has to be done in the
> static initializer (you can see how JBuilder loads it by running the
> Applet Wizard). L&F loading is runtime, which means that compiler-like
> tools such as the Deployment Wizard will not find the classes for you.
> Are you sure that the classes are in your archive (and that the archive
> statement is in the applet html)?
>
> What's the full error in the Java Console (after you switch back to the
> static initializer)?
>
> -Rich
>
> Gus Bellingham wrote:
> >
> > Hi,
> > this is about plugging in a custom LookAndFeel in Swing - newbies
> > beware!
> > I've been trying to install a custom LookAndFeel class (source shown
at
> > bottom), and crazy things are going on. I've tried everything I can
think
> > of. You are supposed to be able to call
> > UIManager.setLookAndFeel("com.spiritone.gus.swing.ShadowLookAndFeel");
> > with the full qualified class name, but it just fails with a
> > ClassNotFoundException, which is crazy because, I know for a fact the
class
> > files are in the right place (relative to the CLASSPATH), I can load
them ok
> > with Class.forName() in the very code block.
> > I've tried the other form of the UIManager.setLookAndFeel( ) method,
> > passing in an instance of the LookAndFeel, and that works UNTIL you try
to
> > instantiate a Swing component, then the getUI( ) method fails, with a
> > ClassNotFoundException on the ShadowButtonUI class, which is also
there, in
> > the correct place, and which I can instantiate and test, without going
> > through UIManager !
> > I've tried this in a static { } initializer, in the init( ) method,
in
> > the main( ) method of an Application, they all fail in the same way.
Its
> > driving me nuts ! Any bright ideas are very gratefully accepted
> > mailto:gus@spiritone.com Thanks !
> >
> > Here's the Swing JApplet :
> > package JButton;
> >
> > import java.awt.*;
> > import java.awt.event.*;
> > import java.applet.*;
> > import javax.swing.*;
> > import javax.swing.plaf.*;
> > import com.spiritone.gus.swing.*;
> >
> > public class Applet2 extends JApplet {
> > boolean isStandalone = false;
> > JPanel jPanel1 = new JPanel();
> > JButton jButton1;
> > file://Pluggable LookAndFeel classes and ComponentUI
> > ButtonUI ui;
> > private static Class lnfClass, uiClass;
> >
> > FlowLayout flowLayout1 = new FlowLayout();
> >
> > file://Initialize the applet
> > public void init() {
> > try {
> > System.out.println("Applet2 Setting Look & Feel:");
> >
file://UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
> >
> >
file://UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassNa
me())
> > ;
> >
> > /* I get a ClassNotFound Exception here !
> > * This sucks, because I've successfully loaded the class already
with
> > Class.forName() above ?
> > *
> > UIManager.setLookAndFeel("com.spiritone.gus.swing.ShadowLookAndFeel");
> > */
> >
> > /* This one works, until a JButton is instantiated, it fails to
load
> > the ButtonUI class:
> > * UIDefaults.getUI() failed: no ComponentUI class for:
> > javax.swing.JButton (see below)
> > */
> > UIManager.setLookAndFeel((LookAndFeel)(lnfClass.newInstance()));
> > System.out.println("UIManager L&F=" +
> > UIManager.getLookAndFeel().getDescription());
> > uiClass =
> > Class.forName(UIManager.getDefaults().getString("ButtonUI"));
> > System.out.println("ButtonUI Class loaded OK =" +
uiClass.getName());
> >
> > }
> > catch (ClassNotFoundException e1) {
> > System.out.println("LookAndFeel : class notfound");
> > e1.printStackTrace(System.out);
> > }
> > catch (Exception e2) {
> > System.out.println("LookAndFeel : unavailable");
> > e2.printStackTrace(System.out);
> > }
> >
> > try {
> > jbInit();
> > }
> > catch(Exception e3) {
> > e3.printStackTrace();
> > }
> > }
> >
> > file://Component initialization
> > private void jbInit() throws Exception {
> > System.out.println("Applet2 CodeBase=" + getCodeBase());
> > file://this.setSize(new Dimension(300, 100));
> > System.out.println("About to create JButton");
> > jButton1 = new JButton();
> > jButton1.setText("Shadow JButton");
> > System.out.println("UIDefaults getUI for JButton=" +
> > UIManager.getDefaults().getUI(jButton1));
> > /* Test the ShadowButtonUI without loading the whole LookAndFeel -
works
> > fine!
> > * ui = (ButtonUI)ShadowButtonUI.createUI(jButton1);
> > * jButton1.setUI(ui);
> > */
> >
> > jPanel1.setLayout(flowLayout1);
> > jPanel1.setBackground(Color.white);
> > this.getContentPane().add(jPanel1, BorderLayout.CENTER);
> > jPanel1.add(jButton1, null);
> > }
> >
> > file://Get Applet information
> > public String getAppletInfo() {
> > return "ShadowLookAndFeel Button Applet";
> > }
> >
> > file://static initializer for setting look & feel
> > static {
> > // LookAndFeel Class Loaded OK here
> > try {
> > lnfClass =
Class.forName("com.spiritone.gus.swing.ShadowLookAndFeel");
> > if (lnfClass != null) {
> > System.out.println("L&F Class loaded OK =" +
lnfClass.getName());
> > }
> > }
> > catch (ClassNotFoundException e1) {
> > System.out.println("LookAndFeel : class notfound");
> > e1.printStackTrace(System.out);
> > }
> > catch (Exception e2) {
> > System.out.println("LookAndFeel : unavailable");
> > e2.printStackTrace(System.out);
> > }
> > }
> > }
> >
> > Here's the problem (this is running under Appletviewer and JDK 1.2):
> >
> >
C:\JBUILDER3\java\bin\AppletViewer.exe -J-Djava.security.policy=C:\JBUILDER3
> >
\lib\appletviewer.policy -J-Djava.class.path=C:\JBuilder3\myclasses;C:\JBUIL
> >
DER3\lib\dx3.0.jar;C:\JBUILDER3\lib\dx3.0-res.jar;C:\JBUILDER3\lib\jbcl3.0.j
> >
ar;C:\JBUILDER3\lib\jbcl3.0-res.jar;C:\JBUILDER3\lib\jgl3.1.0.jar;C:\JBUILDE
> >
R3\lib\dbswing3.0.jar;C:\JBUILDER3\lib\dbswing3.0-res.jar;C:\JBUILDER3\java\
> >
lib\jdkdep.jar;C:\JBUILDER3\java\jre\lib\rt.jar;C:\JBUILDER3\java\lib\dt.jar
> > ;C:\JBUILDER3\java\jre\lib\i18n.jar;C:\JBUILDER3\java\lib\tools.jar
> > C:\JBuilder3\myclasses\JButton.Applet2.html
> > AppAccelerator(tm) 1.2.010 for Java (JDK 1.2), x86 version.
> > Copyright (c) 1997-1999 Inprise Corporation. All Rights Reserved.
> > L&F Class loaded OK =com.spiritone.gus.swing.ShadowLookAndFeel
> > Applet2 Setting Look & Feel:
> > UIManager L&F=Components with offset shadows
> > ButtonUI Class loaded OK =com.spiritone.gus.swing.ShadowButtonUI
> > Applet2 CodeBase=file:/C:/JBuilder3/myclasses/
> > About to create JButton
> > UIDefaults.getUI() failed: no ComponentUI class for:
> >
javax.swing.JButton[,0,0,0x0,invalid,layout=javax.swing.OverlayLayout,alignm
> >
entX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferre
> >
dSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=null,paintBor
> >
der=true,paintFocus=true,pressedIcon=,rolloverEnabled=false,rolloverIcon=,ro
> > lloverSelectedIcon=,selectedIcon=,text=,defaultCapable=true]
> > java.lang.Error
> > at javax.swing.UIDefaults.getUIError(UIDefaults.java:351)
> > at javax.swing.UIDefaults.getUI(Compiled Code)
> > at javax.swing.UIManager.getUI(Compiled Code)
> > at javax.swing.JButton.updateUI(JButton.java:115)
> > at javax.swing.AbstractButton.init(AbstractButton.java:1196)
> > at javax.swing.JButton.<init>(JButton.java:105)
> > at javax.swing.JButton.<init>(JButton.java:73)
> > at JButton.Applet2.jbInit(Applet2.java:71)
> > at JButton.Applet2.init(Applet2.java:59)
> > at sun.applet.AppletPanel.run(Compiled Code)
> > at java.lang.Thread.run(Compiled Code)
> > UIDefaults getUI for JButton=null
> >
> > It's the same if I run it in a Browser IE5 with the JRE 1.3 plugin:
> > Java(TM) Plug-in: Version 1.3.0-C Using JRE version 1.3.0 Java
HotSpot(TM)
> > Client VM
> > User home directory = C:\WINDOWS Proxy Configuration: no proxy JAR
cache
> > enabled.
> > L&F Class loaded OK =com.spiritone.gus.swing.ShadowLookAndFeel
> > Applet2 Setting Look & Feel:
> > UIManager L&F=Components with offset shadows
> > ButtonUI Class loaded OK =com.spiritone.gus.swing.ShadowButtonUI
> > Applet2 CodeBase=file:/C:/JBuilder3/myclasses/
> > About to create JButton
> > UIDefaults.getUI() failed: no ComponentUI class for:
> >
javax.swing.JButton[,0,0,0x0,invalid,layout=javax.swing.OverlayLayout,alignm
> >
entX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferre
> >
dSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=null,paintBor
> >
der=true,paintFocus=true,pressedIcon=,rolloverEnabled=false,rolloverIcon=,ro
> > lloverSelectedIcon=,selectedIcon=,text=,defaultCapable=true]
> > java.lang.Error
> > at javax.swing.UIDefaults.getUIError(Unknown Source)
> > at javax.swing.UIDefaults.getUI(Unknown Source)
> > at javax.swing.UIManager.getUI(Unknown Source)
> > at javax.swing.JButton.updateUI(Unknown Source)
> > at javax.swing.AbstractButton.init(Unknown Source)
> > at javax.swing.JButton.<init>(Unknown Source)
> > at javax.swing.JButton.<init>(Unknown Source)
> > at JButton.Applet2.jbInit(Applet2.java:71)
> > at JButton.Applet2.init(Applet2.java:59)
> > at sun.applet.AppletPanel.run(Unknown Source)
> > at java.lang.Thread.run(Unknown Source)
> > UIDefaults.getUI() failed: no ComponentUI class for:
> >
javax.swing.JButton[,0,0,0x0,invalid,layout=javax.swing.OverlayLayout,alignm
> >
entX=0.0,alignmentY=0.5,border=,flags=0,maximumSize=,minimumSize=,preferredS
> >
ize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=null,paintBorde
> >
r=true,paintFocus=true,pressedIcon=,rolloverEnabled=false,rolloverIcon=,roll
> > overSelectedIcon=,selectedIcon=,text=Shadow JButton,defaultCapable=true]
> > java.lang.Error at javax.swing.UIDefaults.getUIError(Unknown Source)
at
> > javax.swing.UIDefaults.getUI(Unknown Source) at
> > JButton.Applet2.jbInit(Applet2.java:73) at
> > JButton.Applet2.init(Applet2.java:59) at
sun.applet.AppletPanel.run(Unknown
> > Source) at java.lang.Thread.run(Unknown Source)
> > UIDefaults getUI for JButton=null
> >
> > It's the same if I try it in the main( ) method of an Application:
> >
> > C:\JBUILDER3\java\bin\javaw.exe -classpath
> >
"C:\JBuilder3\myclasses;C:\JBUILDER3\lib\dx3.0.jar;C:\JBUILDER3\lib\dx3.0-re
> >
s.jar;C:\JBUILDER3\lib\jbcl3.0.jar;C:\JBUILDER3\lib\jbcl3.0-res.jar;C:\JBUIL
> >
DER3\lib\jgl3.1.0.jar;C:\JBUILDER3\lib\dbswing3.0.jar;C:\JBUILDER3\lib\dbswi
> >
ng3.0-res.jar;C:\JBUILDER3\java\lib\jdkdep.jar;C:\JBUILDER3\java\jre\lib\rt.
> >
jar;C:\JBUILDER3\java\lib\dt.jar;C:\JBUILDER3\java\jre\lib\i18n.jar;C:\JBUIL
> > DER3\java\lib\tools.jar" JButton.Application2
> > AppAccelerator(tm) 1.2.010 for Java (JDK 1.2), x86 version.
> > Copyright (c) 1997-1999 Inprise Corporation. All Rights Reserved.
> > Loading LookAndFeel com.spiritone.gus.swing.ShadowLookAndFeel
> > LookAndFeel Unavailable:
> > java.lang.ClassNotFoundException:
com/spiritone/gus/swing/ShadowLookAndFeel
> > at java.lang.Class.forName0(Native Method)
> > at java.lang.Class.forName(Class.java:124)
> > at javax.swing.UIManager.setLookAndFeel(UIManager.java:365)
> > at JButton.Application2.main(Application2.java:25)
> >
> > Here's my custom LookAndFeel class, it's real simple :
> >
> > package com.spiritone.gus.swing;
> >
> > import javax.swing.UIDefaults;
> > import javax.swing.plaf.metal.MetalLookAndFeel;
> > import java.io.Serializable;
> >
> > public class ShadowLookAndFeel extends MetalLookAndFeel implements
> > Serializable {
> >
> > protected void initClassDefaults(UIDefaults table) {
> > super.initClassDefaults(table);
> > table.put ("ButtonUI", "com.spiritone.gus.swing.ShadowButtonUI");
> > }
> >
> > public String getID() {
> > return "Shadow";
> > }
> > public String getName() {
> > return "Shadow L&F";
> > }
> > public String getDescription() {
> > return "Components with offset shadows";
> > }
> >
> > public boolean isNativeLookAndFeel() {
> > return false;
> > };
> >
> > public boolean isSupportedLookAndFeel() {
> > return true;
> > };
> >
> > public void initialize() {
> > }
> > public void uninitialize() {
> > }
> > public String toString() {
> > return getName() + " : " + getClass().getName();
> > }
> > }
Technical Details
Message-ID:
<8l0nas$gbh9@bornews.borland.com>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailReferences:
<8kma7p$che4@bornews.borland.com> <396F1E50.F14D988B@formlessvoid.com>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 111d45,2ab3485866d84a01 X-Google-Attributes: gid111d45,public From: "Gus Bellingham" <gus@spiritone.com> Subject: Re: UIManager.setLookAndFeel(classname) problem Date: 2000/07/17 Message-ID: <8l0nas$gbh9@bornews.borland.com> X-Deja-AN: 647639553 References: <8kma7p$che4@bornews.borland.com> <396F1E50.F14D988B@formlessvoid.com> Organization: Another Netscape Collabra Server User X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6600 Newsgroups: borland.public.jbuilder.java.swing