Repository: Revivius/nb-darcula Branch: master Commit: d00114bf060a Files: 52 Total size: 194.1 KB Directory structure: gitextract_gut4mkzt/ ├── .gitignore ├── README.md ├── lib/ │ └── com/ │ └── bulenkov/ │ └── darcula/ │ └── 1.0.0/ │ └── darcula-1.0.0.jar ├── nb-configuration.xml ├── pom.xml └── src/ └── main/ ├── java/ │ └── com/ │ └── revivius/ │ └── nb/ │ └── darcula/ │ ├── DarculaLFCustoms.java │ ├── DarkIconFilter.java │ ├── GuaranteedValue.java │ ├── Installer.java │ ├── RelativeColor.java │ ├── ToolbarXP.java │ ├── UIBootstrapValue.java │ ├── options/ │ │ ├── DarculaLAFOptionsPanelController.java │ │ ├── DarculaLAFPanel.form │ │ └── DarculaLAFPanel.java │ └── ui/ │ ├── ContentAreaAwareButtonUI.java │ ├── ContentAreaAwareToggleButtonUI.java │ ├── DarculaSplitPaneDivider.java │ ├── DarculaSplitPaneUI.java │ ├── DarkScrollButtonTabbedPaneUI.java │ ├── IndentAwareTreeUI.java │ ├── InreasedInsetsTableHeaderBorder.java │ ├── OptionsAwareLabelUI.java │ ├── ReducedInsetsDarculaButtonPainter.java │ └── RolloverToolBarUI.java ├── nbm/ │ └── manifest.mf └── resources/ ├── LICENSE-2.0.txt └── com/ └── revivius/ └── nb/ └── darcula/ ├── Bundle.properties ├── Editors/ │ ├── FontsColors/ │ │ └── Darcula/ │ │ ├── annotations.xml │ │ ├── highlights.xml │ │ └── tokenColorings.xml │ ├── application/ │ │ └── xml-dtd/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ └── text/ │ ├── css/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── html/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── javascript/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── plain/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── x-apache-conf/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── x-diff/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── x-el/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── x-java/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── x-json/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── x-jsp/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── x-php5/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── x-properties/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── x-sql/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── x-tag/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── x-tpl/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── xhtml/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ ├── xml/ │ │ └── FontsColors/ │ │ └── Darcula/ │ │ └── tokenColorings.xml │ └── xml-external-parsed-entity/ │ └── FontsColors/ │ └── Darcula/ │ └── tokenColorings.xml ├── layer.xml └── options/ └── Bundle.properties ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ target/ keystore/ nbactions.xml ================================================ FILE: README.md ================================================ A NetBeans Look And Feel plugin using Darcula of IntelliJ IDEA. ![Darcula4NB](/../screenshots/screenshots/v1.4.png?raw=true "Darcula4NB") Wraps [Darcula LAF](https://github.com/bulenkov/Darcula) and provides required NetBeans specific customizations. **Many thanks to Konstantin Bulenkov for open sourcing original Darcula LAF.** The most recent stable version of this plugin is available at the NetBeans Plugin Portal as [Darcula LAF for NetBeans](http://plugins.netbeans.org/plugin/62424/darcula-laf-for-netbeans) and thus it can be installed from "Tools|Plugins|Available Plugins" from the NetBeans IDE. ## Change Log ### [1.6] - 2017-07-31 - Plugin now works on JDK9. Thanks to **Smurfi** and **markiewb**. - Now it is possible to override indentation level of trees (including the one in Projects window) via Tools > Options > Appearance > Darcula Look And Feel. - Tab navigation with CTRL+PageUp/PageDown fixed. Thanks to **markiewb**. - Hard to read colors in SQL results table, start page and notification links fixed. - Hard to read colors for custom HTML tags, CSS preprocessor variables and mixins in code completion popup fixed. - For all addressed issues (16) please see [Milestone v1.6](https://github.com/Revivius/nb-darcula/issues?q=milestone%3Av1.6+is%3Aclosed). ### [1.5] - 2016-04-09 - Hard to read colors in HTML, XHTML, JSP and SQL code completion popups and Apache Conf (.htaccess, .conf) files fixed thank to **granella**. - Baseline alignment of combo boxes fixed thanks to **AlexFalappa**. Fix for toggle buttons moved to original Darcula library; they should look OK now in GUI designer too. - Editor tab colors for 'Same background color from the same project' feature (Tools > Options > Appearance > Document Tabs) adjusted to match Darcula LAF. - More color, border and icon enhancements (including background color for tree and tables, border of selected rows, icons in Profiler and C/C++ wizard). - For all addressed issues (14) please see [Milestone v1.5](https://github.com/Revivius/nb-darcula/issues?q=milestone%3Av1.5+is%3Aclosed). ### [1.4] - 2016-01-31 - Fixed hard to read colors in Code Completion popup (hopefully) for all languages. - Disabled buttons and labels are easier to read. - Fixed default button behavior in dailogs (eg: alt+insert in editor to generate setters and getters). - It is safe to use this plugin in any NetBeans platform application now. Level used to log failed attempts to change hardcoded colors is now INFO and so no error dialog will be displayed at startup. - It is possible to use icon filter to invert icon colors and switch between stretched and non-stretched tabs in Tools > Options > Appearance > Darcula Look And Feel. Thanks to **markiewb** for the contribution. - Improved icons for JOptionPane, thanks to **AlexFalappa** and **granella**. - More color, border and icon enhancements (including NetBeans Task/Issue viewer, submenu icons on MAC, Darcula Editor Theme and others). - For all addressed issues (27) please see [Milestone v1.4](https://github.com/Revivius/nb-darcula/issues?q=milestone%3Av1.4+is%3Aclosed). ### [1.3] - 2016-01-24 - Bundled 'Darcula' theme (Tools > Options > Fonts&Colors). Plugin will set theme to Darcula during first restart. Many thanks to **granella** for the theme and helping with packaging it in plugin. - It is possible to specify font type and size within IDE via Tools > Options > Appearance > Darcula Look And Feel. Many thanks to **markiewb** for implementing this with other font related issues. - More color, border and icon enhancements (including diff, versioning colors and FormDesigner guidelines, new Split Pane UI thanks to [hudsonb](https://github.com/bulenkov/Darcula/pull/5)). - For all addressed issues (14) please see [Milestone v1.3](https://github.com/Revivius/nb-darcula/issues?q=milestone%3Av1.3+is%3Aclosed). ### [1.2] - 2016-01-19 - Fixed dark text in Code Completion popup. - Removed more harsh white borders (including the ones in Options window and sliding buttons). A few remaining (such as the one in Search Results) are hardcoded and I dont know a good way of patching those. - Added a slight margin for buttons ### [1.1] - 2016-01-17 - Font size issue fixed. It is now possible to use --fontsize switch (either in conf file or command line) to specify desired font size, default size is 12. - 'Darcula for NetBeans' is now in 'Preferred look and feel' drop down as requested (Tools > Options > Appearance > Look and Feel). Plugin will set LAF to Darcula during first restart. After that user can switch LAF without uninstalling/disabling the plugin. - Colors in Options window match properly with LAF. - Many harsh white borders (including the one of search box at top right corner of main window) removed. - Contrasting light versions of most core icons provided (close, slide, minimize, restore etc). ### [1.0] - 2016-01-14 ================================================ FILE: nb-configuration.xml ================================================ apache20 true ================================================ FILE: pom.xml ================================================ 4.0.0 com.revivius nb-darcula 1.6 nbm Darcula LAF for NetBeans org.codehaus.mojo nbm-maven-plugin 3.13 true Revivius true src/main/resources/LICENSE-2.0.txt Apache 2.0 keystore/store.jks Revivius org.apache.maven.plugins maven-compiler-plugin 2.5.1 1.6 1.6 org.apache.maven.plugins maven-jar-plugin 2.4 true lib lib true ignore false file:///${project.basedir}/lib netbeans Repository hosting NetBeans modules http://bits.netbeans.org/nexus/content/groups/netbeans false com.bulenkov darcula 1.0.0 org.netbeans.api org-netbeans-swing-plaf ${netbeans.version} org.netbeans.api org-openide-modules ${netbeans.version} org.netbeans.api org-openide-util-lookup ${netbeans.version} org.netbeans.api org-openide-util ${netbeans.version} org.netbeans.api org-netbeans-modules-options-api ${netbeans.version} org.netbeans.api org-openide-awt ${netbeans.version} org.netbeans.api org-openide-dialogs ${netbeans.version} org.netbeans.api org-openide-windows ${netbeans.version} RELEASE80 UTF-8 A NetBeans Look And Feel plugin using Darcula of IntelliJ IDEA. Wraps <a href="https://github.com/bulenkov/Darcula">Darcula LAF</a> and provides required NetBeans specific customizations. <b>Many thanks to Konstantin Bulenkov for open sourcing original Darcula LAF.</b> <h2>Change Log</h2> <h3>[1.6] - 2017-07-31</h3> <ul> <li>Plugin now works on JDK9. Thanks to <b>Smurfi</b> and <b>markiewb</b>.</li> <li>Now it is possible to override indentation level of trees (including the one in Projects window) via Tools > Options > Appearance > Darcula Look And Feel.</li> <li>Tab navigation with CTRL+PageUp/PageDown fixed. Thanks to <b>markiewb</b>.</li> <li>Hard to read colors in SQL results table, start page and notification links fixed.</li> <li>Hard to read colors for custom HTML tags, CSS preprocessor variables and mixins in code completion popup fixed.</li> <li>For all addressed issues (16) please see <a href="https://github.com/Revivius/nb-darcula/issues?q=milestone%3Av1.6+is%3Aclosed">Milestone v1.6</a>.</li> </ul> <h3>[1.5] - 2016-04-09</h3> <ul> <li>Hard to read colors in HTML, XHTML, JSP and SQL code completion popups and Apache Conf (.htaccess, .conf) files fixed thank to <b>granella</b>.</li> <li>Baseline alignment of combo boxes fixed thanks to <b>AlexFalappa</b>. Fix for toggle buttons moved to original Darcula library; they should look OK now in GUI designer too.</li> <li>Editor tab colors for 'Same background color from the same project' feature (Tools > Options > Appearance > Document Tabs) adjusted to match Darcula LAF.</li> <li>More color, border and icon enhancements (including background color for tree and tables, border of selected rows, icons in Profiler and C/C++ wizard).</li> <li>For all addressed issues (14) please see <a href="https://github.com/Revivius/nb-darcula/issues?q=milestone%3Av1.5+is%3Aclosed">Milestone v1.5</a>.</li> </ul> <h3>[1.4] - 2016-01-31</h3> <ul> <li>Fixed hard to read colors in Code Completion popup (hopefully) for all languages.</li> <li>Disabled buttons and labels are easier to read.</li> <li>Fixed default button behavior in dailogs (eg: alt+insert in editor to generate setters and getters).</li> <li>It is safe to use this plugin in any NetBeans platform application now. Level used to log failed attempts to change hardcoded colors is now INFO and so no error dialog will be displayed at startup.</li> <li>It is possible to use icon filter to invert icon colors and switch between stretched and non-stretched tabs in Tools > Options > Appearance > Darcula Look And Feel. Thanks to <b>markiewb</b> for the contribution.</li> <li>Improved icons for JOptionPane, thanks to <b>AlexFalappa</b> and <b>granella</b>.</li> <li>More color, border and icon enhancements (including NetBeans Task/Issue viewer, submenu icons on MAC, Darcula Editor Theme and others).</li> <li>For all addressed issues (27) please see <a href="https://github.com/Revivius/nb-darcula/issues?q=milestone%3Av1.4+is%3Aclosed">Milestone v1.4</a>.</li> </ul> <h3>[1.3] - 2016-01-24</h3> <ul> <li>Bundled 'Darcula' theme (Tools > Options > Fonts&Colors). Plugin will set theme to Darcula during first restart. Many thanks to <b>granella</b> for the theme and helping with packaging it in plugin.</li> <li>It is possible to specify font type and size within IDE via Tools > Options > Appearance > Darcula Look And Feel. Many thanks to <b>markiewb</b> for implementing this with other font related issues.</li> <li>More color, border and icon enhancements (including diff, versioning colors and FormDesigner guidelines, new Split Pane UI thanks to <a href="https://github.com/bulenkov/Darcula/pull/5">hudsonb</a>).</li> <li>For all addressed issues (14) please see <a href="https://github.com/Revivius/nb-darcula/issues?q=milestone%3Av1.3+is%3Aclosed">Milestone v1.3</a>.</li> </ul> <h3>[1.2] - 2016-01-19</h3> <ul> <li>Fixed dark text in Code Completion popup.</li> <li>Removed more harsh white borders (including the ones in Options window and sliding buttons). A few remaining (such as the one in Search Results) are hardcoded and I dont know a good way of patching those.</li> <li>Added a slight margin for buttons.</li> </ul> <h3>[1.1] - 2016-01-17</h3> <ul> <li>Font size issue fixed. It is now possible to use --fontsize switch (either in conf file or command line) to specify desired font size, default size is 12.</li> <li>'Darcula for NetBeans' is now in 'Preferred look and feel' drop down as requested (Tools > Options > Appearance > Look and Feel). Plugin will set LAF to Darcula during first restart. After that user can switch LAF without uninstalling/disabling the plugin.</li> <li>Colors in Options window match properly with LAF.</li> <li>Many harsh white borders (including the one of search box at top right corner of main window) removed.</li> <li>Contrasting light versions of most core icons provided (close, slide, minimize, restore etc).</li> </ul> <h3>[1.0] - 2016-01-14</h3> ================================================ FILE: src/main/java/com/revivius/nb/darcula/DarculaLFCustoms.java ================================================ package com.revivius.nb.darcula; import com.revivius.nb.darcula.ui.InreasedInsetsTableHeaderBorder; import com.revivius.nb.darcula.ui.ReducedInsetsDarculaButtonPainter; import com.revivius.nb.darcula.options.DarculaLAFOptionsPanelController; import com.revivius.nb.darcula.options.DarculaLAFPanel; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.Graphics; import java.awt.Insets; import java.awt.event.KeyEvent; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java.util.prefs.Preferences; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.InputMap; import javax.swing.KeyStroke; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.MatteBorder; import javax.swing.plaf.ColorUIResource; import org.netbeans.swing.plaf.LFCustoms; import org.openide.util.ImageUtilities; import org.openide.util.Lookup; import org.openide.util.NbPreferences; import javax.swing.UIDefaults.ProxyLazyValue; /** * LFCustoms for Darcula LAF. * * @author Revivius */ public class DarculaLFCustoms extends LFCustoms { private static final String FONT_DEFAULT_NAME = "Dialog"; private static final int FONT_DEFAULT_SIZE = 12; public static final String DEFAULT_FONT = FONT_DEFAULT_NAME + " " + FONT_DEFAULT_SIZE; private static final String TAB_FOCUS_FILL_UPPER = "tab_focus_fill_upper"; //NOI18N private static final String TAB_FOCUS_FILL_LOWER = "tab_focus_fill_lower"; //NOI18N private static final String TAB_UNSEL_FILL_UPPER = "tab_unsel_fill_upper"; //NOI18N private static final String TAB_UNSEL_FILL_LOWER = "tab_unsel_fill_lower"; //NOI18N private static final String TAB_SEL_FILL = "tab_sel_fill"; //NOI18N private static final String TAB_MOUSE_OVER_FILL_UPPER = "tab_mouse_over_fill_upper"; //NOI18N private static final String TAB_MOUSE_OVER_FILL_LOWER = "tab_mouse_over_fill_lower"; //NOI18N private static final String TAB_ATTENTION_FILL_UPPER = "tab_attention_fill_upper"; //NOI18N private static final String TAB_ATTENTION_FILL_LOWER = "tab_attention_fill_lower"; //NOI18N private static final String TAB_BORDER = "tab_border"; //NOI18N private static final String TAB_SEL_BORDER = "tab_sel_border"; //NOI18N private static final String TAB_BORDER_INNER = "tab_border_inner"; //NOI18N @Override public Object[] createGuaranteedKeysAndValues() { // same color for DarculaMetalTheme getAcceleratorForeground() Color asfg = new ColorUIResource(187, 187, 187); Object[] result = { "controlShadow", new ColorUIResource(41, 43, 45), "controlHighlight", new ColorUIResource(70, 72, 74), "controlDkShadow", new ColorUIResource(41, 43, 45), "controlLtHighlight", new ColorUIResource(70, 72, 74), "Menu.acceleratorSelectionForeground", asfg, "MenuItem.acceleratorSelectionForeground", asfg, "CheckBoxMenuItem.acceleratorSelectionForeground", asfg, "RadioButtonMenuItem.acceleratorSelectionForeground", asfg }; return result; } @Override public Object[] createLookAndFeelCustomizationKeysAndValues() { Preferences prefs = NbPreferences.forModule(DarculaLAFPanel.class); boolean useStretchedTabs = prefs.getBoolean(DarculaLAFOptionsPanelController.STRETCHED_TABS_BOOLEAN, false); if (useStretchedTabs) { // stretch view tabs System.setProperty("winsys.stretching_view_tabs", "true"); // stretching view tabs seems to be causing resize problems System.setProperty("NB.WinSys.Splitter.Respect.MinimumSize.Enabled", "false"); } Font controlFont = Font.decode(DEFAULT_FONT); Integer in = (Integer) UIManager.get(CUSTOM_FONT_SIZE); //NOI18N if (in != null) { controlFont = Font.decode(FONT_DEFAULT_NAME + " " + in); } boolean overrideFontOption = prefs.getBoolean(DarculaLAFOptionsPanelController.OVERRIDE_FONT_BOOLEAN, false); if (overrideFontOption) { String fontOption = prefs.get(DarculaLAFOptionsPanelController.FONT_STRING, DEFAULT_FONT); controlFont = Font.decode(fontOption); } /** * HtmlLabelUI sets the border color to BLUE for focused cells if * "Tree.selectionBorderColor" is same as background color (see lines * 230 - 247). Here we modify "Tree.selectionBorderColor" slightly. * Modification is not noticable to naked eye but enough to stop * HtmlLabelUI to set focused renderer border color to BLUE. */ Color c = UIManager.getColor("Tree.selectionBackground"); Color focusColor = new Color(c.getRed(), c.getGreen(), c.getBlue() + 1); int leftChildIndent = UIManager.getInt("Tree.leftChildIndent"); if (prefs.getBoolean(DarculaLAFOptionsPanelController.OVERRIDE_TREE_INDENT_BOOLEAN, false)) { leftChildIndent = prefs.getInt(DarculaLAFOptionsPanelController.TREE_INDENT_INT, leftChildIndent); } Object[] result = { // The assorted standard NetBeans metal font customizations CONTROLFONT, controlFont, SYSTEMFONT, controlFont, USERFONT, controlFont, MENUFONT, controlFont, WINDOWTITLEFONT, controlFont, SUBFONT, controlFont.deriveFont(Font.PLAIN, Math.min(controlFont.getSize() - 1, 6)), // Bug in JDK 1.5 thru b59 - pale blue is incorrectly returned for this "textInactiveText", Color.GRAY, /** * Work around a bug in windows which sets the text area font to * "MonoSpaced", causing all accessible dialogs to have monospaced text */ "TextArea.font", new GuaranteedValue("Label.font", controlFont), /** * HtmlLabelUI uses UIManager.getColor("text") to find background * color for unselected items. Make sure the background color used * by HtmlLabelUI is same with the LAF. */ "text", new Color(60, 63, 65), "textText", new Color(187, 187, 187), "infoText", new Color(187, 187, 187), "TabbedPaneUI", "com.revivius.nb.darcula.ui.DarkScrollButtonTabbedPaneUI", "LabelUI", "com.revivius.nb.darcula.ui.OptionsAwareLabelUI", "Label.font", controlFont, "ButtonUI", "com.revivius.nb.darcula.ui.ContentAreaAwareButtonUI", "Button.border", new ReducedInsetsDarculaButtonPainter(), "Button.font", controlFont, "ToggleButtonUI", "com.revivius.nb.darcula.ui.ContentAreaAwareToggleButtonUI", "ToggleButton.border", new ReducedInsetsDarculaButtonPainter(), "ToggleButton.font", controlFont, "ToolBarUI", "com.revivius.nb.darcula.ui.RolloverToolBarUI", "ToolBar.font", controlFont, "SplitPaneUI", "com.revivius.nb.darcula.ui.DarculaSplitPaneUI", SPINNERFONT, controlFont, "Spinner.font", controlFont, /** * #31 * Icon provided by Aqua LAF is not visible on dark background * provide default Metal arrow icon for all LAFs */ "Menu.arrowIcon", new ProxyLazyValue("javax.swing.plaf.metal.MetalIconFactory", "getMenuArrowIcon"), "Menu.acceleratorFont", controlFont, "Menu.font", controlFont, "Table.font", controlFont, "Table.ascendingSortIcon", new ImageIcon(DarculaLFCustoms.class.getResource("column-asc.png")), "Table.descendingSortIcon", new ImageIcon(DarculaLFCustoms.class.getResource("column-desc.png")), "Table.focusCellHighlightBorder", new TransparentBorder(), "TableHeader.cellBorder", new InreasedInsetsTableHeaderBorder(), "TableHeader.font", controlFont, "TitledBorder.border", BorderFactory.createLineBorder(new Color(41, 43, 45), 1), "TitledBorder.font", controlFont, "MenuItem.acceleratorForeground", new Color(238, 238, 238), "MenuItem.acceleratorFont", controlFont, "MenuItem.font", controlFont, LISTFONT, controlFont, "List.font", controlFont, "List.focusCellHighlightBorder", new TransparentBorder(), "TreeUI", "com.revivius.nb.darcula.ui.IndentAwareTreeUI", TREEFONT, controlFont, "Tree.font", controlFont, "Tree.closedIcon", new ImageIcon(DarculaLFCustoms.class.getResource("open.png")), "Tree.openIcon", new ImageIcon(DarculaLFCustoms.class.getResource("open.png")), "Tree.selectionBorderColor", focusColor, // Use calculateD border color for HtmlLabelUI. "Tree.leftChildIndent", leftChildIndent, // FileChooser icons "FileView.directoryIcon", new ImageIcon(DarculaLFCustoms.class.getResource("closed.png")), "FileView.fileIcon", new ImageIcon(DarculaLFCustoms.class.getResource("file.png")), "FileChooser.newFolderIcon", new ImageIcon(DarculaLFCustoms.class.getResource("newFolder.png")), "FileChooser.upFolderIcon", new ImageIcon(DarculaLFCustoms.class.getResource("upFolder.png")), "FileChooser.homeFolderIcon", new ImageIcon(DarculaLFCustoms.class.getResource("homeFolder.png")), "FileChooser.detailsViewIcon", new ImageIcon(DarculaLFCustoms.class.getResource("detailsView.png")), "FileChooser.listViewIcon", new ImageIcon(DarculaLFCustoms.class.getResource("listView.png")), "FileChooser.computerIcon", new ImageIcon(DarculaLFCustoms.class.getResource("computer.png")), "FileChooser.hardDriveIcon", new ImageIcon(DarculaLFCustoms.class.getResource("hardDrive.png")), "FileChooser.floppyDriveIcon", new ImageIcon(DarculaLFCustoms.class.getResource("floppyDrive.png")), "CheckBox.font", controlFont, "CheckBoxMenuItem.acceleratorFont", controlFont, "CheckBoxMenuItem.font", controlFont, "CheckBoxMenuItem.acceleratorForeground", new Color(238, 238, 238), "ColorChooser.font", controlFont, "ComboBox.font", controlFont, "EditorPane.font", controlFont, "FormattedTextField.font", controlFont, "IconButton.font", controlFont, "InternalFrame.optionDialogTitleFont", controlFont, "InternalFrame.paletteTitleFont", controlFont, "InternalFrame.titleFont", controlFont, "MenuBar.font", controlFont, "OptionPane.buttonFont", controlFont, "OptionPane.font", controlFont, "OptionPane.messageFont", controlFont, "OptionPane.messageForeground", new Color(187, 187, 187), PANELFONT, controlFont, "Panel.font", controlFont, "PasswordField.font", controlFont, "PopupMenu.font", controlFont, "ProgressBar.font", controlFont, "RadioButton.font", controlFont, "RadioButtonMenuItem.acceleratorFont", controlFont, "RadioButtonMenuItem.font", controlFont, "RadioButtonMenuItem.acceleratorForeground", new Color(238, 238, 238), "ScrollPane.font", controlFont, "Slider.font", controlFont, "TabbedPane.font", controlFont, //"TabbedPane.smallFont", controlFont, "TextArea.font", controlFont, "TextField.font", controlFont, "TextPane.font", controlFont, "ToolTip.font", controlFont, "ToolTip.border", BorderFactory.createLineBorder(new Color(154, 154, 102)), "ToolTip.borderInactive", BorderFactory.createLineBorder(new Color(154, 154, 102)), "ToolTip.foregroundInactive", new Color(187, 187, 187), "ToolTip.backgroundInactive", new Color(92, 92, 66), "Viewport.font", controlFont, }; removeEnterFromTreeInputMap(); replaceSearchNotFoundColor(); replaceGlyphGutterLineColor(); replaceFormDesignerGapBorderColors(); replaceLFCustomsTextFgColors(); replaceCompletionColors(); replaceSQLCompletionColumnColor(); replaceJSPCompletionColor(); replaceHTMLCompletionColor(); replaceCSSPreprocessorCompletionColors(); replaceProjectTabColors(); return result; } @Override public Object[] createApplicationSpecificKeysAndValues() { UIBootstrapValue editorTabsUI = new Windows8EditorColorings( "org.netbeans.swing.tabcontrol.plaf.Windows8EditorTabDisplayerUI"); Object viewTabsUI = editorTabsUI.createShared( "org.netbeans.swing.tabcontrol.plaf.Windows8ViewTabDisplayerUI"); Object propertySheetValues = new Windows8PropertySheetColorings(); Object[] result = { // enable _dark postfix for resource loading "nb.dark.theme", Boolean.TRUE, "nb.wizard.hideimage", Boolean.TRUE, // main toolbar "Nb.MainWindow.Toolbar.Dragger", "com.revivius.nb.darcula.ToolbarXP", "Nb.MainWindow.Toolbar.Border", BorderFactory.createMatteBorder(1, 0, 0, 0, new Color(41, 43, 45)), "Nb.ToolBar.border", BorderFactory.createEmptyBorder(), EDITOR_TAB_DISPLAYER_UI, editorTabsUI, VIEW_TAB_DISPLAYER_UI, viewTabsUI, SLIDING_BUTTON_UI, "org.netbeans.swing.tabcontrol.plaf.WinXPSlidingButtonUI", PROPERTYSHEET_BOOTSTRAP, propertySheetValues, SCROLLPANE_BORDER, BorderFactory.createLineBorder(new Color(41, 43, 45)), SCROLLPANE_BORDER_COLOR, new Color(41, 43, 45), EDITOR_TOOLBAR_BORDER, BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(41, 43, 45)), EDITOR_ERRORSTRIPE_SCROLLBAR_INSETS, new Insets(16, 0, 16, 0), DESKTOP_BACKGROUND, Color.RED, DESKTOP_BORDER, BorderFactory.createEmptyBorder(), WORKPLACE_FILL, Color.RED, DESKTOP_SPLITPANE_BORDER, BorderFactory.createEmptyBorder(), SPLIT_PANE_DIVIDER_SIZE_VERTICAL, 2, SPLIT_PANE_DIVIDER_SIZE_HORIZONTAL, 2, WARNING_FOREGROUND, new Color(254, 183, 24), ERROR_FOREGROUND, new Color(255, 102, 102), // quicksearch "nb.quicksearch.border", BorderFactory.createEmptyBorder(), // progress ui "nb.progress.cancel.icon", ImageUtilities.loadImage("org/openide/awt/resources/mac_close_rollover_dark.png", false), "nb.progress.cancel.icon.mouseover", ImageUtilities.loadImage("org/openide/awt/resources/mac_close_enabled_dark.png", false), "nb.progress.cancel.icon.pressed", ImageUtilities.loadImage("org/openide/awt/resources/mac_close_pressed_dark.png", false), // explorer views "nb.explorer.unfocusedSelBg", new Color(13, 41, 62), "nb.explorer.unfocusedSelFg", new Color(187, 187, 187), "nb.explorer.noFocusSelectionBackground", new Color(13, 41, 62), "nb.explorer.noFocusSelectionForeground", new Color(187, 187, 187), "ETableHeader.ascendingIcon", new ImageIcon(DarculaLFCustoms.class.getResource("column-asc.png")), "ETableHeader.descendingIcon", new ImageIcon(DarculaLFCustoms.class.getResource("column-desc.png")), // popup switcher "nb.popupswitcher.border", BorderFactory.createLineBorder(new Color(45, 45, 45)), // debugger "nb.debugger.debugging.currentThread", new Color(30, 80, 28), "nb.debugger.debugging.highlightColor", new Color(40, 60, 38), "nb.debugger.debugging.BPHits", new Color(65, 65, 0), "nb.debugger.debugging.bars.BPHits", new Color(120, 120, 25), "nb.debugger.debugging.bars.currentThread", new Color(40, 100, 35), // heapview "nb.heapview.border1", new Color(113, 113, 113), "nb.heapview.border2", new Color(91, 91, 95), "nb.heapview.border3", new Color(128, 128, 128), "nb.heapview.foreground", new Color(222, 222, 222), "nb.heapview.background1", new Color(53, 56, 58), "nb.heapview.background2", new Color(50, 66, 114), "nb.heapview.grid1.start", new Color(97, 95, 87), "nb.heapview.grid1.end", new Color(98, 96, 88), "nb.heapview.grid2.start", new Color(99, 97, 90), "nb.heapview.grid2.end", new Color(101, 99, 92), "nb.heapview.grid3.start", new Color(102, 101, 93), "nb.heapview.grid3.end", new Color(105, 103, 95), "nb.heapview.grid4.start", new Color(107, 105, 97), "nb.heapview.grid4.end", new Color(109, 107, 99), // bug tracking "nb.bugtracking.comment.background", new Color(59, 63, 64), "nb.bugtracking.comment.foreground", new Color(187, 187, 187), "nb.bugtracking.label.highlight", new Color(205, 205, 0), "nb.bugtracking.table.background", new Color(59, 63, 64), "nb.bugtracking.table.background.alternate", new Color(69, 73, 74), "nb.bugtracking.new.color", new Color(73, 210, 73), "nb.bugtracking.modified.color", new Color(26, 184, 255), "nb.bugtracking.obsolete.color", new Color(142, 142, 142), "nb.bugtracking.conflict.color", new Color(255, 100, 100), // db.dataview "nb.dataview.table.grid", new Color(91, 91, 95), "nb.dataview.table.altbackground", new RelativeColor(new Color(0, 0, 0), new Color(20, 20, 20), "Table.background"), "nb.dataview.tablecell.focused", new Color(13, 41, 62), "nb.dataview.tablecell.edited.selected.foreground", new Color(255, 184, 26), "nb.dataview.tablecell.edited.unselected.foreground", new Color(26, 184, 255), // form designer "nb.formdesigner.gap.fixed.color", new Color(70, 73, 75), "nb.formdesigner.gap.resizing.color", new Color(66, 69, 71), "nb.formdesigner.gap.min.color", new Color(78, 81, 83), // link "nb.html.link.foreground", new Color(125, 160, 225), //NOI18N "nb.html.link.foreground.hover", new Color(13, 41, 62), //NOI18N "nb.html.link.foreground.visited", new Color(125, 160, 225), //NOI18N "nb.html.link.foreground.focus", new Color(13, 41, 62), //NOI18N // startpage "nb.startpage.defaultbackground", Boolean.TRUE, "nb.startpage.defaultbuttonborder", Boolean.TRUE, "nb.startpage.bottombar.background", new Color(13, 41, 62), "nb.startpage.topbar.background", new Color(13, 41, 62), "nb.startpage.border.color", new Color(13, 41, 62), "nb.startpage.tab.border1.color", new Color(13, 41, 62), "nb.startpage.tab.border2.color", new Color(13, 41, 62), "nb.startpage.rss.details.color", new Color(187, 187, 187), "nb.startpage.rss.header.color", new Color(125, 160, 225), "nb.startpage.contentheader.color1", new Color(12, 33, 61), "nb.startpage.contentheader.color2", new Color(16, 24, 42), // autoupdate "nb.autoupdate.search.highlight", new Color(13, 41, 62), // notification displayer balloon "nb.core.ui.balloon.defaultGradientStartColor", new Color(92, 92, 66), "nb.core.ui.balloon.defaultGradientFinishColor", new Color(92, 92, 66), "nb.core.ui.balloon.mouseOverGradientStartColor", new Color(92, 92, 66), "nb.core.ui.balloon.mouseOverGradientFinishColor", new Color(92, 92, 66).brighter(), // git "nb.versioning.added.color", new Color(73, 210, 73), "nb.versioning.modified.color", new Color(26, 184, 255), "nb.versioning.deleted.color", new Color(255, 175, 175), "nb.versioning.conflicted.color", new Color(255, 100, 100), "nb.versioning.ignored.color", new Color(142, 142, 142), "nb.versioning.textannotation.color", Color.WHITE, "nb.versioning.tooltip.background.color", new Color(92, 92, 66), // diff "nb.diff.added.color", new Color(43, 85, 43), "nb.diff.changed.color", new Color(40, 85, 112), "nb.diff.deleted.color", new Color(85, 43, 43), "nb.diff.applied.color", new Color(68, 113, 82), "nb.diff.notapplied.color", new Color(67, 105, 141), "nb.diff.unresolved.color", new Color(130, 30, 30), "nb.diff.sidebar.deleted.color", new Color(85, 43, 43), "nb.diff.sidebar.changed.color", new Color(30, 75, 112), // output "nb.output.backgorund", new Color(43, 43, 43), "nb.output.foreground", new Color(187, 187, 187), "nb.output.input", new Color(0, 127, 0), "nb.output.err.foreground", new Color(255, 107, 104), "nb.output.link.foreground", new Color(126, 174, 241), "nb.output.link.foreground.important", new Color(126, 174, 241), "nb.output.warning.foreground", new Color(205, 205, 0), "nb.output.failure.foreground", new Color(255, 107, 104), "nb.output.success.foreground", new Color(112, 255, 112), "nb.output.debug.foreground", new Color(145, 145, 145), "textHighlight", new Color(240, 119, 70), }; result = maybeEnableIconFilter(result); return UIUtils_addInputMapsWithoutCtrlPageUpAndCtrlPageDown(result); } /** * Fixes https://github.com/Revivius/nb-darcula/issues/114 * * @param result * @return */ private Object[] UIUtils_addInputMapsWithoutCtrlPageUpAndCtrlPageDown(Object[] result) { /** * Took the idea of org.netbeans.swing.plaf.metal.MetalLFCustoms.createApplicationSpecificKeysAndValues() to call * org.netbeans.swing.plaf.util.UIUtils.addInputMapsWithoutCtrlPageUpAndCtrlPageDown(Object[]). *
* But it is module-private, so call it via reflections */ ClassLoader loader = Lookup.getDefault().lookup(ClassLoader.class); if (loader == null) { loader = this.getClass().getClassLoader(); } try { Class claszz = loader.loadClass("org.netbeans.swing.plaf.util.UIUtils"); Method method = claszz.getMethod("addInputMapsWithoutCtrlPageUpAndCtrlPageDown", Object[].class); Object[] updatedResult = (Object[]) method.invoke(null, new Object[]{result}); return updatedResult; } catch (Exception ex) { //ignore Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Cannot setup input map", ex); } return result; } private class Windows8EditorColorings extends UIBootstrapValue.Lazy { public Windows8EditorColorings(String name) { super(name); } @Override public Object[] createKeysAndValues() { return new Object[]{ //selected & focused TAB_FOCUS_FILL_UPPER, new Color(75, 110, 175), TAB_FOCUS_FILL_LOWER, new Color(65, 81, 109), //no selection, no focus TAB_UNSEL_FILL_UPPER, new Color(77, 80, 84), TAB_UNSEL_FILL_LOWER, new Color(56, 58, 60), //selected, no focus TAB_SEL_FILL, new Color(100, 104, 107), //no selection, mouse over TAB_MOUSE_OVER_FILL_UPPER, new Color(114, 119, 122), TAB_MOUSE_OVER_FILL_LOWER, new Color(98, 101, 104), TAB_ATTENTION_FILL_UPPER, new Color(255, 255, 128), TAB_ATTENTION_FILL_LOWER, new Color(230, 200, 64), TAB_BORDER, new Color(41, 43, 45), TAB_SEL_BORDER, new Color(41, 43, 45), TAB_BORDER_INNER, new Color(70, 72, 74), //Borders for the tab control EDITOR_TAB_OUTER_BORDER, BorderFactory.createEmptyBorder(), EDITOR_TAB_CONTENT_BORDER, BorderFactory.createCompoundBorder( new MatteBorder(0, 0, 1, 0, new Color(41, 43, 45)), BorderFactory.createEmptyBorder(0, 1, 0, 1) ), EDITOR_TAB_TABS_BORDER, BorderFactory.createEmptyBorder(), VIEW_TAB_OUTER_BORDER, BorderFactory.createEmptyBorder(), VIEW_TAB_CONTENT_BORDER, new MatteBorder(0, 1, 1, 1, new Color(41, 43, 45)), VIEW_TAB_TABS_BORDER, BorderFactory.createEmptyBorder() }; } } private class Windows8PropertySheetColorings extends UIBootstrapValue.Lazy { public Windows8PropertySheetColorings() { super("propertySheet"); //NOI18N } @Override public Object[] createKeysAndValues() { return new Object[]{ PROPSHEET_BACKGROUND, new Color(69, 73, 74), PROPSHEET_SELECTION_BACKGROUND, new Color(75, 110, 175), PROPSHEET_SELECTION_FOREGROUND, Color.WHITE, PROPSHEET_SET_BACKGROUND, new Color(82, 85, 86), PROPSHEET_SET_FOREGROUND, Color.WHITE, PROPSHEET_SELECTED_SET_BACKGROUND, new Color(75, 110, 175), PROPSHEET_SELECTED_SET_FOREGROUND, Color.WHITE, PROPSHEET_DISABLED_FOREGROUND, new Color(161, 161, 146), PROPSHEET_BUTTON_FOREGROUND, new Color(187, 187, 187),}; } } /** * Enables invert filter for icons if user requested. */ private Object[] maybeEnableIconFilter(Object[] defaults) { if (NbPreferences.forModule(DarculaLAFPanel.class).getBoolean("invertIcons", false)) { return appendToArray(defaults, "nb.imageicon.filter", new DarkIconFilter()); } return defaults; } private Object[] appendToArray(Object[] result, final String key, final Object value) { result = Arrays.copyOf(result, result.length + 2); result[result.length - 2] = key; result[result.length - 1] = value; return result; } /** * DarculaLaf:L354-L358 registers ENTER to invoke 'toggle' action. This seems * to cause problems as reported in #14 because enter key can not invoke * default button in dialogs. */ private void removeEnterFromTreeInputMap() { // Make ENTER work in JTrees InputMap treeInputMap = (InputMap) UIManager.get("Tree.focusInputMap"); if (treeInputMap != null) { // it's really possible. For example, GTK+ doesn't have such map treeInputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)); } } /** * NOT_FOUND color is hardcoded, should be taken from UIManager. * Use reflection as in DefaultOutlineCellRenderer. */ private static final String SEARCH_BAR_CLASS = "org.netbeans.modules.editor.search.SearchBar"; private static final String NOT_FOUND_COLOR_FIELD = "NOT_FOUND"; private void replaceSearchNotFoundColor() { replaceFieldValue(SEARCH_BAR_CLASS, NOT_FOUND_COLOR_FIELD, new Color(255, 102, 102)); } /** * DEFAULT_GUTTER_LINE color is hardcoded, should be taken from UIManager. * Use reflection as in DefaultOutlineCellRenderer. */ private static final String GLYPH_GUUTER_CLASS = "org.netbeans.editor.GlyphGutter"; private static final String DEFAULT_GUTTER_LINE_COLOR_FIELD = "DEFAULT_GUTTER_LINE"; private void replaceGlyphGutterLineColor() { replaceFieldValue(GLYPH_GUUTER_CLASS, DEFAULT_GUTTER_LINE_COLOR_FIELD, new Color(136, 136, 136)); } /** * GAP_BORDER_COLOR and SAW_COLOR are hardcoded, should be taken from UIManager. * Use reflection as in DefaultOutlineCellRenderer. */ private static final String FORMDESIGNER_LAYOUT_PAINTER_CLASS = "org.netbeans.modules.form.layoutdesign.LayoutPainter"; private static final String GAP_BORDER_COLOR_FIELD = "gapBorderColor"; private static final String SAW_COLOR_FIELD = "sawColor"; private void replaceFormDesignerGapBorderColors() { replaceFieldValue(FORMDESIGNER_LAYOUT_PAINTER_CLASS, GAP_BORDER_COLOR_FIELD, new Color(49, 53, 54)); replaceFieldValue(FORMDESIGNER_LAYOUT_PAINTER_CLASS, SAW_COLOR_FIELD, new Color(49, 53, 54)); } /** * LFCustoms.getTextFgColor() && LFCustoms.getTextFgColorHTML() uses * windowText. DarculaLaf does not override windowText which is initialized * to Color.BLACK by BasicLookAndFeel (DarculaLaf uses BasicLookAndFeel * with reflection) */ private static final String TEXT_FG_COLOR_HTML_FIELD = "textFgColorHTML"; private static final String TEXT_FG_COLOR_FIELD = "textFgColor"; private void replaceLFCustomsTextFgColors() { replaceFieldValue(LFCustoms.class, TEXT_FG_COLOR_FIELD, new Color(187, 187, 187)); replaceFieldValue(LFCustoms.class, TEXT_FG_COLOR_HTML_FIELD, ""); } /** * #21, #26 * fixes code completion colors for all languages (at least for those extending GsfCompletionItem) */ private static final String GSF_COMPLETION_FORMATTER_CLASS = "org.netbeans.modules.csl.editor.completion.GsfCompletionItem$CompletionFormatter"; private static final String PARAMETER_NAME_COLOR_FIELD = "PARAMETER_NAME_COLOR"; //getHTMLColor(160, 96, 1); private static final String CLASS_COLOR_FIELD = "CLASS_COLOR"; // getHTMLColor(86, 0, 0); private static final String PKG_COLOR_FIELD = "PKG_COLOR"; // getHTMLColor(128, 128, 128); private static final String KEYWORD_COLOR_FIELD = "KEYWORD_COLOR"; //getHTMLColor(0, 0, 153); private static final String FIELD_COLOR_FIELD = "FIELD_COLOR"; // getHTMLColor(0, 134, 24); private static final String VARIABLE_COLOR_FIELD = "VARIABLE_COLOR"; // getHTMLColor(0, 0, 124); private static final String CONSTRUCTOR_COLOR_FIELD = "CONSTRUCTOR_COLOR"; // getHTMLColor(178, 139, 0); private static final String INTERFACE_COLOR_FIELD = "INTERFACE_COLOR"; // getHTMLColor(64, 64, 64); private static final String PARAMETERS_COLOR_FIELD = "PARAMETERS_COLOR"; // getHTMLColor(128, 128, 128); private void replaceCompletionColors() { replaceFieldValue(GSF_COMPLETION_FORMATTER_CLASS, PARAMETER_NAME_COLOR_FIELD, getHTMLColor(new Color(255, 198, 109))); replaceFieldValue(GSF_COMPLETION_FORMATTER_CLASS, CLASS_COLOR_FIELD, getHTMLColor(new Color(214, 128, 128))); replaceFieldValue(GSF_COMPLETION_FORMATTER_CLASS, PKG_COLOR_FIELD, getHTMLColor(new Color(128, 214, 128))); replaceFieldValue(GSF_COMPLETION_FORMATTER_CLASS, KEYWORD_COLOR_FIELD, getHTMLColor(new Color(180, 180, 255))); replaceFieldValue(GSF_COMPLETION_FORMATTER_CLASS, FIELD_COLOR_FIELD, getHTMLColor(new Color(0, 202, 88))); replaceFieldValue(GSF_COMPLETION_FORMATTER_CLASS, VARIABLE_COLOR_FIELD, getHTMLColor(new Color(0, 192, 255))); replaceFieldValue(GSF_COMPLETION_FORMATTER_CLASS, CONSTRUCTOR_COLOR_FIELD, getHTMLColor(new Color(178, 139, 0))); replaceFieldValue(GSF_COMPLETION_FORMATTER_CLASS, INTERFACE_COLOR_FIELD, getHTMLColor(new Color(214, 128, 128))); replaceFieldValue(GSF_COMPLETION_FORMATTER_CLASS, PARAMETERS_COLOR_FIELD, getHTMLColor(new Color(64, 128, 64))); } /** * #67, Column color for SQL */ private static final String SQL_COMPLETION_ITEM_CLASS = "org.netbeans.modules.db.sql.editor.completion.SQLCompletionItem"; private static final String COLUMN_COLOR_FIELD = "COLUMN_COLOR"; // getHtmlColor(7, 7, 171); // NOI18N private void replaceSQLCompletionColumnColor() { replaceFieldValue(SQL_COMPLETION_ITEM_CLASS, COLUMN_COLOR_FIELD, getHTMLColor(new Color(0, 202, 88))); } /** * JSP completion colors */ private static final String JSP_COMPLETION_ITEM_CLASS = "org.netbeans.modules.web.core.syntax.completion.api.JspCompletionItem"; private static final String JSP_COLOR_BASE_COMPLETION = "COLOR_BASE_COMPLETION"; private void replaceJSPCompletionColor() { replaceFieldValue(JSP_COMPLETION_ITEM_CLASS, JSP_COLOR_BASE_COMPLETION, new Color(204, 105, 50)); } /** * #106 * HTML completion colors for HTML Tags and Custom Tags */ private static final String HTML_COMPLETION_ITEM_CLASS = "org.netbeans.modules.html.editor.api.completion.HtmlCompletionItem$Tag"; private static final String CUSTOM_TAG_COMPLETION_ITEM_CLASS = "org.netbeans.modules.html.custom.CustomTagCompletionItem"; private static final String HTML_DEFAULT_FG_COLOR = "DEFAULT_FG_COLOR"; private void replaceHTMLCompletionColor() { replaceFieldValue(HTML_COMPLETION_ITEM_CLASS, HTML_DEFAULT_FG_COLOR, new Color(232, 191, 106)); replaceFieldValue(CUSTOM_TAG_COMPLETION_ITEM_CLASS, HTML_DEFAULT_FG_COLOR, new Color(64, 127, 255)); } /** * #91, CSS selector and preprocessor completion colors (LESS and SASS) */ private static final String CP_COMPLETION_ITEM_CLASS = "org.netbeans.modules.css.prep.editor.CPCompletionItem"; private static final String CP_LHS_COLOR_FIELD = "COLOR"; private static final String CP_RHS_COLOR_FIELD = "ORIGIN_COLOR"; private void replaceCSSPreprocessorCompletionColors() { replaceFieldValue(CP_COMPLETION_ITEM_CLASS, CP_LHS_COLOR_FIELD, new Color(0, 164, 164)); replaceFieldValue(CP_COMPLETION_ITEM_CLASS, CP_RHS_COLOR_FIELD, new Color(255, 255, 255)); } /** * #85, #88 * Tab colors for files belonging to same project */ private static final String PROJECT_COLOR_TAB_DECORATOR_CLASS = "org.netbeans.core.multitabs.impl.ProjectColorTabDecorator"; private static final String BACKGROUND_COLORS_FIELD = "backGroundColors"; private void replaceProjectTabColors() { List backgroundColors = new ArrayList(); backgroundColors.add(new Color(96, 135, 117)); backgroundColors.add(new Color(135, 101, 101)); backgroundColors.add(new Color(135, 127, 94)); backgroundColors.add(new Color(96, 119, 135)); backgroundColors.add(new Color(121, 135, 89)); backgroundColors.add(new Color(135, 105, 89)); backgroundColors.add(new Color(108, 135, 96)); backgroundColors.add(new Color(107, 135, 38)); backgroundColors.add(new Color(118, 89, 135)); replaceFieldValue(PROJECT_COLOR_TAB_DECORATOR_CLASS, BACKGROUND_COLORS_FIELD, backgroundColors); } private static String getHTMLColor(Color c) { return ""; //NOI18N } private void replaceFieldValue(String className, String fieldName, Object value) { Class sbClass = null; try { sbClass = ClassLoader.getSystemClassLoader().loadClass(className); } catch (ClassNotFoundException ex) { try { sbClass = Thread.currentThread().getContextClassLoader().loadClass(className); } catch (ClassNotFoundException ex1) { try { ClassLoader systemClassLoader = (ClassLoader) Lookup.getDefault().lookup(ClassLoader.class); if (systemClassLoader != null) { sbClass = systemClassLoader.loadClass(className); } } catch (ClassNotFoundException ex2) { Logger.getLogger(DarculaLFCustoms.class.getName()).log(Level.INFO, "Can not find class, will not be able to replace its field...", ex2); } } } catch (SecurityException ex) { Logger.getLogger(DarculaLFCustoms.class.getName()).log(Level.INFO, "Can not find class, will not be able to replace its field...", ex); } catch (IllegalArgumentException ex) { Logger.getLogger(DarculaLFCustoms.class.getName()).log(Level.INFO, "Can not find class, will not be able to replace its field...", ex); } if (sbClass == null) { return; } replaceFieldValue(sbClass, fieldName, value); } private void replaceFieldValue(Class clazz, String fieldName, Object value) { try { Field field = clazz.getDeclaredField(fieldName); field.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); field.set(null, value); } catch (IllegalAccessException ex) { Logger.getLogger(DarculaLFCustoms.class.getName()).log(Level.INFO, "Can not replace field...", ex); } catch (NoSuchFieldException ex) { Logger.getLogger(DarculaLFCustoms.class.getName()).log(Level.INFO, "Can not replace field...", ex); } catch (SecurityException ex) { Logger.getLogger(DarculaLFCustoms.class.getName()).log(Level.INFO, "Can not replace field...", ex); } } /** * Fixes https://github.com/Revivius/nb-darcula/issues/119 * * @author markiewb */ private static class TransparentBorder implements Border { @Override public Insets getBorderInsets(Component c) { return new Insets(1, 1, 1, 1); } @Override public boolean isBorderOpaque() { return false; } @Override public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { } } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/DarkIconFilter.java ================================================ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2013 Oracle and/or its affiliates. All rights reserved. * * Oracle and Java are registered trademarks of Oracle and/or its affiliates. * Other names may be trademarks of their respective owners. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common * Development and Distribution License("CDDL") (collectively, the * "License"). You may not use this file except in compliance with the * License. You can obtain a copy of the License at * http://www.netbeans.org/cddl-gplv2.html * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the * specific language governing permissions and limitations under the * License. When distributing the software, include this License Header * Notice in each file and include the License file at * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the * License Header, with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * If you wish your version of this file to be governed by only the CDDL * or only the GPL Version 2, indicate your decision by adding * "[Contributor] elects to include this software in this distribution * under the [CDDL or GPL Version 2] license." If you do not indicate a * single choice of license, a recipient has the option to distribute * your version of this file under either the CDDL, the GPL Version 2 or * to extend the choice of license to its licensees as provided above. * However, if you add GPL Version 2 code and therefore, elected the GPL * Version 2 license, then the option applies only if the new code is * made subject to such option by the copyright holder. * * Contributor(s): * * Portions Copyrighted 2013 Sun Microsystems, Inc. */ package com.revivius.nb.darcula; import java.awt.Color; import java.awt.image.RGBImageFilter; /** * COPIED from o.n.swing.laf.dark\src\org\netbeans\swing\laf\dark\DarkIconFilter.java * * For dark LaFs it inverts icon brightness (=inverts icon image to obtain dark icon, * then inverts its hue to restore original colors). * * @author P. Somol */ public class DarkIconFilter extends RGBImageFilter { /** in dark LaFs brighten all icons; 0.0f = no change, 1.0f = maximum brightening */ private static final float DARK_ICON_BRIGHTEN = 0.1f; @Override public int filterRGB(int x, int y, int color) { int a = color & 0xff000000; int rgb[] = decode(color); int inverted[] = invert(rgb); int result[] = invertHueBrighten(inverted, DARK_ICON_BRIGHTEN); return a | encode(result); } private int[] invert(int[] rgb) { return new int[]{255-rgb[0], 255-rgb[1], 255-rgb[2]}; } private int[] invertHueBrighten(int[] rgb, float brighten) { float hsb[] = new float[3]; Color.RGBtoHSB(rgb[0], rgb[1], rgb[2], hsb); return decode(Color.HSBtoRGB(hsb[0] > 0.5f ? hsb[0]-0.5f : hsb[0]+0.5f, hsb[1], hsb[2]+(1.0f-hsb[2])*brighten)); } private int[] decode(int rgb) { return new int[]{(rgb & 0x00ff0000) >> 16, (rgb & 0x0000ff00) >> 8, rgb & 0x000000ff}; } private int encode(int[] rgb) { return (toBoundaries(rgb[0]) << 16) | (toBoundaries(rgb[1]) << 8) | toBoundaries(rgb[2]); } private int toBoundaries(int color) { return Math.max(0,Math.min(255,color)); } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/GuaranteedValue.java ================================================ package com.revivius.nb.darcula; import javax.swing.*; import java.awt.*; /** * ------------------------------------------------------------ * Copy paste from o.n.swing.plaf because it is module private. * ------------------------------------------------------------ * * A simple mechanism for guaranteeing the presence of a value in UIDefaults. * Some look and feels (GTK/Synth) don't necessarily provide these colors, * resulting in null pointer exceptions. Since we want to make it easy to * write maintainable components, it is preferable to centralize guaranteeing * the value here, rather than have the codebase littered with null tests and * fallbacks for null colors. * * It will either take on the existing value if present, or used the passed * value if not present. If passed an array of UIManager keys, it will try * them in order, and use the first value that returns non-null from * UIManager.get(). * * Usage: *
 * UIManager.put (new GuaranteedValue("controlShadow", Color.LIGHT_GRAY));
 *   or
 * UIManager.put (new GuaranteedValue(new String[] {"Tree.foreground", 
 *    List.foreground", "textText"}, Color.BLACK));
 * 
* * It can also be used to ensure a value matches another value, with a fallback * if it is not present: *
 * UIManager.put("TextArea.font", new GuaranteedValue ("Label.font", new Font("Dialog", Font.PLAIN, 11)))
 *
 * @author  Tim Boudreau
 */
public class GuaranteedValue implements UIDefaults.LazyValue {
    private Object value;
    /** Creates a new instance of GuaranteedValue */
    public GuaranteedValue(String key, Object fallback) {
        //Be fail fast, so no random exceptions from random components later
        if (key == null || fallback == null) {
            throw new NullPointerException ("Null parameters: " + key + ',' + fallback);
        }
        
        value = UIManager.get(key);
        if (value == null) {
            value = fallback;
        }
    }
    
    public GuaranteedValue(String[] keys, Object fallback) {
        //Be fail fast, so no random exceptions from random components later
        if (keys == null || fallback == null) {
            throw new NullPointerException ("Null parameters: " + keys + ',' + fallback);
        }
        for (int i=0; i < keys.length; i++) {
            value = UIManager.get(keys[i]);
            if (value != null) {
                break;
            }
        }
        if (value == null) {
            value = fallback;
        }
    }
    
    public Object createValue(UIDefaults table) {
        return value;
    }
    
    /** Convenience getter of the value as a color - returns null if this
     * instance was used for some other type */
    public Color getColor() {
        Object o = createValue(null);
        if (o instanceof Color) {
            return (Color) o;
        } else {
            return null;
        }
    }

    public Font getFont() {
        Object o = createValue(null);
        if (o instanceof Font) {
            return (Font) o;
        } else {
            return null;
        }
    }
}


================================================
FILE: src/main/java/com/revivius/nb/darcula/Installer.java
================================================
package com.revivius.nb.darcula;

import com.bulenkov.darcula.DarculaLaf;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.Preferences;
import javax.swing.UIManager;
import org.openide.modules.ModuleInstall;
import org.openide.util.Lookup;
import org.openide.util.NbPreferences;
import org.openide.windows.WindowManager;

/**
 * Makes Darcula LAF available in preferred LAF combo, installs
 * DarculaLFCustoms, set Preferences and switch the editor color profile to
 * Darcula theme.
 *
 * @author Revivius
 */
public class Installer extends ModuleInstall {

    private static final String COLOR_MODEL_CLASS_NAME = "org.netbeans.modules.options.colors.ColorModel";

    private static boolean SWITCH_EDITOR_COLORS = false;

    @Override
    public void validate() throws IllegalStateException {
        Preferences prefs = NbPreferences.root().node("laf");
        if (!prefs.getBoolean("darcula.installed", false)) {
            prefs.put("laf", DarculaLaf.class.getName());
            SWITCH_EDITOR_COLORS = true;
        }
        prefs.putBoolean("darcula.installed", true);

        // to make LAF available in Tools > Options > Appearance > Look and Feel
        UIManager.installLookAndFeel(new UIManager.LookAndFeelInfo(DarculaLaf.NAME, DarculaLaf.class.getName()));
        UIManager.put("Nb.DarculaLFCustoms", new DarculaLFCustoms());
    }

    @Override
    public void restored() {
        if (SWITCH_EDITOR_COLORS) {
            WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
                @Override
                public void run() {
                    switchEditorColorsProfile();
                }
            });
        };
    }

    /**
     * Returns if possible to change color profile. Use reflection to
     * instantiate ColorModel (private package) class and get the current
     * profile.
     *
     * @return {@code true} if current profile not equals this theme profile
     * name or {@code false} otherwise.
     */
    private boolean isChangeEditorColorsPossible() {
        ClassLoader loader = Lookup.getDefault().lookup(ClassLoader.class);
        if (loader == null) {
            loader = Installer.class.getClassLoader();
        }
        try {
            Class claszz = loader.loadClass(COLOR_MODEL_CLASS_NAME);
            Object colorModel = claszz.newInstance();
            Method method = claszz.getDeclaredMethod("getCurrentProfile", new Class[0]);
            Object invokeResult = method.invoke(colorModel, new Object[0]);
            return invokeResult != null && !DarculaLaf.NAME.equals(invokeResult);
        } catch (Exception ex) {
            //ignore
            Logger.getLogger(Installer.class.getName()).log(Level.INFO, "Cannot get the current editor colors profile.", ex);
        }
        return false;
    }

    /**
     * Switch the editor color profile if possible. Use reflection to
     * instantiate ColorModel (private package) class and set the current
     * profile
     */
    private void switchEditorColorsProfile() {
        if (!isChangeEditorColorsPossible()) {
            return;
        }

        ClassLoader loader = Lookup.getDefault().lookup(ClassLoader.class);
        if (loader == null) {
            loader = Installer.class.getClassLoader();
        }
        try {
            Class classz = loader.loadClass(COLOR_MODEL_CLASS_NAME);
            Object colorModel = classz.newInstance();
            Method method = classz.getDeclaredMethod("setCurrentProfile", String.class);
            method.invoke(colorModel, DarculaLaf.NAME);

            // method call above changes the token colors but not annotation
            // colors. these two seems to solve the problem
            method = classz.getDeclaredMethod("getAnnotations", String.class);
            Object acs = method.invoke(colorModel, DarculaLaf.NAME);

            method = classz.getDeclaredMethod("setAnnotations", String.class, Collection.class);
            method.invoke(colorModel, DarculaLaf.NAME, acs);
        } catch (Exception ex) {
            //ignore
            Logger.getLogger(Installer.class.getName()).log(Level.INFO, "Cannot change editors colors profile.", ex);
        }
    }
}


================================================
FILE: src/main/java/com/revivius/nb/darcula/RelativeColor.java
================================================
package com.revivius.nb.darcula;

import javax.swing.*;
import java.awt.*;

/** 
 * ------------------------------------------------------------
 * Copy paste from o.n.swing.plaf because it is module private.
 * ------------------------------------------------------------
 *
 * A color which can be placed into UIDefaults, which is computed from:
 * 
    *
  • A base color, as defined in a UI spec - this might be the expected value * for window titlebars, for example
  • *
  • A target color, as defined in a UI spec, whose color is not the base * color, but has a relation to it (such as brighter or darker, or * hue shifted)
  • *
  • The actual color - which may differ from the base color if the user has * customized their UI them (for example, changing the color defaults in * Windows)
  • *
  • (optional) A color that the result must contrast with sufficiently that * text will be readable
  • *
* When constructing the real value, a color will be generated which has the * same relationship to the original value as the base color has to the target * color. * *

What this class is for

* A number of components in NetBeans have colors that should be based on a * color taken from the desktop theme. Swing provides a mechanism for getting * these colors, via UIManager, which will supply correct colors based on the * desktop theme for a variety of operating systems. *

* But often the color in a UI specification is not the same as, but related to * the color that should be used. For example, in windows classic, the tabs * have a gradient based on a light blue color. The color should be related to * the dark blue color normally used in Windows for window titles. However, * if the user has set the window titlebar color to red, a reddish color should * be used. *

* This class allows you to provide a base value (the default Windows * titlebar color, hardcoded) and a prototype value (the blue color that should * be used if the desktop colors are the defaults), and the actual * value retrieved from the UI. The instance of this class is then dropped * into UIDefaults; code can simply call * UIManager.getColor("someColor") and get the right color without * being cluttered with the details of deriving colors. * *

How it does what it does

* The base and prototype are split into HSB color components. The relationship * between the base and prototype values in saturation and brightness is then * computed. This same relationship is then applied to the actual value * as a function of the divergence between the base and actual values * such that the more a color diverges, the less the relationship is applied - * so that, if the base color is dark blue and the prototype color is light * blue, but the actual color is light yellow, you get light yellow (as opposed * to pure white, which a naive application of the relationship would get). * *

Note: It is possible to create cyclic * references between RelativeColor instances (for example, a RelativeColor * that has its own key as one of the keys it should fetch). Don't do that. * * @author Tim Boudreau */ public class RelativeColor implements UIDefaults.LazyValue { private Color value = null; private Color fallback = null; /** Creates a new instance of RelativeColor. * * @param base A Color or UIManager key for a color that the target color is related to * @param target A Color or UIManager key for a color that is what the target color should be if the * actual color is equal to the base color * @param actual Either a Color object or a UIManager String key resolvable * to a color, which represents the * actual color, which may or may not match the target color * @param mustContrast Either a Color object or a UIManager String key * resolvable to a color which must contrast sufficiently with the derived * color that text will be readable. This parameter may be null; the others * may not. */ public RelativeColor(Object base, Object target, Object actual, Object mustContrast) { if (base == null || target == null || actual == null) { throw new NullPointerException ("Null argument(s): " + base + ',' + target + ',' + actual + ',' + mustContrast); } if (base instanceof String) { baseColorKey = (String) base; } else { baseColor = (Color) base; } if (target instanceof String) { targetColorKey = (String) target; } else { targetColor = (Color) target; } if (actual instanceof String) { actualColorKey = (String) actual; } else { actualColor = (Color) actual; } if (mustContrast != null) { if (mustContrast instanceof String) { mustContrastColorKey = (String) mustContrast; } else { mustContrastColor = (Color) mustContrast; } } } /** Creates a new instance of RelativeColor. * * @param base A Color that the target color is related to * @param target A Color that is what the target color should be if the * actual color is equal to the base color * @param actual Either a Color object or a UIManager String key resolvable * to a color, which represents the * actual color, which may or may not match the target color * @param mustContrast Either a Color object or a UIManager String key * resolvable to a color which must contrast sufficiently with the derived * color that text will be readable */ public RelativeColor(Color base, Color target, Object actual) { this (base, target, actual, null); } public void clear() { value = null; if (actualColorKey != null) { actualColor = null; } if (targetColorKey != null) { targetColor = null; } if (mustContrastColorKey != null) { mustContrastColor = null; } if (baseColorKey != null) { baseColor = null; } } public Object createValue(UIDefaults table) { if (value != null) { return value; } Color actual = getActualColor(); Color base = getBaseColor(); if (actual.equals(base)) { value = getTargetColor(); } else { value = deriveColor (base, actual, getTargetColor()); } if (hasMustContrastColor()) { value = ensureContrast(value, getMustContrastColor()); } return value; } /** Convenience getter, as this class is reasonably useful for creating * derived colors without putting them into UIDefaults */ public Color getColor() { return (Color) createValue(null); } private Color targetColor = null; private String targetColorKey = null; private Color getTargetColor() { if (checkState (targetColor, targetColorKey)) { targetColor = fetchColor(targetColorKey); } return targetColor; } private Color baseColor = null; private String baseColorKey = null; private Color getBaseColor() { if (checkState (baseColor, baseColorKey)) { baseColor = fetchColor(baseColorKey); } return baseColor; } private Color mustContrastColor = null; private String mustContrastColorKey = null; private Color getMustContrastColor() { if (checkState (mustContrastColor, mustContrastColorKey)) { mustContrastColor = fetchColor(mustContrastColorKey); } return mustContrastColor; } private Color actualColor = null; private String actualColorKey = null; private Color getActualColor() { if (checkState (actualColor, actualColorKey)) { actualColor = fetchColor(actualColorKey); } return actualColor; } private boolean hasMustContrastColor() { return mustContrastColor != null || mustContrastColorKey != null; } /** Ensures that the key and color are not null, and returns true if the * color needs to be loaded. */ private boolean checkState(Color color, String key) { if (color == null && key == null) { throw new NullPointerException("Both color and key are null for " + this); } return color == null; } private Color fetchColor(String key) { //Todo - check for cyclic references Color result = UIManager.getColor(key); if (result == null) { result = fallback; } return result; } /** Does the actual leg-work of deriving the color */ static Color deriveColor (Color base, Color actual, Color target) { float[] baseHSB = Color.RGBtoHSB(base.getRed(), base.getGreen(), base.getBlue(), null); float[] targHSB = Color.RGBtoHSB(target.getRed(), target.getGreen(), target.getBlue(), null); float[] actualHSB = Color.RGBtoHSB(actual.getRed(), actual.getGreen(), actual.getBlue(), null); float[] resultHSB = new float[3]; float[] finalHSB = new float[3]; float[] diff = percentageDiff (actualHSB, baseHSB); resultHSB[0] = actualHSB[0] + (diff[0] * (targHSB[0] - baseHSB[0])); resultHSB[1] = actualHSB[1] + (diff[1] * (targHSB[1] - baseHSB[1])); resultHSB[2] = actualHSB[2] + (diff[2] * (targHSB[2] - baseHSB[2])); finalHSB[0] = saturate (resultHSB[0]); finalHSB[1] = saturate (resultHSB[1]); finalHSB[2] = saturate (resultHSB[2]); //If the target had *some* color, so should our result - if it pretty //much doesn't, redistribute some of the brightness to the saturation value if (targHSB[1] > 0.1 && resultHSB[1] <= 0.1) { resultHSB[1] = resultHSB[2] * 0.25f; resultHSB[2] = resultHSB[2] - (resultHSB[2] * 0.25f); } Color result = new Color (Color.HSBtoRGB(finalHSB[0], finalHSB[1], finalHSB[2])); return result; } private static float[] percentageDiff (float[] a, float[] b) { float[] result = new float[3]; for (int i=0; i < 3; i++) { result[i] = 1 - Math.abs(a[i] - b[i]); if (result[i] == 0) { result[i] = 1- a[i]; } } return result; } private static final void out (String nm, float[] f) { //XXX for debugging - deleteme StringBuffer sb = new StringBuffer(nm); sb.append(": "); for (int i=0; i < f.length; i++) { sb.append (Math.round(f[i] * 100)); if (i != f.length-1) { sb.append(','); sb.append(' '); } } System.err.println(sb.toString()); } /** Saturate a float value, clamping values below 0 to 0 and above 1 to 1 */ private static float saturate (float f) { return Math.max(0, Math.min(1, f)); } static Color ensureContrast (Color target, Color contrast) { //XXX - this needs some work. What it should really do: //Determine the distance from 0.5 for brightness and saturation of the contrasting color, to //determine the direction in which to adjust. Then adjust in that //direction as a function of the diff between 0.25 and 0.5 of the //diff between the colors...or something like that. The point is //there's a danger zone around 0.5 where things that should be //adjusted away from each other aren't being float[] contHSB = Color.RGBtoHSB(contrast.getRed(), contrast.getGreen(), contrast.getBlue(), null); float[] targHSB = Color.RGBtoHSB(target.getRed(), target.getGreen(), target.getBlue(), null); float[] resultHSB = new float[3]; System.arraycopy(targHSB, 0, resultHSB, 0, 3); float satDiff = Math.abs (targHSB[1] - contHSB[1]); float briDiff = Math.abs (targHSB[2] - contHSB[2]); if (targHSB[1] > 0.6 && resultHSB[1] > 0.6 || (briDiff < 0.45f && satDiff < 0.4f)) { resultHSB[1] /= 3; // System.err.println("adjusting saturation to " + resultHSB[1] + " from " + targHSB[1]); satDiff = Math.abs (targHSB[1] - contHSB[1]); } if (briDiff < 0.3 || (satDiff < 0.3 && briDiff < 0.5)) { float dir = 1.5f * (0.5f - contHSB[2]); resultHSB[2] = saturate (resultHSB[2] + dir); // System.err.println("adjusting brightness to " + resultHSB[2] + " from " + targHSB[2]); } Color result = new Color (Color.HSBtoRGB(resultHSB[0], resultHSB[1], resultHSB[2])); return result; } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/ToolbarXP.java ================================================ package com.revivius.nb.darcula; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import javax.swing.JPanel; import javax.swing.UIManager; /** * Copy paste from o.n.swing.plaf. * @author Revivius */ public final class ToolbarXP extends JPanel { /** Width of grip. */ private static final int GRIP_WIDTH = 7; /** Minimum size. */ private final Dimension dim; /** Maximum size. */ private final Dimension max; public ToolbarXP() { dim = new Dimension(GRIP_WIDTH, GRIP_WIDTH); max = new Dimension(GRIP_WIDTH, Integer.MAX_VALUE); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); int x = 3; for (int i = 4; i < getHeight() - 4; i += 4) { //first draw the rectangular highlight below each dot g.setColor(UIManager.getColor("controlLtHighlight").brighter()); //NOI18N g.fillRect(x + 1, i + 1, 2, 2); //Get the shadow color. We'll paint the darkest dot first, //and work our way to the lightest Color col = UIManager.getColor("controlShadow").brighter(); //NOI18N g.setColor(col); //draw the darkest dot g.drawLine(x + 1, i + 1, x + 1, i + 1); //Get the color components and calculate the amount each component //should increase per dot int red = col.getRed(); int green = col.getGreen(); int blue = col.getBlue(); //Get the default component background - we start with the dark //color, and for each dot, add a percentage of the difference //between this and the background color Color back = getBackground(); int rb = back.getRed(); int gb = back.getGreen(); int bb = back.getBlue(); //Get the amount to increment each component for each dot int incr = (rb - red) / 5; int incg = (gb - green) / 5; int incb = (bb - blue) / 5; //Increment the colors red += incr; green += incg; blue += incb; //Create a slightly lighter color and draw the dot col = new Color(red, green, blue); g.setColor(col); g.drawLine(x + 1, i, x + 1, i); //And do it for the next dot, and so on, for all four dots red += incr; green += incg; blue += incb; col = new Color(red, green, blue); g.setColor(col); g.drawLine(x, i + 1, x, i + 1); red += incr; green += incg; blue += incb; col = new Color(red, green, blue); g.setColor(col); g.drawLine(x, i, x, i); } } /** * @return minimum size */ @Override public Dimension getMinimumSize() { return dim; } @Override public Dimension getMaximumSize() { return max; } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/UIBootstrapValue.java ================================================ package com.revivius.nb.darcula; import javax.swing.UIDefaults; import javax.swing.UIManager; /** * ------------------------------------------------------------ * Copy paste from o.n.swing.plaf because it is module private. * ------------------------------------------------------------ * * Value that can be placed into UIDefaults, which will put additional items into * UIDefaults when its value is requested. *

* The idea is to avoid putting a lot of things that may not be used into * UIDefaults on startup. So, for example, the first time a tab control's UI * is requested, this value will return the string from which the UI can be * fetched - but first it will put the assorted keys and values that that UI * will need into UIDefaults. *

* Since multiple UIs may require the same things in UIDefaults, there is the * method createShared(), which will create another instance (really an inner * class instance) that shares the code and key/value pairs. Whichever is * asked for first will initialize the keys and values required. So the usage * pattern is something like: *

 * Object someKeysAndValues = new Object[] {"fooColor", Color.BLUE, "barColor", Color.RED};
 * UIBootstrapValue bv = new UIBootstrapValue ("com.foo.FnordUIClass", someKeysAndValues);
 * Object next = bv.createShared ("com.foo.ThiptUIClass");
 * UIManager.put ("FnordUI", bv);
 * UIManager.put ("ThiptUI", next);
 * 
* * @author Tim Boudreau */ public class UIBootstrapValue implements UIDefaults.LazyValue { private boolean installed = false; private final String uiClassName; protected Object[] defaults; /** Creates a new instance of UIBootstrapValue */ public UIBootstrapValue(String uiClassName, Object[] defaults) { this.defaults = defaults; this.uiClassName = uiClassName; } /** Create the value that UIDefaults will return. If the keys and values * the UI class we're representing requires have not yet been installed, * this will install them. */ public Object createValue(UIDefaults uidefaults) { if (!installed) { installKeysAndValues(uidefaults); } return uiClassName; } /** Install the defaults the UI we're representing will need to function */ private void installKeysAndValues(UIDefaults ui) { ui.putDefaults (getKeysAndValues()); installed = true; } public Object[] getKeysAndValues() { return defaults; } public void uninstall() { if (defaults == null) { return; } for (int i=0; i < defaults.length; i+=2) { UIManager.put (defaults[i], null); } //null defaults so a Meta instance won't cause us to do work twice defaults = null; } public String toString() { return getClass() + " for " + uiClassName; //NOI18N } /** Create another entry value to put in UIDefaults, which will also * trigger installing the keys and values, to ensure that they are only * added once, by whichever entry is asked for the value first. */ public UIDefaults.LazyValue createShared (String uiClassName) { return new Meta (uiClassName); } private class Meta implements UIDefaults.LazyValue { private String name; public Meta (String uiClassName) { this.name = uiClassName; } public Object createValue(javax.swing.UIDefaults uidefaults) { if (!installed) { installKeysAndValues(uidefaults); } return name; } public String toString() { return "Meta-" + super.toString() + " for " + uiClassName; //NOI18N } } public abstract static class Lazy extends UIBootstrapValue implements UIDefaults.LazyValue { public Lazy (String uiClassName) { super (uiClassName, null); } public Object[] getKeysAndValues() { if (defaults == null) { defaults = createKeysAndValues(); } return defaults; } public abstract Object[] createKeysAndValues(); } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/options/DarculaLAFOptionsPanelController.java ================================================ /* * Copyright 2016 markiewb. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.revivius.nb.darcula.options; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.prefs.PreferenceChangeEvent; import java.util.prefs.PreferenceChangeListener; import javax.swing.JComponent; import javax.swing.SwingUtilities; import org.netbeans.spi.options.OptionsPanelController; import org.openide.LifecycleManager; import org.openide.awt.NotificationDisplayer; import org.openide.util.HelpCtx; import org.openide.util.ImageUtilities; import org.openide.util.Lookup; import org.openide.util.NbPreferences; @OptionsPanelController.SubRegistration( location = "Appearance", displayName = "#AdvancedOption_DisplayName_DarculaLAF", keywords = "#AdvancedOption_Keywords_DarculaLAF", keywordsCategory = "Appearance/DarculaLAF" ) @org.openide.util.NbBundle.Messages({ "AdvancedOption_DisplayName_DarculaLAF=Darcula Look and Feel", "AdvancedOption_Keywords_DarculaLAF=darcula laf, dark, theme, font, laf" }) public final class DarculaLAFOptionsPanelController extends OptionsPanelController { public static final String OVERRIDE_FONT_BOOLEAN = "overrideFont"; public static final String FONT_STRING = "font"; public static final String OVERRIDE_TREE_INDENT_BOOLEAN = "overrideTreeIndent"; public static final String TREE_INDENT_INT = "treeIndent"; public static final String INVERT_ICONS_BOOLEAN = "invertIcons"; public static final String STRETCHED_TABS_BOOLEAN = "stretchedTabs"; private static final PreferenceChangeListener PREF_LISTENER = new PreferenceChangeListener() { @Override public void preferenceChange(PreferenceChangeEvent evt) { NotificationDisplayer.getDefault().notify( "Restart IDE", ImageUtilities.loadImageIcon("com/revivius/nb/darcula/options/restart.png", true), "Click here to restart IDE and apply new settings.", new ActionListener() { @Override public void actionPerformed(ActionEvent e) { LifecycleManager.getDefault().markForRestart(); LifecycleManager.getDefault().exit(); } } ); } }; static { NbPreferences.forModule(DarculaLAFPanel.class).addPreferenceChangeListener(PREF_LISTENER); } private DarculaLAFPanel panel; private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); private boolean changed; @Override public void update() { getPanel().load(); changed = false; } @Override public void applyChanges() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { getPanel().store(); changed = false; } }); } @Override public void cancel() { // need not do anything special, if no changes have been persisted yet } @Override public boolean isValid() { return getPanel().valid(); } @Override public boolean isChanged() { return changed; } @Override public HelpCtx getHelpCtx() { return null; // new HelpCtx("...ID") if you have a help set } @Override public JComponent getComponent(Lookup masterLookup) { return getPanel(); } @Override public void addPropertyChangeListener(PropertyChangeListener l) { pcs.addPropertyChangeListener(l); } @Override public void removePropertyChangeListener(PropertyChangeListener l) { pcs.removePropertyChangeListener(l); } private DarculaLAFPanel getPanel() { if (panel == null) { panel = new DarculaLAFPanel(this); } return panel; } void changed() { if (!changed) { changed = true; pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true); } pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null); } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/options/DarculaLAFPanel.form ================================================
================================================ FILE: src/main/java/com/revivius/nb/darcula/options/DarculaLAFPanel.java ================================================ /* * Copyright 2016 markiewb. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.revivius.nb.darcula.options; import com.revivius.nb.darcula.DarculaLFCustoms; import java.awt.Font; import java.beans.PropertyEditor; import java.beans.PropertyEditorManager; import java.util.prefs.Preferences; import javax.swing.UIManager; import org.netbeans.spi.options.OptionsPanelController; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; import org.openide.util.NbPreferences; @OptionsPanelController.Keywords( location = "Appearance", tabTitle = "Darcula Look and Feel", keywords = { "dark theme", "dark", "theme", "laf", "font", "look and feel", "darcula", "invert", "invert colors", "stretched", "stretched tabs", "tree indent", "indent" } ) public class DarculaLAFPanel extends javax.swing.JPanel { private final DarculaLAFOptionsPanelController controller; DarculaLAFPanel(DarculaLAFOptionsPanelController controller) { this.controller = controller; initComponents(); } public void reinitUI() { if (!cbFontSizeOverride.isSelected()) { lblFontName.setText(DarculaLFCustoms.DEFAULT_FONT); } lblFontName.setEnabled(cbFontSizeOverride.isSelected()); btnChooseFont.setEnabled(cbFontSizeOverride.isSelected()); spTreeIndent.setEnabled(cbTreeIndentOverride.isSelected()); lblTreeIndentPx.setEnabled(cbTreeIndentOverride.isSelected()); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ // //GEN-BEGIN:initComponents private void initComponents() { cbFontSizeOverride = new javax.swing.JCheckBox(); lblFontName = new javax.swing.JTextField(); btnChooseFont = new javax.swing.JButton(); cbInvertIcons = new javax.swing.JCheckBox(); cbStretchedTabs = new javax.swing.JCheckBox(); cbTreeIndentOverride = new javax.swing.JCheckBox(); spTreeIndent = new javax.swing.JSpinner(); lblTreeIndentPx = new javax.swing.JLabel(); org.openide.awt.Mnemonics.setLocalizedText(cbFontSizeOverride, org.openide.util.NbBundle.getMessage(DarculaLAFPanel.class, "DarculaLAFPanel.cbFontSizeOverride.text")); // NOI18N cbFontSizeOverride.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { cbFontSizeOverrideStateChanged(evt); } }); lblFontName.setEditable(false); lblFontName.setText(org.openide.util.NbBundle.getMessage(DarculaLAFPanel.class, "DarculaLAFPanel.lblFontName.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(btnChooseFont, org.openide.util.NbBundle.getMessage(DarculaLAFPanel.class, "DarculaLAFPanel.btnChooseFont.text")); // NOI18N btnChooseFont.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnChooseFontActionPerformed(evt); } }); org.openide.awt.Mnemonics.setLocalizedText(cbInvertIcons, org.openide.util.NbBundle.getMessage(DarculaLAFPanel.class, "DarculaLAFPanel.cbInvertIcons.text")); // NOI18N cbInvertIcons.addItemListener(new java.awt.event.ItemListener() { public void itemStateChanged(java.awt.event.ItemEvent evt) { cbInvertIconsItemStateChanged(evt); } }); org.openide.awt.Mnemonics.setLocalizedText(cbStretchedTabs, org.openide.util.NbBundle.getMessage(DarculaLAFPanel.class, "DarculaLAFPanel.cbStretchedTabs.text")); // NOI18N cbStretchedTabs.addItemListener(new java.awt.event.ItemListener() { public void itemStateChanged(java.awt.event.ItemEvent evt) { cbStretchedTabsItemStateChanged(evt); } }); org.openide.awt.Mnemonics.setLocalizedText(cbTreeIndentOverride, org.openide.util.NbBundle.getMessage(DarculaLAFPanel.class, "DarculaLAFPanel.cbTreeIndentOverride.text")); // NOI18N cbTreeIndentOverride.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { cbTreeIndentOverrideStateChanged(evt); } }); spTreeIndent.setModel(new javax.swing.SpinnerNumberModel(8, 4, 60, 1)); org.openide.awt.Mnemonics.setLocalizedText(lblTreeIndentPx, org.openide.util.NbBundle.getMessage(DarculaLAFPanel.class, "DarculaLAFPanel.lblTreeIndentPx.text")); // NOI18N javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(cbStretchedTabs, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(cbInvertIcons, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(cbFontSizeOverride) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblFontName, javax.swing.GroupLayout.PREFERRED_SIZE, 198, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnChooseFont)) .addGroup(layout.createSequentialGroup() .addComponent(cbTreeIndentOverride) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(spTreeIndent, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblTreeIndentPx))) .addGap(0, 222, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(cbFontSizeOverride) .addComponent(lblFontName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(btnChooseFont)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(cbTreeIndentOverride) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(spTreeIndent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lblTreeIndentPx))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(cbInvertIcons) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(cbStretchedTabs) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); }// //GEN-END:initComponents private void cbFontSizeOverrideStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_cbFontSizeOverrideStateChanged controller.changed(); reinitUI(); }//GEN-LAST:event_cbFontSizeOverrideStateChanged private void btnChooseFontActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnChooseFontActionPerformed PropertyEditor pe = PropertyEditorManager.findEditor(Font.class); Font f = Font.decode(lblFontName.getText()); pe.setValue(f); DialogDescriptor dd = new DialogDescriptor( pe.getCustomEditor(), "Font Chooser" ); dd.setOptions(new Object[]{ DialogDescriptor.OK_OPTION, DialogDescriptor.CANCEL_OPTION }); DialogDisplayer.getDefault().createDialog(dd).setVisible(true); if (dd.getValue() == DialogDescriptor.OK_OPTION) { f = (Font) pe.getValue(); lblFontName.setText(f.getName() + " " + f.getSize()); controller.changed(); } }//GEN-LAST:event_btnChooseFontActionPerformed private void cbInvertIconsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cbInvertIconsItemStateChanged controller.changed(); }//GEN-LAST:event_cbInvertIconsItemStateChanged private void cbStretchedTabsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cbStretchedTabsItemStateChanged controller.changed(); }//GEN-LAST:event_cbStretchedTabsItemStateChanged private void cbTreeIndentOverrideStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_cbTreeIndentOverrideStateChanged controller.changed(); reinitUI(); }//GEN-LAST:event_cbTreeIndentOverrideStateChanged void load() { Preferences prefs = NbPreferences.forModule(DarculaLAFPanel.class); cbFontSizeOverride.setSelected(prefs.getBoolean(DarculaLAFOptionsPanelController.OVERRIDE_FONT_BOOLEAN, false)); lblFontName.setText(prefs.get(DarculaLAFOptionsPanelController.FONT_STRING, DarculaLFCustoms.DEFAULT_FONT)); cbTreeIndentOverride.setSelected(prefs.getBoolean(DarculaLAFOptionsPanelController.OVERRIDE_TREE_INDENT_BOOLEAN, false)); spTreeIndent.setValue(prefs.getInt(DarculaLAFOptionsPanelController.TREE_INDENT_INT, UIManager.getInt("Tree.leftChildIndent"))); cbInvertIcons.setSelected(prefs.getBoolean(DarculaLAFOptionsPanelController.INVERT_ICONS_BOOLEAN, false)); cbStretchedTabs.setSelected(prefs.getBoolean(DarculaLAFOptionsPanelController.STRETCHED_TABS_BOOLEAN, false)); reinitUI(); } void store() { Preferences prefs = NbPreferences.forModule(DarculaLAFPanel.class); prefs.putBoolean(DarculaLAFOptionsPanelController.OVERRIDE_FONT_BOOLEAN, cbFontSizeOverride.isSelected()); prefs.put(DarculaLAFOptionsPanelController.FONT_STRING, lblFontName.getText()); prefs.putBoolean(DarculaLAFOptionsPanelController.OVERRIDE_TREE_INDENT_BOOLEAN, cbTreeIndentOverride.isSelected()); prefs.putInt(DarculaLAFOptionsPanelController.TREE_INDENT_INT, (Integer) spTreeIndent.getValue()); prefs.putBoolean(DarculaLAFOptionsPanelController.INVERT_ICONS_BOOLEAN, cbInvertIcons.isSelected()); prefs.putBoolean(DarculaLAFOptionsPanelController.STRETCHED_TABS_BOOLEAN, cbStretchedTabs.isSelected()); } boolean valid() { // TODO check whether form is consistent and complete return true; } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnChooseFont; private javax.swing.JCheckBox cbFontSizeOverride; private javax.swing.JCheckBox cbInvertIcons; private javax.swing.JCheckBox cbStretchedTabs; private javax.swing.JCheckBox cbTreeIndentOverride; private javax.swing.JTextField lblFontName; private javax.swing.JLabel lblTreeIndentPx; private javax.swing.JSpinner spTreeIndent; // End of variables declaration//GEN-END:variables } ================================================ FILE: src/main/java/com/revivius/nb/darcula/ui/ContentAreaAwareButtonUI.java ================================================ package com.revivius.nb.darcula.ui; import com.bulenkov.iconloader.util.GraphicsConfig; import com.bulenkov.iconloader.util.GraphicsUtil; import com.bulenkov.iconloader.util.SystemInfo; import java.awt.Color; import java.awt.Component; import java.awt.FontMetrics; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Paint; import java.awt.Rectangle; import javax.swing.AbstractButton; import javax.swing.ButtonModel; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicButtonUI; import sun.swing.SwingUtilities2; /** * A minor re-write of DarculaButtonUI to prevent painting background when * content area filled property is set to false on button. * * Mostly copy paste from DarculaButtonUI. * * @author Revivius */ public class ContentAreaAwareButtonUI extends BasicButtonUI { public static ComponentUI createUI(JComponent c) { return new ContentAreaAwareButtonUI(); } public static boolean isSquare(Component c) { if (c instanceof JButton) { JButton b = (JButton) c; return "square".equals(b.getClientProperty("JButton.buttonType")); } return false; } @Override public void paint(Graphics g, JComponent c) { Border border = c.getBorder(); GraphicsConfig config = GraphicsUtil.setupAAPainting(g); boolean square = isSquare(c); Graphics2D g2d = (Graphics2D) g; AbstractButton b = (AbstractButton) c; if ((c.isEnabled()) && (border != null)) { //if (!square) { g2d.setPaint(getBackgroundPaint(c)); //} if (b.isContentAreaFilled()) { int arc = 5; if (square) { arc = 3; } g.fillRoundRect(1, 1, c.getWidth() - 2, c.getHeight() - 2, arc, arc); } } super.paint(g, c); config.restore(); } protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text) { AbstractButton button = (AbstractButton) c; ButtonModel model = button.getModel(); Color fg = button.getForeground(); if (((fg instanceof UIResource)) && ((button instanceof JButton)) && (((JButton) button).isDefaultButton())) { Color selectedFg = UIManager.getColor("Button.darcula.selectedButtonForeground"); if (selectedFg != null) { fg = selectedFg; } } g.setColor(fg); FontMetrics metrics = SwingUtilities2.getFontMetrics(c, g); int mnemonicIndex = button.getDisplayedMnemonicIndex(); if (model.isEnabled()) { SwingUtilities2.drawStringUnderlineCharAt(c, g, text, mnemonicIndex, textRect.x + getTextShiftOffset(), textRect.y + metrics .getAscent() + getTextShiftOffset()); } else { g.setColor(UIManager.getColor("Button.disabledText")); SwingUtilities2.drawStringUnderlineCharAt(c, g, text, -1, textRect.x + getTextShiftOffset(), textRect.y + metrics .getAscent() + getTextShiftOffset()); } } protected Paint getBackgroundPaint(JComponent c) { JButton b = (JButton) c; if (b.isDefaultButton()) { return new GradientPaint( 0.0F, 0.0F, getSelectedButtonColor1(), 0.0F, c.getHeight(), getSelectedButtonColor2() ); } return new GradientPaint( 0.0F, 0.0F, getButtonColor1(), 0.0F, c.getHeight(), getButtonColor2() ); } @Override public void update(Graphics g, JComponent c) { super.update(g, c); if (c instanceof JButton) { JButton b = (JButton) c; if (b.isDefaultButton() && !SystemInfo.isMac && !c.getFont().isBold()) { c.setFont(c.getFont().deriveFont(1)); } } } protected Color getButtonColor1() { return UIManager.getColor("Button.darcula.color1"); } protected Color getButtonColor2() { return UIManager.getColor("Button.darcula.color2"); } protected Color getSelectedButtonColor1() { return UIManager.getColor("Button.darcula.selection.color1"); } protected Color getSelectedButtonColor2() { return UIManager.getColor("Button.darcula.selection.color2"); } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/ui/ContentAreaAwareToggleButtonUI.java ================================================ package com.revivius.nb.darcula.ui; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Paint; import javax.swing.JComponent; import javax.swing.JToggleButton; import javax.swing.plaf.ComponentUI; /** * A minor re-write of DarculaButtonUI to prevent painting background when * content area filled property is set to false on button and painting a * noticable background if button is selected. * * Adapted from modified DarculaButtonUI. * * @author Revivius */ public class ContentAreaAwareToggleButtonUI extends ContentAreaAwareButtonUI { public static ComponentUI createUI(JComponent c) { return new ContentAreaAwareToggleButtonUI(); } @Override protected Paint getBackgroundPaint(JComponent c) { JToggleButton b = (JToggleButton) c; if (b.isSelected()) { return new GradientPaint( 0.0F, 0.0F, getButtonColor1().brighter(), 0.0F, c.getHeight(), getButtonColor2().brighter() ); } return new GradientPaint( 0.0F, 0.0F, getButtonColor1(), 0.0F, c.getHeight(), getButtonColor2() ); } @Override public void update(Graphics g, JComponent c) { super.update(g, c); } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/ui/DarculaSplitPaneDivider.java ================================================ package com.revivius.nb.darcula.ui; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Graphics; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JSplitPane; import javax.swing.border.Border; import javax.swing.plaf.basic.BasicSplitPaneDivider; import com.bulenkov.iconloader.IconLoader; import com.bulenkov.iconloader.util.DoubleColor; import com.bulenkov.iconloader.util.Gray; import com.bulenkov.iconloader.util.UIUtil; /** * Thanks to hudsonb: https://github.com/bulenkov/Darcula/pull/5 * * @author Revivius */ public class DarculaSplitPaneDivider extends BasicSplitPaneDivider { private Icon splitGlueV = IconLoader.findIcon("/com/bulenkov/darcula/icons/splitGlueV.png", DarculaSplitPaneDivider.class, true); private Icon splitGlueH = IconLoader.findIcon("/com/bulenkov/darcula/icons/splitGlueH.png", DarculaSplitPaneDivider.class, true); /** * Creates an instance of DarculaSplitPaneDivider. Registers this * instance for mouse events and mouse dragged events. */ public DarculaSplitPaneDivider(DarculaSplitPaneUI ui) { super(ui); } @Override public void paint(Graphics g) { super.paint(g); if(splitPane.getOrientation() == JSplitPane.VERTICAL_SPLIT) splitGlueV.paintIcon(this, g, getWidth() / 2, (getHeight() - splitGlueV.getIconHeight()) / 2); else splitGlueH.paintIcon(this, g, (getWidth() - splitGlueH.getIconWidth()) / 2, getHeight() / 2); } @Override protected JButton createLeftOneTouchButton() { JButton b = new JButton() { public void setBorder(Border b) { } public void paint(Graphics g) { if (splitPane != null) { int[] xs = new int[3]; int[] ys = new int[3]; int blockSize; // Fill the background first ... g.setColor(this.getBackground()); g.fillRect(0, 0, this.getWidth(), this.getHeight()); // ... then draw the arrow. g.setColor(new DoubleColor(Gray._255, UIUtil.getLabelForeground())); if (orientation == JSplitPane.VERTICAL_SPLIT) { blockSize = Math.min(getHeight(), ONE_TOUCH_SIZE); xs[0] = blockSize; xs[1] = 0; xs[2] = blockSize << 1; ys[0] = 0; ys[1] = ys[2] = blockSize; g.drawPolygon(xs, ys, 3); // Little trick to make the // arrows of equal size } else { blockSize = Math.min(getWidth(), ONE_TOUCH_SIZE); xs[0] = xs[2] = blockSize; xs[1] = 0; ys[0] = 0; ys[1] = blockSize; ys[2] = blockSize << 1; } g.fillPolygon(xs, ys, 3); } } // Don't want the button to participate in focus traversable. public boolean isFocusTraversable() { return false; } }; b.setMinimumSize(new Dimension(ONE_TOUCH_SIZE, ONE_TOUCH_SIZE)); b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); b.setFocusPainted(false); b.setBorderPainted(false); b.setRequestFocusEnabled(false); return b; } @Override protected JButton createRightOneTouchButton() { JButton b = new JButton() { public void setBorder(Border border) { } public void paint(Graphics g) { if (splitPane != null) { int[] xs = new int[3]; int[] ys = new int[3]; int blockSize; // Fill the background first ... g.setColor(this.getBackground()); g.fillRect(0, 0, this.getWidth(), this.getHeight()); // ... then draw the arrow. if (orientation == JSplitPane.VERTICAL_SPLIT) { blockSize = Math.min(getHeight(), ONE_TOUCH_SIZE); xs[0] = blockSize; xs[1] = blockSize << 1; xs[2] = 0; ys[0] = blockSize; ys[1] = ys[2] = 0; } else { blockSize = Math.min(getWidth(), ONE_TOUCH_SIZE); xs[0] = xs[2] = 0; xs[1] = blockSize; ys[0] = 0; ys[1] = blockSize; ys[2] = blockSize << 1; } g.setColor(new DoubleColor(Gray._255, UIUtil.getLabelForeground())); g.fillPolygon(xs, ys, 3); } } // Don't want the button to participate in focus traversable. public boolean isFocusTraversable() { return false; } }; b.setMinimumSize(new Dimension(ONE_TOUCH_SIZE, ONE_TOUCH_SIZE)); b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); b.setFocusPainted(false); b.setBorderPainted(false); b.setRequestFocusEnabled(false); return b; } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/ui/DarculaSplitPaneUI.java ================================================ package com.revivius.nb.darcula.ui; import javax.swing.JComponent; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicSplitPaneDivider; import javax.swing.plaf.basic.BasicSplitPaneUI; /** * Thanks to hudsonb: https://github.com/bulenkov/Darcula/pull/5 * * @author Revivius */ public class DarculaSplitPaneUI extends BasicSplitPaneUI { @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"}) public static ComponentUI createUI(JComponent c) { return new DarculaSplitPaneUI(); } @Override public BasicSplitPaneDivider createDefaultDivider() { return new DarculaSplitPaneDivider(this); } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/ui/DarkScrollButtonTabbedPaneUI.java ================================================ /* * Copyright 2016 Revivius. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.revivius.nb.darcula.ui; import com.bulenkov.darcula.ui.DarculaTabbedPaneUI; import java.awt.Color; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.SwingConstants; import static javax.swing.SwingConstants.EAST; import static javax.swing.SwingConstants.NORTH; import static javax.swing.SwingConstants.SOUTH; import static javax.swing.SwingConstants.WEST; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicArrowButton; /** * Overrides {@link #createScrollButton(int)} to provide a button which is more suitable to dark look and feel. * @author Revivius */ public class DarkScrollButtonTabbedPaneUI extends DarculaTabbedPaneUI { public static ComponentUI createUI(JComponent c) { return new DarkScrollButtonTabbedPaneUI(); } @Override protected JButton createScrollButton(int direction) { if (direction != SOUTH && direction != NORTH && direction != EAST && direction != WEST) { throw new IllegalArgumentException("Direction must be one of: " + "SOUTH, NORTH, EAST or WEST"); } return new ScrollableTabButton(direction); } private class ScrollableTabButton extends BasicArrowButton implements UIResource, SwingConstants { public ScrollableTabButton(int direction) { super(direction, new Color(60, 63, 65), new Color(54, 54, 54), new Color(169, 169, 169), new Color(54, 54, 54)); setBorder(BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder(0, 0, 0, 1), BorderFactory.createLineBorder(new Color(169, 169, 169))) ); } } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/ui/IndentAwareTreeUI.java ================================================ /* * Copyright 2017 Revivius. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.revivius.nb.darcula.ui; import com.bulenkov.darcula.ui.DarculaTreeUI; import com.revivius.nb.darcula.options.DarculaLAFOptionsPanelController; import com.revivius.nb.darcula.options.DarculaLAFPanel; import java.util.prefs.Preferences; import javax.swing.JComponent; import javax.swing.plaf.ComponentUI; import org.openide.util.NbPreferences; /** * Overriden to workarround isSkinny() method in DarculaTreeUI. * @author Revivius */ public class IndentAwareTreeUI extends DarculaTreeUI { private static final Preferences PREFS = NbPreferences.forModule(DarculaLAFPanel.class); public static ComponentUI createUI(JComponent c) { return new IndentAwareTreeUI(); } @Override protected int getRowX(int row, int depth) { if (PREFS.getBoolean(DarculaLAFOptionsPanelController.OVERRIDE_TREE_INDENT_BOOLEAN, false)) { return totalChildIndent * (depth + depthOffset); } return super.getRowX(row, depth); } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/ui/InreasedInsetsTableHeaderBorder.java ================================================ package com.revivius.nb.darcula.ui; import com.bulenkov.darcula.DarculaTableHeaderBorder; import java.awt.Component; import java.awt.Insets; /** * Increases table header insets. * @author Revivius */ public class InreasedInsetsTableHeaderBorder extends DarculaTableHeaderBorder { @Override public Insets getBorderInsets(Component c) { return new Insets(1, 2, 1, 2); } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/ui/OptionsAwareLabelUI.java ================================================ package com.revivius.nb.darcula.ui; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Graphics; import java.beans.PropertyChangeEvent; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.metal.MetalLabelUI; import org.netbeans.swing.plaf.LFCustoms; /** * Many thanks to Neil C. Smith of Praxis-Life. This trick is mostly * based on his excellent blog article: * https://praxisintermedia.wordpress.com/2011/09/29/the-dark-arts-of-netbeans-hackery/ * * @author Revivius */ public class OptionsAwareLabelUI extends MetalLabelUI { private static final String OPTIONS_PANEL_NAME = "org.netbeans.modules.options.OptionsPanel"; private static boolean bgReplaced = false; public static ComponentUI createUI(JComponent c) { if (c.getClass().getName().startsWith(OPTIONS_PANEL_NAME)) { return new OptionsAwareLabelUI(); } return MetalLabelUI.createUI(c); } private static final Color oldHighlighted = new Color(224, 232, 246); private final Color fgNormal = UIManager.getColor("textText"); private final Color bgNormal = UIManager.getColor("List.background"); private final Color bgSelected = UIManager.getColor("List.selectionBackground"); private final Color bgHighlighted = new Color(13, 41, 62); private final Border normalBorder = new EmptyBorder(6, 8, 6, 8); private final Border highlightBorder = new CompoundBorder( new LineBorder(bgNormal), new EmptyBorder(4, 7, 4, 7) ); private boolean ignoreChanges; @Override public void update(Graphics g, JComponent c) { super.update(g, c); if (bgReplaced) { return; } // In NB 8.1 CategoryButtons are in a JScrollPane Container parent = SwingUtilities.getAncestorOfClass(JScrollPane.class, c); if (parent == null) { parent = SwingUtilities.getAncestorOfClass(JPanel.class, c); } // In NB 8.0 CategoryButtons are in a JPanel if (parent != null) { parent = parent.getParent(); } if (parent != null && (parent instanceof JPanel)) { JPanel panel = (JPanel) parent; replaceBg(panel); panel.setBorder(BorderFactory.createMatteBorder( 0, 0, 1, 0, UIManager.getColor(LFCustoms.SCROLLPANE_BORDER_COLOR))); bgReplaced = true; } } private void replaceBg(JComponent component) { component.setBackground(bgNormal); if (component instanceof JScrollPane) { JScrollPane sc = (JScrollPane) component; sc.getViewport().setBackground(bgNormal); sc.getViewport().getView().setBackground(bgNormal); } Component[] components = component.getComponents(); for (Component c : components) { if (c instanceof JPanel || c instanceof JScrollPane) { replaceBg((JComponent) c); } } } @Override public void propertyChange(PropertyChangeEvent e) { if (ignoreChanges) { super.propertyChange(e); return; } if (!(e.getSource() instanceof JLabel)) { super.propertyChange(e); return; } JLabel c = (JLabel) e.getSource(); if ("background".equals(e.getPropertyName())) { ignoreChanges = true; Color bgCurrent = c.getBackground(); if (Color.WHITE.equals(bgCurrent)) { c.setBackground(bgNormal); } else if (oldHighlighted.equals(bgCurrent)) { c.setBackground(bgHighlighted); } else if (!bgNormal.equals(bgCurrent)) { c.setBackground(bgSelected); } ignoreChanges = false; } else if ("foreground".equals(e.getPropertyName())) { ignoreChanges = true; if (!fgNormal.equals(c.getForeground())) { c.setForeground(fgNormal); } ignoreChanges = false; } else if ("border".equals(e.getPropertyName())) { ignoreChanges = true; Border current = c.getBorder(); if (current instanceof EmptyBorder) { c.setBorder(normalBorder); } else { c.setBorder(highlightBorder); } ignoreChanges = false; } else { super.propertyChange(e); } } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/ui/ReducedInsetsDarculaButtonPainter.java ================================================ package com.revivius.nb.darcula.ui; import com.bulenkov.darcula.DarculaUIUtil; import com.bulenkov.darcula.ui.DarculaButtonUI; import com.bulenkov.iconloader.util.GraphicsConfig; import com.bulenkov.iconloader.util.Gray; import java.awt.Component; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.RenderingHints; import javax.swing.border.Border; import javax.swing.plaf.InsetsUIResource; import javax.swing.plaf.UIResource; /** * A minor re-write of DarculaButtonPainter to reduce border insets. * * Mostly copy paste from DarculaButtonPainter. * * @author Revivius */ public class ReducedInsetsDarculaButtonPainter implements Border, UIResource { @Override public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { Graphics2D g2d = (Graphics2D) g; boolean square = DarculaButtonUI.isSquare(c); if (c.hasFocus()) { DarculaUIUtil.paintFocusRing(g2d, 2, 2, width - 3, height - 3); } else { GraphicsConfig config = new GraphicsConfig(g); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT); g2d.setPaint(new GradientPaint( width / 2, y, Gray._80.withAlpha(90), width / 2, height, Gray._90.withAlpha(90))); g2d.setPaint(Gray._100.withAlpha(180)); int arc = 5; if (square) { arc = 3; } g.drawRoundRect(x + 1, y + 1, width - 2, height - 2, arc, arc); config.restore(); } } @Override public Insets getBorderInsets(Component c) { if (DarculaButtonUI.isSquare(c)) { return new InsetsUIResource(2, 0, 2, 0); } return new InsetsUIResource(4, 6, 4, 6); } @Override public boolean isBorderOpaque() { return false; } } ================================================ FILE: src/main/java/com/revivius/nb/darcula/ui/RolloverToolBarUI.java ================================================ package com.revivius.nb.darcula.ui; import java.awt.Color; import java.awt.Component; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.LineBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicToolBarUI; import org.netbeans.swing.plaf.LFCustoms; /** * A ToolBarUI that installs a ChangeListener on buttons to enable rollover for * JButtons and JToggleButtons. * * @author Revivius */ public class RolloverToolBarUI extends BasicToolBarUI { private static final String LISTENER_KEY = "ToolbarUI.ListenerKey"; private static final ChangeListener LISTENER = new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { AbstractButton b = (AbstractButton) e.getSource(); boolean rollover = b.getModel().isRollover(); b.setContentAreaFilled(rollover || b.getModel().isSelected()); b.setBorderPainted(rollover); } }; // #24 // o.openide.awt.ToolbarWithOverflow private static final PropertyChangeListener BORDER_UPDATER = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { JComponent src = (JComponent) evt.getSource(); Border border = src.getBorder(); if (border instanceof LineBorder) { LineBorder lb = (LineBorder) border; if (lb.getThickness() == 1 && Color.LIGHT_GRAY.equals(lb.getLineColor())) { src.setBorder(BorderFactory.createLineBorder(UIManager.getColor(LFCustoms.SCROLLPANE_BORDER_COLOR))); } } } }; public static ComponentUI createUI(JComponent c) { return new RolloverToolBarUI(); } @Override public void installUI(JComponent c) { super.installUI(c); // #24 if ("overflowToolbar".equals(toolBar.getName())) { toolBar.addPropertyChangeListener("border", BORDER_UPDATER); } } @Override protected void uninstallDefaults() { super.uninstallDefaults(); // #24 if ("overflowToolbar".equals(toolBar.getName())) { toolBar.removePropertyChangeListener("border", BORDER_UPDATER); } } @Override protected void setBorderToNonRollover(Component c) { if (c instanceof AbstractButton) { AbstractButton b = (AbstractButton) c; configureButton(b); } } @Override protected void setBorderToRollover(Component c) { if (c instanceof AbstractButton) { AbstractButton b = (AbstractButton) c; configureButton(b); } } @Override protected void setBorderToNormal(Component c) { if (c instanceof AbstractButton) { AbstractButton b = (AbstractButton) c; b.setBorderPainted(true); b.setContentAreaFilled(true); b.setRolloverEnabled(false); uninstallListener(b); } } private void configureButton(AbstractButton b) { b.setBorderPainted(false); b.setContentAreaFilled(false); b.setRolloverEnabled(true); installListener(b); } private void installListener(AbstractButton b) { Object o = b.getClientProperty(LISTENER_KEY); if (o == null) { b.addChangeListener(LISTENER); LISTENER.stateChanged(new ChangeEvent(b)); } } private void uninstallListener(AbstractButton b) { Object o = b.getClientProperty(LISTENER_KEY); if (o != null) { b.addChangeListener(LISTENER); } } } ================================================ FILE: src/main/nbm/manifest.mf ================================================ Manifest-Version: 1.0 OpenIDE-Module-Install: com/revivius/nb/darcula/Installer.class OpenIDE-Module-Layer: com/revivius/nb/darcula/layer.xml OpenIDE-Module-Localizing-Bundle: com/revivius/nb/darcula/Bundle.properties OpenIDE-Module-Display-Category: Base IDE Built-By: Revivius ================================================ FILE: src/main/resources/LICENSE-2.0.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Bundle.properties ================================================ #Localized module labels. Defaults taken from POM (, , ) if unset. #OpenIDE-Module-Name= #OpenIDE-Module-Short-Description= #OpenIDE-Module-Long-Description= #OpenIDE-Module-Display-Category= #Wed Jan 13 20:48:16 EET 2016 ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/FontsColors/Darcula/annotations.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/FontsColors/Darcula/highlights.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/application/xml-dtd/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/css/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/html/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/javascript/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/plain/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/x-apache-conf/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/x-diff/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/x-el/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/x-java/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/x-json/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/x-jsp/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/x-php5/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/x-properties/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/x-sql/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/x-tag/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/x-tpl/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/xhtml/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/xml/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/Editors/text/xml-external-parsed-entity/FontsColors/Darcula/tokenColorings.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/layer.xml ================================================ ================================================ FILE: src/main/resources/com/revivius/nb/darcula/options/Bundle.properties ================================================ DarculaLAFPanel.cbFontSizeOverride.text=Ove&rride default fonts by DarculaLAFPanel.lblFontName.text=Fontname Size DarculaLAFPanel.btnChooseFont.text=... DarculaLAFPanel.cbInvertIcons.text=In&vert icon color values (light and dark levels) DarculaLAFPanel.cbStretchedTabs.text=&Use stretched tabs DarculaLAFPanel.cbTreeIndentOverride.text=Override tree indent by DarculaLAFPanel.lblTreeIndentPx.text=pixels