Browse Source

fix toolbar and menu on windows

master
Konstantin Bulenkov 12 years ago
parent
commit
e5aefdb02f
  1. 2
      .idea/misc.xml
  2. 15
      src/com/bulenkov/darcula/DarculaLaf.java
  3. 5
      src/com/bulenkov/darcula/darcula.properties
  4. 3
      src/com/bulenkov/darcula/darcula_linux.properties
  5. 7
      src/com/bulenkov/darcula/darcula_windows.properties
  6. 22
      src/com/bulenkov/darcula/ui/DarculaMenuBarUI.java
  7. 22
      src/com/bulenkov/darcula/ui/DarculaToolBarUI.java
  8. 11
      src/com/bulenkov/darcula/util/ColorUtil.java
  9. 100
      src/com/bulenkov/darcula/util/StringUtil.java
  10. 138
      src/com/bulenkov/darcula/util/UIManagerUtil.java

2
.idea/misc.xml

@ -6,7 +6,7 @@
<component name="ProjectKey">
<option name="state" value="https://bulenkov@bitbucket.org/bulenkov/darcula.git" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

15
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);

5
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

3
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

7
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
ToolBarUI=com.bulenkov.darcula.ui.DarculaToolBarUI
ToggleButton.shadow=0d293e
#InternalFrameUI=com.bulenkov.darcula.ui.win.DarculaWindowsInternalFrameUI

22
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());
}
}

22
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());
}
}

11
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;
}
}

100
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';
}
}

138
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<Object[]>() {
@Override
public int compare(Object[] o1, Object[] o2) {
return StringUtil.naturalCompare(o1[0].toString(), o2[0].toString());
}
});
JTable table = new JTable(new DefaultTableModel(data, new Object[]{"Name", "Value"}) {
@Override
public boolean isCellEditable(int row, int column) {
return column == 1 && getValueAt(row, column) instanceof Color;
}
}) {
@Override
public boolean editCellAt(int row, int column, EventObject e) {
if (isCellEditable(row, column) && e instanceof MouseEvent) {
final Object color = getValueAt(row, column);
final Color newColor = JColorChooser.showDialog(null, "Set Color", (Color)color);
if (newColor != null) {
final ColorUIResource colorUIResource = new ColorUIResource(newColor);
final Object key = getValueAt(row, 0);
UIManager.put(key, colorUIResource);
setValueAt(colorUIResource, row, column);
}
}
return false;
}
};
table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
final JPanel panel = new JPanel(new BorderLayout());
final JLabel label = new JLabel(value == null ? "" : value.toString());
panel.add(label, BorderLayout.CENTER);
if (value instanceof Color) {
final Color c = (Color) value;
label.setText(String.format("[r=%d,g=%d,b=%d] hex=0x%s", c.getRed(), c.getGreen(), c.getBlue(), ColorUtil.toHex(c)));
label.setForeground(ColorUtil.isDark(c) ? Color.white : Color.black);
panel.setBackground(c);
return panel;
} else if (value instanceof Icon) {
try {
final Icon icon = new IconWrap((Icon) value);
if (icon.getIconHeight() <= 20) {
label.setIcon(icon);
}
label.setText(String.format("(%dx%d) %s)", icon.getIconWidth(), icon.getIconHeight(), label.getText()));
} catch (Throwable e1) {//
}
return panel;
} else if (value instanceof Border) {
try {
final Insets i = ((Border) value).getBorderInsets(null);
label.setText(String.format("[%d, %d, %d, %d] %s", i.top, i.left, i.bottom, i.right, label.getText()));
return panel;
} catch (Exception ignore) {
}
}
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
});
final JScrollPane pane = new JScrollPane(table);
table.setShowGrid(false);
final JPanel panel = new JPanel(new BorderLayout());
panel.add(pane, BorderLayout.CENTER);
frame.getContentPane().add(panel);
frame.setVisible(true);
}
private static class IconWrap implements Icon {
private final Icon myIcon;
public IconWrap(Icon icon) {
myIcon = icon;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
try {
myIcon.paintIcon(c, g, x, y);
} catch (Exception e) {
}
}
@Override
public int getIconWidth() {
return myIcon.getIconWidth();
}
@Override
public int getIconHeight() {
return myIcon.getIconHeight();
}
}
}
Loading…
Cancel
Save