diff --git a/.idea/misc.xml b/.idea/misc.xml
index a0db047..75af768 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/src/com/bulenkov/darcula/DarculaLaf.java b/src/com/bulenkov/darcula/DarculaLaf.java
index 0fb3887..74d198b 100644
--- a/src/com/bulenkov/darcula/DarculaLaf.java
+++ b/src/com/bulenkov/darcula/DarculaLaf.java
@@ -17,6 +17,7 @@ package com.bulenkov.darcula;
import com.bulenkov.darcula.util.ColorUtil;
import com.bulenkov.darcula.util.StringUtil;
+import com.bulenkov.darcula.util.UIManagerUtil;
import sun.awt.AppContext;
import javax.swing.*;
@@ -29,6 +30,8 @@ import javax.swing.text.DefaultEditorKit;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.*;
@@ -72,11 +75,21 @@ public final class DarculaLaf extends BasicLookAndFeel {
@SuppressWarnings("UnusedParameters")
private static void log(Exception e) {
//everything is gonna be alright
- //e.printStackTrace();
+ e.printStackTrace();
}
@Override
public UIDefaults getDefaults() {
+ final Timer[] timer = new Timer[1];
+ timer[0] = new Timer(2000, new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ UIManagerUtil.showInfo();
+ timer[0].stop();
+ }
+ });
+ timer[0].start();
+
try {
final Method superMethod = BasicLookAndFeel.class.getDeclaredMethod("getDefaults");
superMethod.setAccessible(true);
diff --git a/src/com/bulenkov/darcula/darcula.properties b/src/com/bulenkov/darcula/darcula.properties
index 8a33709..92a2c96 100644
--- a/src/com/bulenkov/darcula/darcula.properties
+++ b/src/com/bulenkov/darcula/darcula.properties
@@ -5,9 +5,14 @@ darcula.foreground=bbbbbb
darcula.textForeground=bbbbbb
darcula.caretForeground=bbbbbb
darcula.inactiveBackground=3C3F41
+darcula.highlight=3C3F41
+darcula.light=3C3F41
window=3c3f41
info=3c3f41
controlLtHighlight=3c3f41
+controlHighlight=3c3f41
+menu=3c3f41
+desktop=3c3f41
text=bbbbbb
textText=bbbbbb
diff --git a/src/com/bulenkov/darcula/darcula_linux.properties b/src/com/bulenkov/darcula/darcula_linux.properties
index aef0536..d523622 100644
--- a/src/com/bulenkov/darcula/darcula_linux.properties
+++ b/src/com/bulenkov/darcula/darcula_linux.properties
@@ -4,4 +4,7 @@ darcula.selectionForeground=bbbbbb
PopupMenu.border=com.bulenkov.darcula.ui.DarculaPopupMenuBorder
+MenuBarUI=com.bulenkov.darcula.ui.DarculaMenuBarUI
MenuBar.border=com.bulenkov.darcula.ui.DarculaMenuBarBorder
+
+ToolBarUI=com.bulenkov.darcula.ui.DarculaToolBarUI
diff --git a/src/com/bulenkov/darcula/darcula_windows.properties b/src/com/bulenkov/darcula/darcula_windows.properties
index 8e38720..df0a46b 100644
--- a/src/com/bulenkov/darcula/darcula_windows.properties
+++ b/src/com/bulenkov/darcula/darcula_windows.properties
@@ -1,9 +1,14 @@
# suppress inspection "UnusedProperty" for whole file
darcula.selectionBackground=4B6EAF
darcula.selectionForeground=bbbbbb
+darcula.select=0D293E
PopupMenu.border=com.bulenkov.darcula.ui.DarculaPopupMenuBorder
+MenuBarUI=com.bulenkov.darcula.ui.DarculaMenuBarUI
MenuBar.border=com.bulenkov.darcula.ui.DarculaMenuBarBorder
-InternalFrameUI=com.bulenkov.darcula.ui.win.DarculaWindowsInternalFrameUI
\ No newline at end of file
+ToolBarUI=com.bulenkov.darcula.ui.DarculaToolBarUI
+ToggleButton.shadow=0d293e
+
+#InternalFrameUI=com.bulenkov.darcula.ui.win.DarculaWindowsInternalFrameUI
\ No newline at end of file
diff --git a/src/com/bulenkov/darcula/ui/DarculaMenuBarUI.java b/src/com/bulenkov/darcula/ui/DarculaMenuBarUI.java
new file mode 100644
index 0000000..9111018
--- /dev/null
+++ b/src/com/bulenkov/darcula/ui/DarculaMenuBarUI.java
@@ -0,0 +1,22 @@
+package com.bulenkov.darcula.ui;
+
+import javax.swing.*;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.metal.MetalMenuBarUI;
+import java.awt.*;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class DarculaMenuBarUI extends MetalMenuBarUI {
+ @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
+ public static ComponentUI createUI(JComponent c) {
+ return new DarculaMenuBarUI();
+ }
+
+ @Override
+ public void paint(Graphics g, JComponent c) {
+ g.setColor(UIManager.getColor("MenuItem.background"));
+ g.fillRect(0, 0, c.getWidth(), c.getHeight());
+ }
+}
diff --git a/src/com/bulenkov/darcula/ui/DarculaToolBarUI.java b/src/com/bulenkov/darcula/ui/DarculaToolBarUI.java
new file mode 100644
index 0000000..908e7ce
--- /dev/null
+++ b/src/com/bulenkov/darcula/ui/DarculaToolBarUI.java
@@ -0,0 +1,22 @@
+package com.bulenkov.darcula.ui;
+
+import javax.swing.*;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.metal.MetalToolBarUI;
+import java.awt.*;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class DarculaToolBarUI extends MetalToolBarUI {
+ @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
+ public static ComponentUI createUI(JComponent c) {
+ return new DarculaToolBarUI();
+ }
+
+ @Override
+ public void paint(Graphics g, JComponent c) {
+ g.setColor(UIManager.getColor("ToolBar.background"));
+ g.fillRect(0, 0, c.getWidth(), c.getHeight());
+ }
+}
diff --git a/src/com/bulenkov/darcula/util/ColorUtil.java b/src/com/bulenkov/darcula/util/ColorUtil.java
index 5c0c2b9..776be08 100644
--- a/src/com/bulenkov/darcula/util/ColorUtil.java
+++ b/src/com/bulenkov/darcula/util/ColorUtil.java
@@ -54,4 +54,15 @@ public class ColorUtil {
}
}
+ public static boolean isDark(final Color c) {
+ // based on perceptional luminosity, see
+ return (1 - (0.299 * c.getRed() + 0.587 * c.getGreen() + 0.114 * c.getBlue()) / 255) >= 0.5;
+ }
+
+ public static String toHex(final Color c) {
+ final String R = Integer.toHexString(c.getRed());
+ final String G = Integer.toHexString(c.getGreen());
+ final String B = Integer.toHexString(c.getBlue());
+ return (R.length() < 2 ? "0" : "") + R + (G.length() < 2 ? "0" : "") + G + (B.length() < 2 ? "0" : "") + B;
+ }
}
diff --git a/src/com/bulenkov/darcula/util/StringUtil.java b/src/com/bulenkov/darcula/util/StringUtil.java
index 606c551..93634ba 100644
--- a/src/com/bulenkov/darcula/util/StringUtil.java
+++ b/src/com/bulenkov/darcula/util/StringUtil.java
@@ -39,4 +39,104 @@ public class StringUtil {
}
return result;
}
+
+ public static int naturalCompare(String string1, String string2) {
+ return naturalCompare(string1, string2, false);
+ }
+
+ private static int naturalCompare(String string1, String string2, boolean caseSensitive) {
+ final int string1Length = string1.length();
+ final int string2Length = string2.length();
+ for (int i = 0, j = 0; i < string1Length && j < string2Length; i++, j++) {
+ char ch1 = string1.charAt(i);
+ char ch2 = string2.charAt(j);
+ if ((isDigit(ch1) || ch1 == ' ') && (isDigit(ch2) || ch2 == ' ')) {
+ int startNum1 = i;
+ while (ch1 == ' ' || ch1 == '0') { // skip leading spaces and zeros
+ startNum1++;
+ if (startNum1 >= string1Length) break;
+ ch1 = string1.charAt(startNum1);
+ }
+ int startNum2 = j;
+ while (ch2 == ' ' || ch2 == '0') {
+ startNum2++;
+ if (startNum2 >= string2Length) break;
+ ch2 = string2.charAt(startNum2);
+ }
+ i = startNum1;
+ j = startNum2;
+ while (i < string1Length && isDigit(string1.charAt(i))) i++;
+ while (j < string2Length && isDigit(string2.charAt(j))) j++;
+ String digits1 = string1.substring(startNum1, i);
+ String digits2 = string2.substring(startNum2, j);
+ if (digits1.length() != digits2.length()) {
+ return digits1.length() - digits2.length();
+ }
+ int numberDiff = digits1.compareTo(digits2);
+ if (numberDiff != 0) {
+ return numberDiff;
+ }
+ i--;
+ j--;
+ final int lengthDiff = (i - startNum1) - (j - startNum2);
+ if (lengthDiff != 0) {
+ return lengthDiff;
+ }
+ for (; startNum1 < i; startNum1++, startNum2++) {
+ final int diff = string1.charAt(startNum1) - string2.charAt(startNum2);
+ if (diff != 0) {
+ return diff;
+ }
+ }
+ }
+ else {
+ if (caseSensitive) {
+ return ch1 - ch2;
+ }
+ else {
+ // similar logic to charsMatch() below
+ if (ch1 != ch2) {
+ final int diff1 = toUpperCase(ch1) - toUpperCase(ch2);
+ if (diff1 != 0) {
+ final int diff2 = toLowerCase(ch1) - toLowerCase(ch2);
+ if (diff2 != 0) {
+ return diff2;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (!caseSensitive && string1Length == string2Length) {
+ // do case sensitive compare if case insensitive strings are equal
+ return naturalCompare(string1, string2, true);
+ }
+ return string1Length - string2Length;
+ }
+
+ public static char toUpperCase(char a) {
+ if (a < 'a') {
+ return a;
+ }
+ if (a <= 'z') {
+ return (char)(a + ('A' - 'a'));
+ }
+ return Character.toUpperCase(a);
+ }
+
+ public static char toLowerCase(char a) {
+ if (a < 'A' || a >= 'a' && a <= 'z') {
+ return a;
+ }
+
+ if (a <= 'Z') {
+ return (char)(a + ('a' - 'A'));
+ }
+
+ return Character.toLowerCase(a);
+ }
+
+ private static boolean isDigit(char c) {
+ return c >= '0' && c <= '9';
+ }
}
diff --git a/src/com/bulenkov/darcula/util/UIManagerUtil.java b/src/com/bulenkov/darcula/util/UIManagerUtil.java
new file mode 100644
index 0000000..7778f0d
--- /dev/null
+++ b/src/com/bulenkov/darcula/util/UIManagerUtil.java
@@ -0,0 +1,138 @@
+package com.bulenkov.darcula.util;
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import javax.swing.plaf.ColorUIResource;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.DefaultTableModel;
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.EventObject;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class UIManagerUtil {
+
+ public static void showInfo() {
+ JFrame frame = new JFrame();
+ frame.setSize(500, 800);
+ frame.setTitle("Edit LaF Defaults");
+
+ final UIDefaults defaults = UIManager.getDefaults();
+ Enumeration keys = defaults.keys();
+ final Object[][] data = new Object[defaults.size()][2];
+ int i = 0;
+ while (keys.hasMoreElements()) {
+ Object key = keys.nextElement();
+ data[i][0] = key;
+ data[i][1] = defaults.get(key);
+ i++;
+ }
+
+ Arrays.sort(data, new Comparator