Browse Source

Add option to toggle unified menubar.

pull/187/head
weisj 4 years ago
parent
commit
e2ed1ffc46
  1. 9
      core/src/main/java/com/github/weisj/darklaf/ui/rootpane/DarkRootPaneUI.java
  2. 1
      core/src/main/resources/com/github/weisj/darklaf/properties/platform/windows.properties
  3. 13
      core/src/test/java/ui/ComponentDemo.java
  4. 135
      windows/src/main/java/com/github/weisj/darklaf/platform/windows/ui/WindowsTitlePane.java

9
core/src/main/java/com/github/weisj/darklaf/ui/rootpane/DarkRootPaneUI.java

@ -49,6 +49,7 @@ public class DarkRootPaneUI extends BasicRootPaneUI implements HierarchyListener
protected static final String KEY_PREFIX = "JRootPane."; protected static final String KEY_PREFIX = "JRootPane.";
public static final String KEY_NO_DECORATIONS_UPDATE = KEY_PREFIX + "noDecorationsUpdate"; public static final String KEY_NO_DECORATIONS_UPDATE = KEY_PREFIX + "noDecorationsUpdate";
public static final String KEY_NO_DECORATIONS = KEY_PREFIX + "noDecorations"; public static final String KEY_NO_DECORATIONS = KEY_PREFIX + "noDecorations";
public static final String KEY_UNIFIED_MENUBAR = KEY_PREFIX + "unifiedMenuBar";
protected static final String[] borderKeys = new String[]{"RootPane.border", protected static final String[] borderKeys = new String[]{"RootPane.border",
"RootPane.frameBorder", "RootPane.frameBorder",
"RootPane.plainDialogBorder", "RootPane.plainDialogBorder",
@ -76,12 +77,18 @@ public class DarkRootPaneUI extends BasicRootPaneUI implements HierarchyListener
super.installUI(c); super.installUI(c);
rootPane = (JRootPane) c; rootPane = (JRootPane) c;
windowDecorationsStyle = rootPane.getWindowDecorationStyle(); windowDecorationsStyle = rootPane.getWindowDecorationStyle();
LookAndFeel.installColors(rootPane, "RootPane.background", "RootPane.foreground");
updateClientDecoration(); updateClientDecoration();
installBorder(rootPane); installBorder(rootPane);
installListeners(rootPane); installListeners(rootPane);
} }
@Override
protected void installDefaults(final JRootPane c) {
super.installDefaults(c);
c.putClientProperty(KEY_UNIFIED_MENUBAR, UIManager.getBoolean("TitlePane.unifiedMenuBar"));
LookAndFeel.installColors(c, "RootPane.background", "RootPane.foreground");
}
protected void installBorder(final JRootPane root) { protected void installBorder(final JRootPane root) {
if (root == null) return; if (root == null) return;
LookAndFeel.installBorder(root, borderKeys[windowDecorationsStyle]); LookAndFeel.installBorder(root, borderKeys[windowDecorationsStyle]);

1
core/src/main/resources/com/github/weisj/darklaf/properties/platform/windows.properties

@ -26,6 +26,7 @@
# #
FileChooser.listViewWindowsStyle = true FileChooser.listViewWindowsStyle = true
TitlePane.unifiedMenuBar = true
Table.alternateRowColor = false Table.alternateRowColor = false
Tree.alternateRowColor = false Tree.alternateRowColor = false
List.alternateRowColor = false List.alternateRowColor = false

13
core/src/test/java/ui/ComponentDemo.java

@ -43,6 +43,8 @@ import com.github.weisj.darklaf.icons.IconLoader;
import com.github.weisj.darklaf.settings.ThemeSettingsMenuItem; import com.github.weisj.darklaf.settings.ThemeSettingsMenuItem;
import com.github.weisj.darklaf.theme.Theme; import com.github.weisj.darklaf.theme.Theme;
import com.github.weisj.darklaf.theme.info.PreferredThemeStyle; import com.github.weisj.darklaf.theme.info.PreferredThemeStyle;
import com.github.weisj.darklaf.ui.rootpane.DarkRootPaneUI;
import com.github.weisj.darklaf.util.PropertyUtil;
public interface ComponentDemo { public interface ComponentDemo {
@ -212,6 +214,17 @@ public interface ComponentDemo {
addActionListener(e -> LafManager.setDecorationsEnabled(isSelected())); addActionListener(e -> LafManager.setDecorationsEnabled(isSelected()));
} }
}); });
dev.add(new JCheckBoxMenuItem("Unified Menubar") {
{
SwingUtilities.invokeLater(() -> {
setSelected(PropertyUtil.getBooleanProperty(SwingUtilities.getRootPane(dev),
DarkRootPaneUI.KEY_UNIFIED_MENUBAR));
});
addActionListener(e -> SwingUtilities.getRootPane(dev)
.putClientProperty(DarkRootPaneUI.KEY_UNIFIED_MENUBAR,
isSelected()));
}
});
return dev; return dev;
} }

