void testNames() { Color defaultColor = label.getBackground(); UIManager.put("\"BlueLabel\"[Enabled].background", new ColorUIResource(Color.BLUE)); UIManager.put("\"RedLabel\"[Enabled].background", new ColorUIResource(Color.RED)); nimbus.register(Region.LABEL, "\"BlueLabel\""); nimbus.register(Region.LABEL, "\"RedLabel\""); label.setName("BlueLabel"); check(Color.BLUE); label.setName("RedLabel"); check(Color.RED); // remove name, color goes back to default label.setName(null); check(defaultColor); }
private static void fixGtkPopupStyle() { if (!UIUtil.isUnderGTKLookAndFeel()) return; final SynthStyleFactory original = SynthLookAndFeel.getStyleFactory(); SynthLookAndFeel.setStyleFactory(new SynthStyleFactory() { @Override public SynthStyle getStyle(final JComponent c, final Region id) { final SynthStyle style = original.getStyle(c, id); if (id == Region.POPUP_MENU) { final Integer x = ReflectionUtil.getField(style.getClass(), style, int.class, "xThickness"); if (x != null && x == 0) { // workaround for Sun bug #6636964 ReflectionUtil.setField(style.getClass(), style, int.class, "xThickness", 1); ReflectionUtil.setField(style.getClass(), style, int.class, "yThickness", 3); } } return style; } }); new JBPopupMenu(); // invokes updateUI() -> updateStyle() SynthLookAndFeel.setStyleFactory(original); }
private static void patchGtkDefaults(UIDefaults defaults) { if (!UIUtil.isUnderGTKLookAndFeel()) return; Map<String, Icon> map = ContainerUtil.newHashMap( Arrays.asList("OptionPane.errorIcon", "OptionPane.informationIcon", "OptionPane.warningIcon", "OptionPane.questionIcon"), Arrays.asList(AllIcons.General.ErrorDialog, AllIcons.General.InformationDialog, AllIcons.General.WarningDialog, AllIcons.General.QuestionDialog)); // GTK+ L&F keeps icons hidden in style SynthStyle style = SynthLookAndFeel.getStyle(new JOptionPane(""), Region.DESKTOP_ICON); for (String key : map.keySet()) { if (defaults.get(key) != null) continue; Object icon = style == null ? null : style.get(null, key); defaults.put(key, icon instanceof Icon ? icon : map.get(key)); } Color fg = defaults.getColor("Label.foreground"); Color bg = defaults.getColor("Label.background"); if (fg != null && bg != null) { defaults.put("Label.disabledForeground", UIUtil.mix(fg, bg, 0.5)); } }
/** * Called by UIManager when this look and feel is installed. */ @Override public void initialize() { super.initialize(); // create synth style factory setStyleFactory(new SynthStyleFactory() { @Override public SynthStyle getStyle(JComponent c, Region r) { SynthStyle style = getSeaGlassStyle(c, r); if (!(style instanceof SeaGlassStyle)) { style = new SeaGlassStyleWrapper(style); } return style; } }); }
protected void uninstallDefaults() { SeaGlassContext context = getContext(slider, ENABLED); style.uninstallDefaults(context); context.dispose(); style = null; context = getContext(slider, Region.SLIDER_TRACK, ENABLED); sliderTrackStyle.uninstallDefaults(context); context.dispose(); sliderTrackStyle = null; context = getContext(slider, Region.SLIDER_THUMB, ENABLED); sliderThumbStyle.uninstallDefaults(context); context.dispose(); sliderThumbStyle = null; }
private void updateStyle(JToolBar c) { SeaGlassContext context = getContext(c, Region.TOOL_BAR_CONTENT, null, ENABLED); contentStyle = SeaGlassLookAndFeel.updateStyle(context, this); context.getComponent().setOpaque(false); context.dispose(); context = getContext(c, Region.TOOL_BAR_DRAG_WINDOW, null, ENABLED); context.getComponent().setOpaque(false); dragWindowStyle = SeaGlassLookAndFeel.updateStyle(context, this); context.dispose(); context = getContext(c, ENABLED); context.getComponent().setOpaque(false); SynthStyle oldStyle = style; style = SeaGlassLookAndFeel.updateStyle(context, this); if (oldStyle != style) { handleIcon = style.getIcon(context, "ToolBar.handleIcon"); if (oldStyle != null) { uninstallKeyboardActions(); installKeyboardActions(); } } context.dispose(); }
@Override protected void uninstallDefaults() { SeaGlassContext context = getContext(toolBar, ENABLED); style.uninstallDefaults(context); context.dispose(); style = null; handleIcon = null; context = getContext(toolBar, Region.TOOL_BAR_CONTENT, contentStyle, ENABLED); contentStyle.uninstallDefaults(context); context.dispose(); contentStyle = null; context = getContext(toolBar, Region.TOOL_BAR_DRAG_WINDOW, dragWindowStyle, ENABLED); dragWindowStyle.uninstallDefaults(context); context.dispose(); dragWindowStyle = null; toolBar.setLayout(null); }
/** * DOCUMENT ME! * * @param g DOCUMENT ME! * @param c DOCUMENT ME! * @param region DOCUMENT ME! */ protected void paintSearchButton(Graphics g, JTextComponent c, Region region) { Rectangle bounds; if (region == SeaGlassRegion.SEARCH_FIELD_FIND_BUTTON) { bounds = getFindButtonBounds(); } else { bounds = getCancelButtonBounds(); } SeaGlassContext subcontext = getContext(c, region); SeaGlassLookAndFeel.updateSubregion(subcontext, g, bounds); SeaGlassSynthPainterImpl painter = (SeaGlassSynthPainterImpl) subcontext.getPainter(); painter.paintSearchButtonForeground(subcontext, g, bounds.x, bounds.y, bounds.width, bounds.height); subcontext.dispose(); }
/** * Create a SynthContext for the component, subregion, and state. * * @param c the component. * @param subregion the subregion. * @param state the state. * * @return the newly created SynthContext. */ private SeaGlassContext getContext(JComponent c, Region subregion, int state) { SynthStyle style = null; Class klass = SeaGlassContext.class; if (subregion == Region.TABBED_PANE_TAB) { style = tabStyle; } else if (subregion == Region.TABBED_PANE_TAB_AREA) { style = tabAreaStyle; } else if (subregion == Region.TABBED_PANE_CONTENT) { style = tabContentStyle; } else if (subregion == SeaGlassRegion.TABBED_PANE_TAB_CLOSE_BUTTON) { style = tabCloseStyle; } return SeaGlassContext.getContext(klass, c, subregion, style, state); }
protected void uninstallDefaults() { SeaGlassContext context = getContext(scrollbar, ENABLED); style.uninstallDefaults(context); context.dispose(); style = null; context = getContext(scrollbar, Region.SCROLL_BAR_TRACK, ENABLED); trackStyle.uninstallDefaults(context); context.dispose(); trackStyle = null; context = getContext(scrollbar, Region.SCROLL_BAR_THUMB, ENABLED); thumbStyle.uninstallDefaults(context); context.dispose(); thumbStyle = null; context = getContext(scrollbar, SeaGlassRegion.SCROLL_BAR_CAP, ENABLED); capStyle.uninstallDefaults(context); context.dispose(); capStyle = null; super.uninstallDefaults(); }
/** * @inheritDoc */ @Override protected void uninstallDefaults() { SeaGlassContext context = getContext(tree, ENABLED); style.uninstallDefaults(context); context.dispose(); style = null; context = getContext(tree, Region.TREE_CELL, ENABLED); cellStyle.uninstallDefaults(context); context.dispose(); cellStyle = null; if (tree.getTransferHandler() instanceof UIResource) { tree.setTransferHandler(null); } }
/** * Creates a SeaGlassContext with the specified values. This is meant for * subclasses and custom UI implementors. You very rarely need to construct * a SeaGlassContext, though some methods will take one. * * @param component JComponent * @param region Identifies the portion of the JComponent * @param style Style associated with the component * @param state State of the component as defined in SynthConstants. */ public SeaGlassContext(JComponent component, Region region, SynthStyle style, int state) { super(component, region, style, state); if (component == fakeComponent) { this.component = null; this.region = null; this.style = null; return; } if (component == null || region == null || style == null) { throw new NullPointerException("You must supply a non-null component, region and style"); } reset(component, region, style, state); }
/** * @see javax.swing.plaf.basic.BasicSplitPaneDivider#paint(java.awt.Graphics) */ public void paint(Graphics g) { Graphics g2 = g.create(); SeaGlassContext context = ((SeaGlassSplitPaneUI) splitPaneUI).getContext(splitPane, Region.SPLIT_PANE_DIVIDER); Rectangle bounds = getBounds(); bounds.x = bounds.y = 0; SeaGlassLookAndFeel.updateSubregion(context, g, bounds); context.getPainter().paintSplitPaneDividerBackground(context, g, 0, 0, bounds.width, bounds.height, splitPane.getOrientation()); context.getPainter().paintSplitPaneDividerForeground(context, g, 0, 0, getWidth(), getHeight(), splitPane.getOrientation()); context.dispose(); // super.paint(g2); for (int counter = 0; counter < getComponentCount(); counter++) { Component child = getComponent(counter); Rectangle childBounds = child.getBounds(); Graphics childG = g.create(childBounds.x, childBounds.y, childBounds.width, childBounds.height); child.paint(childG); childG.dispose(); } g2.dispose(); }
/** Paint bumps to specific Graphics. */ @Override public void paint (Graphics g) { Icon icon = UIManager.getIcon("ToolBar.handleIcon"); Region region = Region.TOOL_BAR; SynthStyleFactory sf = SynthLookAndFeel.getStyleFactory(); SynthStyle style = sf.getStyle(toolbar, region); SynthContext context = new SynthContext(toolbar, region, style, SynthConstants.DEFAULT); SynthGraphicsUtils sgu = context.getStyle().getGraphicsUtils(context); sgu.paintText(context, g, null, icon, SwingConstants.LEADING, SwingConstants.LEADING, 0, 0, 0, -1, 0); }
/** Creates a new instance of GTKColor */ public ThemeValue(Region region, ColorType colorType, Object fallback) { this.fallback = fallback; this.aRegion = region; this.aColorType = colorType; register(this); }
/** Creates a new instance of GTKColor */ public ThemeValue(Region region, ColorType colorType, Object fallback, boolean darken) { this.fallback = fallback; this.aRegion = region; this.aColorType = colorType; this.darken = darken; register(this); }
/** * <p>Registers the given region and prefix. The prefix, if it contains * quoted sections, refers to certain named components. If there are not * quoted sections, then the prefix refers to a generic component type.</p> * * <p>If the given region/prefix combo has already been registered, then * it will not be registered twice. The second registration attempt will * fail silently.</p> * * @param region The Synth Region that is being registered. Such as Button, * or ScrollBarThumb. * @param prefix The UIDefault prefix. For example, could be ComboBox, or if * a named components, "MyComboBox", or even something like * ToolBar:"MyComboBox":"ComboBox.arrowButton" */ void register(Region region, String prefix) { //validate the method arguments if (region == null || prefix == null) { throw new IllegalArgumentException( "Neither Region nor Prefix may be null"); } //Add a LazyStyle for this region/prefix to m. List<LazyStyle> styles = m.get(region); if (styles == null) { styles = new LinkedList<LazyStyle>(); styles.add(new LazyStyle(prefix)); m.put(region, styles); } else { //iterate over all the current styles and see if this prefix has //already been registered. If not, then register it. for (LazyStyle s : styles) { if (prefix.equals(s.prefix)) { return; } } styles.add(new LazyStyle(prefix)); } //add this region to the map of registered regions registeredRegions.put(region.getName(), region); }
/** * <p>Locate the style associated with the given region, and component. * This is called from NimbusLookAndFeel in the SynthStyleFactory * implementation.</p> * * <p>Lookup occurs as follows:<br/> * Check the map of styles <code>m</code>. If the map contains no styles at * all, then simply return the defaultStyle. If the map contains styles, * then iterate over all of the styles for the Region <code>r</code> looking * for the best match, based on prefix. If a match was made, then return * that SynthStyle. Otherwise, return the defaultStyle.</p> * * @param comp The component associated with this region. For example, if * the Region is Region.Button then the component will be a JButton. * If the Region is a subregion, such as ScrollBarThumb, then the * associated component will be the component that subregion belongs * to, such as JScrollBar. The JComponent may be named. It may not be * null. * @param r The region we are looking for a style for. May not be null. */ SynthStyle getStyle(JComponent comp, Region r) { //validate method arguments if (comp == null || r == null) { throw new IllegalArgumentException( "Neither comp nor r may be null"); } //if there are no lazy styles registered for the region r, then return //the default style List<LazyStyle> styles = m.get(r); if (styles == null || styles.size() == 0) { return defaultStyle; } //Look for the best SynthStyle for this component/region pair. LazyStyle foundStyle = null; for (LazyStyle s : styles) { if (s.matches(comp)) { //replace the foundStyle if foundStyle is null, or //if the new style "s" is more specific (ie, its path was //longer), or if the foundStyle was "simple" and the new style //was not (ie: the foundStyle was for something like Button and //the new style was for something like "MyButton", hence, being //more specific.) In all cases, favor the most specific style //found. if (foundStyle == null || (foundStyle.parts.length < s.parts.length) || (foundStyle.parts.length == s.parts.length && foundStyle.simple && !s.simple)) { foundStyle = s; } } } //return the style, if found, or the default style if not found return foundStyle == null ? defaultStyle : foundStyle.getStyle(comp, r); }
/** * Gets the style. Creates it if necessary. * @return the style */ SynthStyle getStyle(JComponent c, Region r) { // if the component has overrides, it gets its own unique style // instead of the shared style. if (c.getClientProperty("Nimbus.Overrides") != null) { Map<Region, SynthStyle> map = overridesCache.get(c); SynthStyle s = null; if (map == null) { map = new HashMap<Region, SynthStyle>(); overridesCache.put(c, map); } else { s = map.get(r); } if (s == null) { s = new NimbusStyle(prefix, c); map.put(r, s); } return s; } // lazily create the style if necessary if (style == null) style = new NimbusStyle(prefix, null); // return the style return style; }
private boolean matches(Component c, int partIndex) { if (partIndex < 0) return true; if (c == null) return false; //only get here if partIndex > 0 and c == null String name = c.getName(); if (parts[partIndex].named && parts[partIndex].s.equals(name)) { //so far so good, recurse return matches(c.getParent(), partIndex - 1); } else if (!parts[partIndex].named) { //if c is not named, and parts[partIndex] has an expected class //type registered, then check to make sure c is of the //right type; Class clazz = parts[partIndex].c; if (clazz != null && clazz.isAssignableFrom(c.getClass())) { //so far so good, recurse return matches(c.getParent(), partIndex - 1); } else if (clazz == null && registeredRegions.containsKey(parts[partIndex].s)) { Region r = registeredRegions.get(parts[partIndex].s); Component parent = r.isSubregion() ? c : c.getParent(); //special case the JInternalFrameTitlePane, because it //doesn't fit the mold. very, very funky. if (r == Region.INTERNAL_FRAME_TITLE_PANE && parent != null && parent instanceof JInternalFrame.JDesktopIcon) { JInternalFrame.JDesktopIcon icon = (JInternalFrame.JDesktopIcon) parent; parent = icon.getInternalFrame(); } //it was the name of a region. So far, so good. Recurse. return matches(parent, partIndex - 1); } } return false; }
/** Called by UIManager when this look and feel is installed. */ @Override public void initialize() { super.initialize(); defaults.initialize(); // create synth style factory setStyleFactory(new SynthStyleFactory() { @Override public SynthStyle getStyle(JComponent c, Region r) { return defaults.getStyle(c, r); } }); }
private Test6660049(Class<? extends JComponent>... types) { this.types = types; run(); this.region = new Region("Button", "ButtonUI", true) { @Override public String getName() { throw new Error("6660049: exploit is available"); } }; }
private static void testSynthIcon() { if (!checkAndSetNimbusLookAndFeel()) { return; } JMenuItem menu = new JMenuItem(); Icon subMenuIcon = UIManager.getIcon("Menu.arrowIcon"); if (!(subMenuIcon instanceof SynthIcon)) { throw new RuntimeException("Icon is not a SynthIcon!"); } Region region = SynthLookAndFeel.getRegion(menu); SynthStyle style = SynthLookAndFeel.getStyle(menu, region); SynthContext synthContext = new SynthContext(menu, region, style, SynthConstants.ENABLED); int width = SynthGraphicsUtils.getIconWidth(subMenuIcon, synthContext); int height = SynthGraphicsUtils.getIconHeight(subMenuIcon, synthContext); paintAndCheckIcon(subMenuIcon, synthContext, width, height); int newWidth = width * 17; int newHeight = height * 37; Icon centeredIcon = new CenteredSynthIcon((SynthIcon) subMenuIcon, newWidth, newHeight); paintAndCheckIcon(centeredIcon, synthContext, newWidth, newHeight); }