/* * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Sun Microsystems nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.jdesktop.swingxset; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.ComponentOrientation; import java.awt.Container; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Font; import java.awt.Frame; import java.awt.KeyboardFocusManager; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.PrintWriter; import java.io.StringWriter; import java.util.HashMap; import java.util.List; import java.util.ServiceLoader; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.ButtonGroup; import javax.swing.ButtonModel; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JRadioButtonMenuItem; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.LookAndFeel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import org.jdesktop.application.Action; import org.jdesktop.application.ResourceMap; import org.jdesktop.swingx.JXFrame; import org.jdesktop.swingx.JXMultiSplitPane; import org.jdesktop.swingx.JXPanel; import org.jdesktop.swingx.MultiSplitLayout; import org.jdesktop.swingx.MultiSplitLayout.Node; import org.jdesktop.swingx.appframework.AppSearchFactory; import org.jdesktop.swingx.appframework.SingleXFrameApplication; import org.jdesktop.swingx.appframework.StyledTextActions; import org.jdesktop.swingx.search.SearchFactory; import org.jdesktop.swingx.util.OS; import org.jdesktop.swingx.util.font.FontPolicies; import org.jdesktop.swingx.util.font.FontPolicy; import org.jdesktop.swingx.util.font.FontSet; import org.jdesktop.swingx.util.font.UIFontUtils; import org.jdesktop.swingx.util.font.WrapperFontSet; import org.jdesktop.swingxset.util.DemoUtils; import com.sun.swingset3.Demo; import com.sun.swingset3.codeview.CodeViewer; import com.sun.swingset3.utilities.RoundedBorder; import com.sun.swingset3.utilities.Utilities; /** * * @author Amy Fowler * @author Jeanette Winzenburg (SwingX adaption) */ public class SwingXSet extends SingleXFrameApplication { public static final Logger logger = Logger.getLogger(SwingXSet.class.getName()); private static final ServiceLoader<LookAndFeel> LOOK_AND_FEEL_LOADER = ServiceLoader.load(LookAndFeel.class); public static final String CONTROL_VERY_LIGHT_SHADOW_KEY = "controlVeryLightShadowColor"; public static final String CONTROL_LIGHT_SHADOW_KEY = "controlLightShadowColor"; public static final String CONTROL_MID_SHADOW_KEY = "controlMidShadowColor"; public static final String CONTROL_VERY_DARK_SHADOW_KEY = "controlVeryDarkShadowColor"; public static final String CONTROL_DARK_SHADOW_KEY = "controlDarkShadowColor"; public static final String TITLE_GRADIENT_COLOR1_KEY = "titleGradientColor1"; public static final String TITLE_GRADIENT_COLOR2_KEY = "titleGradientColor2"; public static final String TITLE_FOREGROUND_KEY = "titleForegroundColor"; public static final String CODE_HIGHLIGHT_KEY = "codeHighlightColor"; public static final String TITLE_FONT_KEY = "titleFont"; public static final String SUB_PANEL_BACKGROUND_KEY = "subPanelBackgroundColor"; private static final Border EMPTY_BORDER = new EmptyBorder(0, 0, 0, 0); private static final Border PANEL_BORDER = new EmptyBorder(10, 10, 10, 10); private static final String DEMO_LIST_FILE = "/META-INF/demolist"; static { // Property must be set *early* due to Apple Bug#3909714 if (System.getProperty("os.name").equals("Mac OS X")) { System.setProperty("apple.laf.useScreenMenuBar", "true"); } // temporary workaround for problem with Nimbus classname UIManager.LookAndFeelInfo lafInfo[] = UIManager.getInstalledLookAndFeels(); for(int i = 0; i < lafInfo.length; i++) { if (lafInfo[i].getName().equals("Nimbus")) { lafInfo[i] = new UIManager.LookAndFeelInfo("Nimbus", "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); break; } } UIManager.setInstalledLookAndFeels(lafInfo); UIManager.put("swing.boldMetal", Boolean.FALSE); UIManager.put("auto-add-separator", Boolean.FALSE); } public static void main(String[] args) { launch(SwingXSet.class, args); } public static boolean runningOnMac() { return System.getProperty("os.name").equals("Mac OS X"); } public static boolean usingNimbus() { return UIManager.getLookAndFeel().getName().equals("Nimbus"); } // End of statics private ResourceMap resourceMap; // Application models private PropertyChangeListener demoPropertyChangeListener; private HashMap<String, JComponent> runningDemoCache; private DemoSelector demoSelector; // GUI components and controls private MultiSplitLayout multiSplitLayout; private CodeViewer codeViewer; private ButtonGroup lookAndFeelRadioGroup; private JPopupMenu popup; // Properties private String lookAndFeel; private boolean hasBig; // -------------------- SwingXSet application/control code /** * Sets the bigFontSet property which is a flag indicating whether a large * FontSet should be used. * <p> * If true, the LAF FontSet is scaled up by a fixed amount, otherwise it's * taken as is. * * The default is false. * * @param bigFontSet a boolean indicating whether or not the system Fonts * should be scaled up. */ public void setBigFontSet(boolean bigFontSet) { boolean old = isBigFontSet(); if (old == bigFontSet) return; this.hasBig = bigFontSet; updateFontSet(); firePropertyChange("bigFontSet", old, isBigFontSet()); } /** * Returns the bigFontSet property. * @return */ public boolean isBigFontSet() { return hasBig; } /** * Toggle the bigFontSet property. * <p> * Note: this is public as an implementation side-effect. DON'T USE! */ @Action(selectedProperty = "bigFontSet", enabledProperty = "windowsOS") public void toggleFontSet() { } public boolean isWindowsOS() { return OS.isWindows(); } /** * Internal state update after FontSet flag has been changed. */ private void updateFontSet() { if (!isBigFontSet()) { UIFontUtils.initFontDefaults(UIManager.getDefaults(), null); } else { // <snip> Install sscaled font FontPolicy windowsPolicy = FontPolicies.getDefaultWindowsPolicy(); FontSet fontSet = windowsPolicy.getFontSet(null, UIManager .getLookAndFeelDefaults()); WrapperFontSet scaled = new WrapperFontSet(fontSet, 5); UIFontUtils.initFontDefaults(UIManager.getDefaults(), scaled); // </snip> } updateLookAndFeel(); } /** * Toggles the codeViewerVisible property. * <p> * Note: this is public as an implementation side-effect. DON'T USE! */ @Action (selectedProperty = "codeViewerVisible") public void toggleCodeViewerVisible() { } public void setCodeViewerVisible(boolean selectorVisible) { boolean old = isCodeViewerVisible(); // <snip> MultiSplit toggle visiility by constraint multiSplitLayout.displayNode("source", selectorVisible); ((JComponent) getMainFrame().getContentPane()).revalidate(); // </snip> firePropertyChange("codeViewerVisible", old, isCodeViewerVisible()); requestFocusOnDemo(); } public boolean isCodeViewerVisible() { JComponent selector = getComponentByConstraint("source"); return selector.isVisible(); } /** * Toggles the selectorVisible property. * <p> * Note: this is public as an implementation side-effect. DON'T USE! * */ @Action (selectedProperty = "selectorVisible") public void toggleSelectorVisible() { } public void setSelectorVisible(boolean selectorVisible) { boolean old = isSelectorVisible(); // <snip> MultiSplit toggle visiility by constraint multiSplitLayout.displayNode("selector", selectorVisible); ((JComponent) getMainFrame().getContentPane()).revalidate(); // </snip> firePropertyChange("selectorVisible", old, isSelectorVisible()); requestFocusOnDemo(); } public boolean isSelectorVisible() { JComponent selector = getComponentByConstraint("selector"); return selector.isVisible(); } /** * @param demoContainer */ private void requestFocusOnDemo() { SwingUtilities.invokeLater(new Runnable() { public void run() { Demo demo = demoSelector.getSelectedDemo(); if (demo != null) { Component demoComponent = demo.getDemoComponent(); if (demoComponent != null) { KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent(demoComponent); } } } }); } private void updateFromSelectedDemoChanged() { JComponent demoContainer = getComponentByConstraint("demo"); Demo demo = getDemo(); if (demo != null) { JComponent demoPanel = runningDemoCache.get(demo.getName()); if (demoPanel == null || demo.getDemoComponent() == null) { demo.startInitializing(); demoPanel = createDemoPanel(demo); if (demoPanel != null) { runningDemoCache.put(demo.getName(), demoPanel); } } if (demoPanel != null) { demoContainer.removeAll(); //(currentDemoPanel); demoContainer.add(demoPanel, BorderLayout.CENTER); demoContainer.revalidate(); demoContainer.repaint(); multiSplitLayout.layoutByWeight(getMainFrame().getContentPane()); } } codeViewer.setSourceFiles(demo != null? demo.getSourceFiles() : null); } private JComponent createDemoPanel(Demo demo) { try { return new DemoXPanel(demo); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public Demo getDemo() { return demoSelector.getSelectedDemo(); } private class DemoSelectionListener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent event) { if (event.getPropertyName().equals("selectedDemo")) { updateFromSelectedDemoChanged(); } } } // registered on Demo to detect when the demo component is instantiated. // we need this because when we embed the demo inside an HTML description pane, // we don't have control over the demo component's instantiation private class DemoPropertyChangeListener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent e) { String propertyName = e.getPropertyName(); if (propertyName.equals("demoComponent")) { Demo demo = (Demo)e.getSource(); JComponent demoComponent = (JComponent)e.getNewValue(); if (demoComponent != null) { demoComponent.putClientProperty("swingset3.demo", demo); demoComponent.addHierarchyListener(new DemoVisibilityListener()); registerPopups(demoComponent); } } } } private class DemoVisibilityListener implements HierarchyListener { public void hierarchyChanged(HierarchyEvent event) { if ((event.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) > 0) { JComponent component = (JComponent)event.getComponent(); final Demo demo = (Demo)component.getClientProperty("swingset3.demo"); if (!component.isShowing()) { demo.stop(); } else { getComponentByConstraint("demo").revalidate(); EventQueue.invokeLater(new Runnable() { public void run() { demo.start(); } }); } } } } private JComponent getComponentByConstraint(String string) { Node node = multiSplitLayout.getNodeForName(string); return (JComponent) multiSplitLayout.getComponentForNode(node); } public void setLookAndFeel(String lookAndFeel) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException { String oldLookAndFeel = this.lookAndFeel; if (oldLookAndFeel != lookAndFeel) { boolean oldBig = isBigFontSet(); hasBig = false; updateFontSet(); UIManager.setLookAndFeel(lookAndFeel); this.lookAndFeel = lookAndFeel; updateLookAndFeel(); setBigFontSet(oldBig); firePropertyChange("lookAndFeel", oldLookAndFeel, lookAndFeel); } } @Action public void setLookAndFeel() { ButtonModel model = lookAndFeelRadioGroup.getSelection(); String lookAndFeelName = model.getActionCommand(); try { setLookAndFeel(lookAndFeelName); } catch (Exception ex) { displayErrorMessage(resourceMap.getString("error.unableToChangeLookAndFeel") + "to "+lookAndFeelName, ex); } } public String getLookAndFeel() { return lookAndFeel; } private void updateLookAndFeel() { Window windows[] = Frame.getWindows(); for(Window window : windows) { SwingUtilities.updateComponentTreeUI(window); for(JComponent demoPanel : runningDemoCache.values()) { SwingUtilities.updateComponentTreeUI(demoPanel); } } ((AppSearchFactory) SearchFactory.getInstance()).updateUI(); } // hook used to detect if any components in the demo have registered a // code snippet key for the their creation code inside the source private void registerPopups(Component component) { if (component instanceof Container) { Component children[] = ((Container)component).getComponents(); for(Component child: children) { if (child instanceof JComponent) { registerPopups(child); } } } if (component instanceof JComponent) { JComponent jcomponent = (JComponent)component; String snippetKey = (String)jcomponent.getClientProperty("snippetKey"); if (snippetKey != null) { jcomponent.setComponentPopupMenu(popup); } } } private class ViewCodeSnippetAction extends AbstractAction { public ViewCodeSnippetAction() { super("View Source Code"); } public void actionPerformed(ActionEvent actionEvent) { Container popup = (JComponent)actionEvent.getSource(); while(popup != null && !(popup instanceof JPopupMenu)) { popup = popup.getParent(); } JComponent target = (JComponent)((JPopupMenu)popup).getInvoker(); String snippetKey = (String)target.getClientProperty("snippetKey"); if (snippetKey != null) { codeViewer.highlightSnippetSet(snippetKey); } else { logger.log(Level.WARNING, "can't find source code snippet for:" + snippetKey); } } } private static class EditPropertiesAction extends AbstractAction { public EditPropertiesAction() { super("Edit Properties"); } @Override public boolean isEnabled() { return false; } public void actionPerformed(ActionEvent actionEvent) { } } //------------------- override/implement Application @Override protected void initialize(String args[]) { // following line is for debugging initial layount only, will be removed .. // deleteSessionState(); try { // JW: don't want to start up with Nimbus because it misbehaves // severely in not cleaning up behind itself ... UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ex) { // not catestrophic } super.initialize(args); resourceMap = getContext().getResourceMap(); runningDemoCache = new HashMap<String, JComponent>(); List<Demo> demos = DemoCreator.getInstance().createDemos(args, DEMO_LIST_FILE); for (Demo demo : demos) { demo.addPropertyChangeListener(getDemoPropertyChangeListener()); } demoSelector = new DemoSelector(demos); // SearchFactory.getInstance().setUseFindBar(true); } @Override protected void startup() { configureDefaults(); JXFrame frame = (JXFrame) getMainFrame(); frame.add(createMainPanel()); frame.setJMenuBar(createMenuBar()); applyDefaults(); installListeners(); // PENDING JW: moved from start of method to after component creation // otherwise throws with bsaf-1.9.1 // needs tracking - dont know what's happening ... StyledTextActions.install(getContext()); show(frame); demoSelector.setDefaultSelectedDemo(); } /** * Overridden to apply fade-out hook instead of halting the runtime. */ @Override protected void end() { DemoUtils.fadeOutAndExit(getMainFrame(), 800); } @Override protected void configureWindow(Window root) { super.configureWindow(root); if (root == getMainFrame()) { // PENDING JW // brute force: prevent super from pack()'ing the mainframe // initially - actually it's a problem of our overall // layout, packing giving horrible results ... // we have to do it here (instead of in show as I assumed) // because super's injecting properties will invalidate root.pack(); root.setBounds(0, 0, 1024, 748); root.validate(); } } @Override protected JXFrame createXFrame() { // JXFrame frame = new JXFrame(); // frame.setRootPane(new JXDemoRootPane()); return new JXDemoFrame(); } protected void installListeners() { UIManager.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { if (event.getPropertyName().equals("lookAndFeel")) { configureDefaults(); } } }); demoSelector.addPropertyChangeListener(new DemoSelectionListener()); } // --------------------------- build components protected JComponent createMainPanel() { // <snip> MultiSplit layout declaration String layout = "(ROW " + "(LEAF name=selector weight=0.25)" + "(COLUMN weight=0.75 " + "(LEAF name= demo weight=0.7)" + "(LEAF name=source weight=0.3)" + ")" + ")"; multiSplitLayout = new MultiSplitLayout(MultiSplitLayout.parseModel(layout)); // </snip> JXMultiSplitPane splitPane = new JXMultiSplitPane(); splitPane.setLayout(multiSplitLayout); // Create demo selector panel on left JComponent demoSelectorPanel = demoSelector.getSelectorComponent(); demoSelectorPanel.setBorder(PANEL_BORDER); splitPane.add(demoSelectorPanel, "selector"); // Create panel to contain currently running demo JComponent demoContainer = new JXPanel(); demoContainer.setLayout(new BorderLayout()); demoContainer.setBorder(PANEL_BORDER); splitPane.add(demoContainer, "demo"); // Create source code pane codeViewer = new CodeViewer(); // Font font = codeViewer.getFont(); // codeViewer.setFont(font.deriveFont(Font.BOLD, 20.f)); JComponent codeContainer = new JPanel(new BorderLayout()); codeContainer.add(codeViewer); codeContainer.setBorder(PANEL_BORDER); splitPane.add(codeContainer, "source"); // Create shareable popup menu for demo actions popup = new JPopupMenu(); popup.add(new EditPropertiesAction()); popup.add(new ViewCodeSnippetAction()); return splitPane; } protected JMenuBar createMenuBar() { JMenuBar menubar = new JMenuBar(); menubar.setName("menubar"); // File menu JMenu fileMenu = new JMenu(); fileMenu.setName("file"); menubar.add(fileMenu); // File -> Quit if (!runningOnMac()) { JMenuItem quitItem = new JMenuItem(); quitItem.setName("quit"); quitItem.setAction(getAction("quit")); fileMenu.add(quitItem); } // View menu JMenu viewMenu = new JMenu(); viewMenu.setName("view"); // View -> Look and Feel viewMenu.add(createLookAndFeelMenu()); menubar.add(viewMenu); viewMenu.add(new JCheckBoxMenuItem(getAction("toggleFontSet"))); JMenuItem toggleSelectorVisible = new JCheckBoxMenuItem(getAction("toggleSelectorVisible")); // PENDING JW: Action binding to selected - force initial state toggleSelectorVisible.setSelected(isSelectorVisible()); viewMenu.add(toggleSelectorVisible); JMenuItem toggleCodeViewerVisible = new JCheckBoxMenuItem(getAction("toggleCodeViewerVisible")); // PENDING JW: Action binding to selected - force initial state toggleCodeViewerVisible.setSelected(isCodeViewerVisible()); viewMenu.add(toggleCodeViewerVisible); // debug // viewMenu.add(new JMenuItem(getAction("debugVisible"))); // JMenuItem toggleCO = new JMenuItem(getAction("toggleCO")); // viewMenu.add(toggleCO); return menubar; } @Action public void debugVisible() { toggleCodeViewerVisible(); } @Action public void toggleCO() { JFrame frame = getMainFrame(); ComponentOrientation current = frame.getComponentOrientation(); if (current == ComponentOrientation.LEFT_TO_RIGHT) { frame.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); } else { frame.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); } frame.getRootPane().revalidate(); frame.invalidate(); frame.validate(); frame.repaint(); } protected JMenu createLookAndFeelMenu() { JMenu menu = new JMenu(); menu.setName("lookAndFeel"); // Look for toolkit look and feels first UIManager.LookAndFeelInfo lookAndFeelInfos[] = UIManager.getInstalledLookAndFeels(); lookAndFeel = UIManager.getLookAndFeel().getClass().getName(); lookAndFeelRadioGroup = new ButtonGroup(); for(UIManager.LookAndFeelInfo lafInfo: lookAndFeelInfos) { menu.add(createLookAndFeelItem(lafInfo.getName(), lafInfo.getClassName())); } // Now load any look and feels defined externally as service via java.util.ServiceLoader LOOK_AND_FEEL_LOADER.iterator(); for (LookAndFeel laf : LOOK_AND_FEEL_LOADER) { menu.add(createLookAndFeelItem(laf.getName(), laf.getClass().getName())); } return menu; } protected JRadioButtonMenuItem createLookAndFeelItem(String lafName, String lafClassName) { JRadioButtonMenuItem lafItem = new JRadioButtonMenuItem(); lafItem.setSelected(lafClassName.equals(lookAndFeel)); lafItem.setHideActionText(true); lafItem.setAction(getAction("setLookAndFeel")); lafItem.setText(lafName); lafItem.setActionCommand(lafClassName); lookAndFeelRadioGroup.add(lafItem); return lafItem; } private javax.swing.Action getAction(String actionName) { return getContext().getActionMap().get(actionName); } // For displaying error messages to user protected void displayErrorMessage(String message, Exception ex) { JPanel messagePanel = new JPanel(new BorderLayout()); JLabel label = new JLabel(message); messagePanel.add(label); if (ex != null) { JComponent panel = new JXPanel(new BorderLayout()); panel.setBorder(new RoundedBorder()); // remind(aim): provide way to allow user to see exception only if desired StringWriter writer = new StringWriter(); ex.printStackTrace(new PrintWriter(writer)); JTextArea exceptionText = new JTextArea(); exceptionText.setText("Cause of error:\n" + writer.getBuffer().toString()); exceptionText.setBorder(new RoundedBorder()); exceptionText.setOpaque(false); exceptionText.setBackground( Utilities.deriveColorHSB(UIManager.getColor("Panel.background"), 0, 0, -.2f)); JScrollPane scrollpane = new JScrollPane(exceptionText); scrollpane.setBorder(EMPTY_BORDER); scrollpane.setPreferredSize(new Dimension(600,240)); panel.add(scrollpane); messagePanel.add(panel, BorderLayout.SOUTH); } JOptionPane.showMessageDialog(getMainFrame(), messagePanel, resourceMap.getString("error.title"), JOptionPane.ERROR_MESSAGE); } // ----------------------- init/read/create Demos protected PropertyChangeListener getDemoPropertyChangeListener() { if (demoPropertyChangeListener == null) { demoPropertyChangeListener = new DemoPropertyChangeListener(); } return demoPropertyChangeListener; } //------------------------ init/configure ui properties private void configureDefaults() { // Color palette algorithm courtesy of Jasper Potts Color controlColor = UIManager.getColor("control"); UIManager.put(CONTROL_VERY_LIGHT_SHADOW_KEY, Utilities.deriveColorHSB(controlColor, 0, 0, -0.02f)); UIManager.put(CONTROL_LIGHT_SHADOW_KEY, Utilities.deriveColorHSB(controlColor, 0, 0, -0.06f)); UIManager.put(CONTROL_MID_SHADOW_KEY, Utilities.deriveColorHSB(controlColor, 0, 0, -0.16f)); UIManager.put(CONTROL_VERY_DARK_SHADOW_KEY, Utilities.deriveColorHSB(controlColor, 0, 0, -0.5f)); UIManager.put(CONTROL_DARK_SHADOW_KEY, Utilities.deriveColorHSB(controlColor, 0, 0, -0.32f)); // Calculate gradient colors for title panels Color titleColor = UIManager.getColor(usingNimbus()? "nimbusBase" : "activeCaption"); // Some LAFs (e.g. GTK) don't contain "activeCaption" if (titleColor == null) { titleColor = controlColor; } float hsb[] = Color.RGBtoHSB( titleColor.getRed(), titleColor.getGreen(), titleColor.getBlue(), null); UIManager.put(TITLE_GRADIENT_COLOR1_KEY, Color.getHSBColor(hsb[0]-.013f, .15f, .85f)); UIManager.put(TITLE_GRADIENT_COLOR2_KEY, Color.getHSBColor(hsb[0]-.005f, .24f, .80f)); UIManager.put(TITLE_FOREGROUND_KEY, Color.getHSBColor(hsb[0], .54f, .40f)); // Calculate highlight color for code pane UIManager.put(CODE_HIGHLIGHT_KEY, Color.getHSBColor(hsb[0]-.005f, .20f, .95f)); Font labelFont = UIManager.getFont("Label.font"); UIManager.put(TITLE_FONT_KEY, labelFont.deriveFont(Font.BOLD, labelFont.getSize()+4f)); Color panelColor = UIManager.getColor("Panel.background"); UIManager.put(SUB_PANEL_BACKGROUND_KEY, Utilities.deriveColorHSB(panelColor, 0, 0, -.06f)); applyDefaults(); } protected void applyDefaults() { if (codeViewer != null) { codeViewer.setHighlightColor(UIManager.getColor(CODE_HIGHLIGHT_KEY)); } } }