135
windows/src/main/java/com/github/weisj/darklaf/platform/windows/ui/WindowsTitlePane.java

@ -44,6 +44,7 @@ import com.github.weisj.darklaf.platform.decorations.CustomTitlePane;
import com.github.weisj.darklaf.platform.windows.JNIDecorationsWindows; import com.github.weisj.darklaf.platform.windows.JNIDecorationsWindows;
import com.github.weisj.darklaf.platform.windows.PointerUtil; import com.github.weisj.darklaf.platform.windows.PointerUtil;
import com.github.weisj.darklaf.util.PropertyKey; import com.github.weisj.darklaf.util.PropertyKey;
import com.github.weisj.darklaf.util.PropertyUtil;
import com.github.weisj.darklaf.util.Scale; import com.github.weisj.darklaf.util.Scale;
/** /**
@ -59,22 +60,14 @@ public class WindowsTitlePane extends CustomTitlePane {
private static final int ICON_WIDTH = 32; private static final int ICON_WIDTH = 32;
private static final int ICON_SIZE = ICON_WIDTH - 3 * PAD; private static final int ICON_SIZE = ICON_WIDTH - 3 * PAD;
private final JRootPane rootPane; private final JRootPane rootPane;
private final ContainerListener layeredPaneContainerListener = new ContainerListener() {
@Override
public void componentAdded(final ContainerEvent e) {
if (e.getChild() instanceof JMenuBar) {
addMenuBar(getRootPane().getJMenuBar());
}
if (getRootPane().getJMenuBar() == null && menuBar != null) {
removeMenuBar();
}
}
@Override private boolean unifiedMenuBar;
public void componentRemoved(final ContainerEvent e) {} private ContainerListener rootPaneContainerListener;
}; private ContainerListener layeredPaneContainerListener;
private boolean oldResizable; private boolean oldResizable;
private PropertyChangeListener propertyChangeListener; private PropertyChangeListener windowPropertyChangeListener;
private PropertyChangeListener rootPanePropertyChangeListener;
private WindowListener windowListener; private WindowListener windowListener;
private ToggleIcon closeIcon; private ToggleIcon closeIcon;
private ToggleIcon maximizeIcon; private ToggleIcon maximizeIcon;
@ -92,21 +85,6 @@ public class WindowsTitlePane extends CustomTitlePane {
private final Window window; private final Window window;
private long windowHandle; private long windowHandle;
private JMenuBar menuBar; private JMenuBar menuBar;
private final ContainerListener rootPaneContainerListener = new ContainerListener() {
@Override
public void componentAdded(final ContainerEvent e) {
if (e.getChild() instanceof JLayeredPane) {
((JLayeredPane) e.getChild()).addContainerListener(layeredPaneContainerListener);
}
}
@Override
public void componentRemoved(final ContainerEvent e) {
if (e.getChild() instanceof JLayeredPane) {
((JLayeredPane) e.getChild()).removeContainerListener(layeredPaneContainerListener);
}
}
};
private int state; private int state;
private Color inactiveBackground; private Color inactiveBackground;
@ -131,8 +109,9 @@ public class WindowsTitlePane extends CustomTitlePane {
this.window = window; this.window = window;
bundle = ResourceBundle.getBundle("com.github.weisj.darklaf.bundles.actions", getLocale()); bundle = ResourceBundle.getBundle("com.github.weisj.darklaf.bundles.actions", getLocale());
this.decorationStyle = decorationStyle; this.decorationStyle = decorationStyle;
rootPane.addContainerListener(rootPaneContainerListener);
rootPane.getLayeredPane().addContainerListener(layeredPaneContainerListener); updateMenuBar(true);
state = -1; state = -1;
oldResizable = true; oldResizable = true;
installSubcomponents(); installSubcomponents();
@ -140,6 +119,65 @@ public class WindowsTitlePane extends CustomTitlePane {
setLayout(createLayout()); setLayout(createLayout());
} }
private void updateMenuBar(final boolean install) {
unifiedMenuBar = PropertyUtil.getBooleanProperty(rootPane, "JRootPane.unifiedMenuBar");
if (unifiedMenuBar && install) {
if (rootPaneContainerListener == null) {
rootPaneContainerListener = createRootPaneContainerListener();
}
if (layeredPaneContainerListener == null) {
layeredPaneContainerListener = createLayeredPaneContainerListener();
}
rootPane.addContainerListener(rootPaneContainerListener);
rootPane.getLayeredPane().addContainerListener(layeredPaneContainerListener);
addMenuBar(getRootPane().getJMenuBar());
} else {
rootPane.removeContainerListener(rootPaneContainerListener);
rootPane.getLayeredPane().removeContainerListener(layeredPaneContainerListener);
if (menuBar != null) {
getRootPane().setJMenuBar(menuBar);
menuBar.setPreferredSize(null);
menuBar = null;
}
}
rootPane.revalidate();
}
private ContainerListener createRootPaneContainerListener() {
return new ContainerListener() {
@Override
public void componentAdded(final ContainerEvent e) {
if (e.getChild() instanceof JLayeredPane) {
((JLayeredPane) e.getChild()).addContainerListener(layeredPaneContainerListener);
}
}
@Override
public void componentRemoved(final ContainerEvent e) {
if (e.getChild() instanceof JLayeredPane) {
((JLayeredPane) e.getChild()).removeContainerListener(layeredPaneContainerListener);
}
}
};
}
private ContainerListener createLayeredPaneContainerListener() {
return new ContainerListener() {
@Override
public void componentAdded(final ContainerEvent e) {
if (e.getChild() instanceof JMenuBar) {
addMenuBar(getRootPane().getJMenuBar());
}
if (getRootPane().getJMenuBar() == null && menuBar != null) {
removeMenuBar();
}
}
@Override
public void componentRemoved(final ContainerEvent e) {}
};
}
private static JButton createButton(final Icon icon, final Action action) { private static JButton createButton(final Icon icon, final Action action) {
return createButton(icon, action, false); return createButton(icon, action, false);
} }
@ -177,19 +215,16 @@ public class WindowsTitlePane extends CustomTitlePane {
uninstallListeners(); uninstallListeners();
uninstallDecorations(removeDecorations); uninstallDecorations(removeDecorations);
removeAll(); removeAll();
if (menuBar != null) { updateMenuBar(false);
getRootPane().setJMenuBar(menuBar);
}
} }
private void uninstallListeners() { private void uninstallListeners() {
if (window != null) { if (window != null) {
window.removeWindowListener(windowListener); window.removeWindowListener(windowListener);
window.removePropertyChangeListener(propertyChangeListener); window.removePropertyChangeListener(windowPropertyChangeListener);
} }
if (rootPane != null) { if (rootPane != null) {
rootPane.removeContainerListener(rootPaneContainerListener); rootPane.removePropertyChangeListener(rootPanePropertyChangeListener);
rootPane.getLayeredPane().removeContainerListener(layeredPaneContainerListener);
} }
} }
@ -259,8 +294,10 @@ public class WindowsTitlePane extends CustomTitlePane {
if (window != null) { if (window != null) {
windowListener = createWindowListener(); windowListener = createWindowListener();
window.addWindowListener(windowListener); window.addWindowListener(windowListener);
propertyChangeListener = createWindowPropertyChangeListener(); windowPropertyChangeListener = createWindowPropertyChangeListener();
window.addPropertyChangeListener(propertyChangeListener); rootPanePropertyChangeListener = createRootPanePropertyChangeListener();
rootPane.addPropertyChangeListener(rootPanePropertyChangeListener);
window.addPropertyChangeListener(windowPropertyChangeListener);
} }
} }
@ -269,7 +306,11 @@ public class WindowsTitlePane extends CustomTitlePane {
} }
private PropertyChangeListener createWindowPropertyChangeListener() { private PropertyChangeListener createWindowPropertyChangeListener() {
return new PropertyChangeHandler(); return new WindowPropertyChangeListener();
}
private PropertyChangeListener createRootPanePropertyChangeListener() {
return new RootPanePropertyChangeListener();
} }
private void installSubcomponents() { private void installSubcomponents() {
@ -294,7 +335,7 @@ public class WindowsTitlePane extends CustomTitlePane {
} }
protected void addMenuBar(final JMenuBar menuBar) { protected void addMenuBar(final JMenuBar menuBar) {
if (menuBar != null) { if (menuBar != null && unifiedMenuBar) {
this.menuBar = menuBar; this.menuBar = menuBar;
// Otherwise, a white bar will appear where the menuBar used to be. // Otherwise, a white bar will appear where the menuBar used to be.
menuBar.setPreferredSize(new Dimension(0, 0)); menuBar.setPreferredSize(new Dimension(0, 0));
@ -809,7 +850,7 @@ public class WindowsTitlePane extends CustomTitlePane {
} }
} }
protected class PropertyChangeHandler implements PropertyChangeListener { protected class WindowPropertyChangeListener implements PropertyChangeListener {
@Override @Override
public void propertyChange(final PropertyChangeEvent pce) { public void propertyChange(final PropertyChangeEvent pce) {
@ -842,6 +883,16 @@ public class WindowsTitlePane extends CustomTitlePane {
} }
} }
protected class RootPanePropertyChangeListener implements PropertyChangeListener {
@Override
public void propertyChange(final PropertyChangeEvent evt) {
if ("JRootPane.unifiedMenuBar".equals(evt.getPropertyName())) {
updateMenuBar(true);
}
}
}
protected class WindowHandler extends WindowAdapter { protected class WindowHandler extends WindowAdapter {
public void windowActivated(final WindowEvent ev) { public void windowActivated(final WindowEvent ev) {

Loading…
Cancel
Save