Index: core/src/org/netbeans/core/NbTheme.java =================================================================== RCS file: /cvs/core/src/org/netbeans/core/NbTheme.java,v retrieving revision 1.5 diff -u -r1.5 NbTheme.java --- core/src/org/netbeans/core/NbTheme.java 17 Jan 2002 15:46:01 -0000 1.5 +++ core/src/org/netbeans/core/NbTheme.java 14 Jul 2002 16:11:45 -0000 @@ -18,119 +18,135 @@ import javax.swing.plaf.*; import javax.swing.plaf.metal.*; import org.openide.*; +import java.util.*; +/** An extension of javax.swing.plaf.metal.DefaultMetalTheme which can read a an xml + * file named themes.xml and apply the theme defined in XML. NbTheme + * stores its data in the UIDefaults instance available from the + * look-and-feel manager (UiManager.getLookAndFeel.getDefaults()). + * These means that theme files may also override per-component-type settings + * stored there, so changes to look and feel deeper than those afforded by the + * MetalTheme parent class are possible. + *

+ * NbTheme supports five kinds of data: Colors, Fonts, Integers, + * Strings, and Booleans, which are the major interesting data types typical + * stored in UIDefaults. */ public class NbTheme extends MetalTheme implements org.xml.sax.DocumentHandler { - public static final String THEMEFILE_NAME = "Themes.xml"; // NOI18N - - private static final String MAIN_TAG = "MetalTheme"; // NOI18N - private static final String MAIN_ACTIVATE_TAG = "activate"; // NOI18N - private static final String THEME_TAG = "Theme"; // NOI18N - private static final String THEME_NAME_TAG = "name"; // NOI18N - - private static final String R_TAG = "R"; // NOI18N - private static final String G_TAG = "G"; // NOI18N - private static final String B_TAG = "B"; // NOI18N - private static final String PRIMARY1_TAG = "primary1"; // NOI18N - private static final String PRIMARY2_TAG = "primary2"; // NOI18N - private static final String PRIMARY3_TAG = "primary3"; // NOI18N - private static final String SECONDARY1_TAG = "secondary1"; // NOI18N - private static final String SECONDARY2_TAG = "secondary2"; // NOI18N - private static final String SECONDARY3_TAG = "secondary3"; // NOI18N - - private static final String FONTNAME_TAG = "name"; // NOI18N - private static final String FONTSTYLE_TAG = "style"; // NOI18N - private static final String FONTSTYLE_PLAIN = "Plain"; // NOI18N - private static final String FONTSTYLE_BOLD = "Bold"; // NOI18N - private static final String FONTSTYLE_ITALIC = "Italic"; // NOI18N - private static final String FONTSIZE_TAG = "size"; // NOI18N - private static final String CONTROLFONT_TAG = "controlFont"; // NOI18N - private static final String SYSTEMFONT_TAG = "systemFont"; // NOI18N - private static final String USERFONT_TAG = "userFont"; // NOI18N - private static final String SUBFONT_TAG = "subFont"; // NOI18N - private static final String MENUFONT_TAG = "menuFont"; // NOI18N - private static final String WINDOWTITLEFONT_TAG = "windowTitleFont"; // NOI18N - - - // default Theme - private ColorUIResource primary1 = new ColorUIResource(102, 102, 153); - private ColorUIResource primary2 = new ColorUIResource(153, 153, 204); - private ColorUIResource primary3 = new ColorUIResource(204, 204, 255); - - private ColorUIResource secondary1 = new ColorUIResource(102, 102, 102); - private ColorUIResource secondary2 = new ColorUIResource(153, 153, 153); - private ColorUIResource secondary3 = new ColorUIResource(204, 204, 204); - - private FontUIResource controlFont; - private FontUIResource systemFont; - private FontUIResource userFont; - private FontUIResource subFont; - private FontUIResource menuFont; - private FontUIResource windowTitleFont; - - private String activeTag=""; // NOI18N - private boolean activeTagFlag=false; - - public String getName(){ return "NetBeans"; } // NOI18N - - /** Creates new NBTheme */ + public static final String THEMEFILE_NAME = "themes.xml"; // NOI18N + // legal xml tags for theme files + private static final String THEMESET_TAG = "themeset"; // NOI18N + private static final String ACTIVE_ATTR = "active"; // NOI18N + private static final String THEME_TAG = "theme"; // NOI18N + private static final String BOOL_TAG = "boolean"; // NOI18N + private static final String DIM_TAG = "dimension"; // NOI18N + private static final String FONT_TAG = "font"; // NOI18N + private static final String INSETS_TAG = "insets"; // NOI18N + // attributes recognized in various tags + private static final String COLOR_ATTR = "color"; // NOI18N + private static final String KEY_ATTR = "key"; // NOI18N + private static final String METRIC_TAG = "metric"; // NOI18N + private static final String STRING_TAG = "string"; // NOI18N + private static final String NAME_ATTR = "name"; // NOI18N + private static final String FONTSTYLE_ATTR = "style"; // NOI18N + private static final String FONTSIZE_ATTR = "size"; // NOI18N + private static final String VALUE_ATTR = "value"; + private static final String WIDTH_ATTR = "width"; + private static final String HEIGHT_ATTR = "height"; + private static final String RED_ATTR = "r"; // NOI18N + private static final String GREEN_ATTR = "g"; // NOI18N + private static final String BLUE_ATTR = "b"; // NOI18N + private static final String LEFT_ATTR = "left"; // NOI18N + private static final String TOP_ATTR = "top"; // NOI18N + private static final String RIGHT_ATTR = "right"; // NOI18N + private static final String BOTTOM_ATTR = "bottom"; // NOI18N + // font styles + private static final String FONTSTYLE_PLAIN = "plain"; // NOI18N + private static final String FONTSTYLE_BOLD = "bold"; // NOI18N + private static final String FONTSTYLE_ITALIC = "italic"; // NOI18N + // keys used to store theme values in UIDefaults + private static final String CONTROLFONT = "controlFont"; // NOI18N + private static final String SYSTEMFONT = "systemFont"; // NOI18N + private static final String USERFONT = "userFont"; // NOI18N + private static final String MENUFONT = "menuFont"; // NOI18N + private static final String WINDOWTITLEFONT = "windowTitleFont"; // NOI18N + private static final String SUBFONT = "subFont"; // NOI18N + private static final String PRIMARY1 = "primary1"; // NOI18N + private static final String PRIMARY2 = "primary2"; // NOI18N + private static final String PRIMARY3 = "primary3"; // NOI18N + private static final String SECONDARY1 = "secondary1"; // NOI18N + private static final String SECONDARY2 = "secondary2"; // NOI18N + private static final String SECONDARY3 = "secondary3"; // NOI18N + private static final String WHITE = "white"; // NOI18N + private static final String BLACK = "black"; // NOI18N + + private HashSet activeThemes=null; + private boolean inActiveTheme=false; + + private UIDefaults defaults; + public String getName(){ return "NetBeans XML Theme"; } // NOI18N + /** Create a new instance of NBTheme */ public NbTheme() { - try{ - controlFont = new FontUIResource(new Font("Dialog", Font.PLAIN, 11)); // NOI18N - systemFont = new FontUIResource(new Font("Dialog", Font.PLAIN, 11)); // NOI18N - userFont = new FontUIResource(new Font("Dialog", Font.PLAIN, 11)); // NOI18N - menuFont = new FontUIResource(new Font("Dialog", Font.PLAIN, 11)); // NOI18N - windowTitleFont = new FontUIResource(new Font("Dialog", Font.PLAIN, 11)); // NOI18N - subFont = new FontUIResource(new Font("Dialog", Font.PLAIN, 10)); // NOI18N - UIManager.getDefaults ().put ("List.font", controlFont); // NOI18N - UIManager.getDefaults ().put ("Tree.font", controlFont); // NOI18N - UIManager.getDefaults ().put ("Panel.font", controlFont); // NOI18N - } catch (Exception e){ - ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, e); - } + defaults = UIManager.getDefaults(); //cache to avoid overhead + addCustomDefaults (); parseTheme(); } - protected ColorUIResource getPrimary1() { return primary1; } - protected ColorUIResource getPrimary2() { return primary2; } - protected ColorUIResource getPrimary3() { return primary3; } - - protected ColorUIResource getSecondary1() { return secondary1; } - protected ColorUIResource getSecondary2() { return secondary2; } - protected ColorUIResource getSecondary3() { return secondary3; } - - public FontUIResource getControlTextFont() { return controlFont; } - public FontUIResource getSystemTextFont() { return systemFont; } - public FontUIResource getUserTextFont() { return userFont; } - public FontUIResource getMenuTextFont() { return menuFont; } - public FontUIResource getWindowTitleFont() { return windowTitleFont; } - public FontUIResource getSubTextFont() { return subFont; } + private void addCustomDefaults () { + //Note, all of this could be removed, and the themes file used + //for this job, but it does mean NetBeans would never start if + //the themes file was missing - primary1, etc. would produce an NPE + //when the UI calls them - Tim + defaults.put(PRIMARY1, new ColorUIResource(102, 102, 153)); // NOI18N + defaults.put(PRIMARY2, new ColorUIResource(153, 153, 204)); // NOI18N + defaults.put(PRIMARY3, new ColorUIResource(204, 204, 255)); // NOI18N + + defaults.put(SECONDARY1, new ColorUIResource(102, 102, 102)); // NOI18N + defaults.put(SECONDARY2, new ColorUIResource(153, 153, 153)); // NOI18N + defaults.put(SECONDARY3, new ColorUIResource(204, 204, 204)); // NOI18N + + defaults.put(WHITE, new ColorUIResource(255,255,255)); // NOI18N + defaults.put(BLACK, new ColorUIResource(0,0,0)); // NOI18N + + FontUIResource controlFont = new FontUIResource(new Font("Dialog", Font.PLAIN, 11)); + defaults.put(CONTROLFONT, controlFont); // NOI18N + defaults.put(SYSTEMFONT, controlFont); // NOI18N + defaults.put(USERFONT, controlFont); // NOI18N + defaults.put(MENUFONT, controlFont); // NOI18N + defaults.put(WINDOWTITLEFONT, controlFont); // NOI18N + UIManager.getDefaults ().put ("List.font", controlFont); // NOI18N + UIManager.getDefaults ().put ("Tree.font", controlFont); // NOI18N + UIManager.getDefaults ().put ("Panel.font", controlFont); // NOI18N + + defaults.put(SUBFONT, new FontUIResource(new Font("Dialog", Font.PLAIN, 10))); // NOI18N + } private void parseTheme(){ - org.xml.sax.Parser p = org.openide.loaders.XMLDataObject.createParser(); p.setDocumentHandler(this); java.io.File f = new java.io.File(NonGui.getSystemDir() + java.io.File.separator + THEMEFILE_NAME); - java.io.Reader cs = null; - boolean useDefaults = false; - try{ - cs = new java.io.FileReader(f); + if (!f.exists()) { + return; + } + java.io.Reader fr = null; + try { + fr = new java.io.FileReader(f); } catch(java.io.FileNotFoundException e){ - useDefaults = true; + //should never happen + ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, e); } - if(!useDefaults){ - org.xml.sax.InputSource is = new org.xml.sax.InputSource(cs); - - try{ - p.parse(is); - } - catch(java.io.IOException ie){ - ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ie); - } - catch(org.xml.sax.SAXException se){ - ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, se); - } + org.xml.sax.InputSource is = new org.xml.sax.InputSource(fr); + try{ + p.parse(is); + activeThemes=null; //dispose of now useless hashtable + } + catch(java.io.IOException ie){ + ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ie); + } + catch(org.xml.sax.SAXException se){ + ErrorManager.getDefault().annotate(se, "Error parsing theme file"); //NOI18N + ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, se); } } @@ -141,89 +157,129 @@ } public void startElement(java.lang.String p1,org.xml.sax.AttributeList atts) throws org.xml.sax.SAXException { - int r = 0; - int g = 0; - int b = 0; - String fontname = null; - int fontstyle = 0; - int fontsize = 0; - - if(p1.equals(MAIN_TAG) && atts.getLength()==1 && atts.getName(0).equals(MAIN_ACTIVATE_TAG)) { - activeTag = atts.getValue(0); + //found the themeset? + if (p1.equals(THEMESET_TAG)) { + //break out the comma delimited list of active themes + //and stores them in activeThemes hashset + String themes = atts.getValue (ACTIVE_ATTR); + if (themes != null) { + StringTokenizer tok = new StringTokenizer (themes, ","); //NOI18N + activeThemes = new HashSet (tok.countTokens() + 1); + while (tok.hasMoreTokens()) { + activeThemes.add(tok.nextToken()); + } + } } else{ - if(p1.equals(THEME_TAG) && atts.getLength()==1 && atts.getName(0).equals(THEME_NAME_TAG) && atts.getValue(0).equals(activeTag)){ - activeTagFlag=true; - } - - if(activeTagFlag){ - for (int i = 0; i < atts.getLength(); i++) { - if(atts.getName(i).equals(R_TAG)){ - r = Integer.valueOf(atts.getValue(i)).intValue(); - } - if(atts.getName(i).equals(G_TAG)){ - g = Integer.valueOf(atts.getValue(i)).intValue(); - } - if(atts.getName(i).equals(B_TAG)){ - b = Integer.valueOf(atts.getValue(i)).intValue(); - } - if(atts.getName(i).equals(FONTNAME_TAG)){ - fontname = atts.getValue(i); - } - if(atts.getName(i).equals(FONTSTYLE_TAG)){ - if(atts.getValue(i).equals(FONTSTYLE_PLAIN)) fontstyle = Font.PLAIN; - if(atts.getValue(i).equals(FONTSTYLE_BOLD)) fontstyle = Font.BOLD; - if(atts.getValue(i).equals(FONTSTYLE_ITALIC)) fontstyle = Font.ITALIC; + if (p1.equals(THEME_TAG) && (activeThemes != null)) { + //see if the current theme is one of the active ones + String themeName = atts.getValue (NAME_ATTR); + inActiveTheme = activeThemes.contains(themeName); + } else { + if (inActiveTheme) { + if (p1.equals (COLOR_ATTR)) { + handleColor (atts); + return; } - if(atts.getName(i).equals(FONTSIZE_TAG)){ - fontsize = Integer.valueOf(atts.getValue(i)).intValue(); + if (p1.equals (FONT_TAG)) { + handleFont (atts); + return; + } + if (p1.equals (METRIC_TAG)) { + handleMetric (atts); + return; + } + if (p1.equals (STRING_TAG)) { + handleString (atts); + return; + } + if (p1.equals (INSETS_TAG)) { + handleInsets (atts); + return; + } + if (p1.equals (BOOL_TAG)) { + handleBool (atts); + return; + } + if (p1.equals (DIM_TAG)) { + handleDim (atts); } - } - - if(p1.equals(PRIMARY1_TAG)){ - primary1 = new ColorUIResource(r, g, b); - } - if(p1.equals(PRIMARY2_TAG)){ - primary2 = new ColorUIResource(r, g, b); - } - if(p1.equals(PRIMARY3_TAG)){ - primary3 = new ColorUIResource(r, g, b); - } - - if(p1.equals(SECONDARY1_TAG)){ - secondary1 = new ColorUIResource(r, g, b); - } - if(p1.equals(SECONDARY2_TAG)){ - secondary2 = new ColorUIResource(r, g, b); - } - if(p1.equals(SECONDARY3_TAG)){ - secondary3 = new ColorUIResource(r, g, b); - } - if(p1.equals(CONTROLFONT_TAG)){ - controlFont = new FontUIResource(new Font(fontname, fontstyle, fontsize)); - UIManager.getDefaults ().put ("List.font", controlFont); // NOI18N - UIManager.getDefaults ().put ("Tree.font", controlFont); // NOI18N - UIManager.getDefaults ().put ("Panel.font", controlFont); // NOI18N - } - if(p1.equals(SYSTEMFONT_TAG)){ - systemFont = new FontUIResource(new Font(fontname, fontstyle, fontsize)); - } - if(p1.equals(USERFONT_TAG)){ - userFont = new FontUIResource(new Font(fontname, fontstyle, fontsize)); - } - if(p1.equals(SUBFONT_TAG)){ - subFont = new FontUIResource(new Font(fontname, fontstyle, fontsize)); - } - if(p1.equals(MENUFONT_TAG)){ - menuFont = new FontUIResource(new Font(fontname, fontstyle, fontsize)); - } - if(p1.equals(WINDOWTITLEFONT_TAG)){ - windowTitleFont = new FontUIResource(new Font(fontname, fontstyle, fontsize)); } } } } + private final void handleFont (org.xml.sax.AttributeList atts) { + String key = atts.getValue (KEY_ATTR); + String fontname = atts.getValue (NAME_ATTR); + String fontstylename = atts.getValue (FONTSTYLE_ATTR); + int fontsize = intFromAttr (atts, FONTSIZE_ATTR); + int fontstyle = Font.PLAIN; + if(fontstylename.equals(FONTSTYLE_BOLD)) { + fontstyle = Font.BOLD; + } else { + if(fontstylename.equals(FONTSTYLE_ITALIC)) fontstyle = Font.ITALIC; + } + FontUIResource resource = new FontUIResource (fontname, fontstyle, fontsize); + defaults.put (key, resource); + } + + private final void handleColor (org.xml.sax.AttributeList atts) { + int r = intFromAttr (atts, RED_ATTR); + int g = intFromAttr (atts, GREEN_ATTR); + int b = intFromAttr (atts, BLUE_ATTR); + String key = atts.getValue(KEY_ATTR); + ColorUIResource resource = new ColorUIResource (r,g,b); + defaults.put (key, resource); + } + + private final void handleMetric (org.xml.sax.AttributeList atts) { + String key = atts.getValue(KEY_ATTR); + Integer resource = Integer.valueOf (atts.getValue(VALUE_ATTR)); + defaults.put (key, resource); + } + + private final void handleString (org.xml.sax.AttributeList atts) { + String key = atts.getValue (KEY_ATTR); + String resource = atts.getValue (VALUE_ATTR); + defaults.put (key, resource); + } + + private final void handleBool (org.xml.sax.AttributeList atts) { + String key = atts.getValue (KEY_ATTR); + Boolean resource = Boolean.valueOf (key); + defaults.put (key, resource); + } + + private final void handleDim (org.xml.sax.AttributeList atts) { + String key = atts.getValue (KEY_ATTR); + int width = intFromAttr (atts, WIDTH_ATTR); + int height = intFromAttr (atts, HEIGHT_ATTR); + DimensionUIResource resource = new DimensionUIResource (width, height); + defaults.put (key, resource); + } + + private final void handleInsets (org.xml.sax.AttributeList atts) { + String key = atts.getValue (KEY_ATTR); + int top = intFromAttr (atts, TOP_ATTR); + int left = intFromAttr (atts, LEFT_ATTR); + int bottom = intFromAttr (atts, RIGHT_ATTR); + int right = intFromAttr (atts, RIGHT_ATTR); + InsetsUIResource resource = new InsetsUIResource (top, left, bottom, + right); + defaults.put (key, resource); + } + + + private final int intFromAttr (final org.xml.sax.AttributeList atts, final String key) { + try { + return Integer.valueOf (atts.getValue (key)).intValue(); + } catch (NumberFormatException nfe) { + ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, nfe); + return 0; + } + } + public void characters(char[] p1,int p2,int p3) throws org.xml.sax.SAXException { } @@ -232,9 +288,8 @@ public void endElement(java.lang.String p1) throws org.xml.sax.SAXException { if(p1.equals(THEME_TAG)){ - activeTagFlag=false; + inActiveTheme=false; } - } public void ignorableWhitespace(char[] p1,int p2,int p3) throws org.xml.sax.SAXException { @@ -242,14 +297,28 @@ public void processingInstruction(java.lang.String p1,java.lang.String p2) throws org.xml.sax.SAXException { } + + private final ColorUIResource getColor(String key) { + return (ColorUIResource) defaults.get (key); + } + + private final FontUIResource getFont(String key) { + return (FontUIResource) defaults.get (key); + } + + public FontUIResource getControlTextFont() { return getFont (CONTROLFONT); } + public FontUIResource getSystemTextFont() { return getFont (SYSTEMFONT); } + public FontUIResource getUserTextFont() { return getFont (USERFONT); } + public FontUIResource getMenuTextFont() { return getFont (MENUFONT); } + public FontUIResource getWindowTitleFont() { return getFont (WINDOWTITLEFONT); } + public FontUIResource getSubTextFont() { return getFont (SUBFONT); } + protected ColorUIResource getPrimary1() { return getColor (PRIMARY1); } + protected ColorUIResource getPrimary2() { return getColor (PRIMARY2); } + protected ColorUIResource getPrimary3() { return getColor (PRIMARY3); } + protected ColorUIResource getSecondary1() { return getColor (SECONDARY1); } + protected ColorUIResource getSecondary2() { return getColor (SECONDARY2); } + protected ColorUIResource getSecondary3() { return getColor (SECONDARY3); } + protected ColorUIResource getWhite() { return getColor (WHITE); } + protected ColorUIResource getBlack() { return getColor (BLACK); } - /* - public ColorUIResource getSystemTextColor(){ return primary1; } - public ColorUIResource getControlTextColor(){ return primary1; } - public ColorUIResource getInactiveControlTextColor(){ return primary1; } - public ColorUIResource getInactiveSystemTextColor(){ return primary1; } - public ColorUIResource getUserTextColor(){ return primary1; } - public ColorUIResource getTextHighlightColor(){ return primary1; } - public ColorUIResource getHighlightedTextColor(){ return primary1; } - */ }