From d803daa2ba03a371d096b4f4a0308c34016c8549 Mon Sep 17 00:00:00 2001 From: weisj Date: Sun, 15 Mar 2020 19:39:45 +0100 Subject: [PATCH] Added TristateCheckBoxMenuItem Added MenuItem demos for CheckBox RadioButton and TristateCheckBox. --- .../tristate/TristateCheckBoxMenuItem.java | 168 ++++++++++++++++++ .../DarkTristateCheckBoxMenuItemUI.java | 67 +++++++ .../darklaf/properties/ui/tristate.properties | 3 +- .../test/java/ui/checkBox/CheckBoxDemo.java | 9 + .../java/ui/checkBox/TriCheckBoxDemo.java | 10 ++ .../java/ui/radioButton/RadioButtonDemo.java | 9 + 6 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/com/github/weisj/darklaf/components/tristate/TristateCheckBoxMenuItem.java create mode 100644 core/src/main/java/com/github/weisj/darklaf/ui/tristate/DarkTristateCheckBoxMenuItemUI.java diff --git a/core/src/main/java/com/github/weisj/darklaf/components/tristate/TristateCheckBoxMenuItem.java b/core/src/main/java/com/github/weisj/darklaf/components/tristate/TristateCheckBoxMenuItem.java new file mode 100644 index 00000000..7aa1c029 --- /dev/null +++ b/core/src/main/java/com/github/weisj/darklaf/components/tristate/TristateCheckBoxMenuItem.java @@ -0,0 +1,168 @@ +/* + * MIT License + * + * Copyright (c) 2020 Jannis Weis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.github.weisj.darklaf.components.tristate; + +import com.github.weisj.darklaf.DarkLaf; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class TristateCheckBoxMenuItem extends JCheckBoxMenuItem { + + /** + * Creates an initially unselected tristate check box menu item with no set text or icon. + */ + public TristateCheckBoxMenuItem() { + this(null, null, TristateState.DESELECTED); + } + + /** + * Creates an initially unselected tristate check box menu item with an icon. + * + * @param icon the icon of the {@code JCheckBoxMenuItem}. + */ + public TristateCheckBoxMenuItem(final Icon icon) { + this(null, icon, TristateState.DESELECTED); + } + + /** + * Creates an initially unselected tristate check box menu item with text. + * + * @param text the text of the {@code JCheckBoxMenuItem} + */ + public TristateCheckBoxMenuItem(final String text) { + this(text, null, TristateState.DESELECTED); + } + + /** + * Creates a menu item whose properties are taken from the + * Action supplied. + * + * @param a the action of the {@code JCheckBoxMenuItem} + * @since 1.3 + */ + public TristateCheckBoxMenuItem(final Action a) { + this(); + setAction(a); + } + + /** + * Creates an initially unselected check box menu item with the specified text and icon. + * + * @param text the text of the {@code JCheckBoxMenuItem} + * @param icon the icon of the {@code JCheckBoxMenuItem} + */ + public TristateCheckBoxMenuItem(final String text, final Icon icon) { + this(text, icon, TristateState.DESELECTED); + } + + /** + * Creates a tristate check box menu item with the specified text and selection state. + * + * @param text the text of the check box menu item. + * @param state the selected state of the check box menu item. + */ + public TristateCheckBoxMenuItem(final String text, final TristateState state) { + this(text, null, state); + } + + /** + * Creates a tristate check box menu item with the specified text, icon, and selection state. + * + * @param text the text of the check box menu item. + * @param icon the icon of the check box menu item. + * @param state the selected state of the check box menu item. + */ + public TristateCheckBoxMenuItem(final String text, final Icon icon, final TristateState state) { + super(text, icon); + setModel(new TristateButtonModel(state)); + // override action behaviour + super.addMouseListener(new MouseAdapter() { + public void mousePressed(final MouseEvent e) { + TristateCheckBoxMenuItem.this.iterateState(); + } + }); + setFocusable(false); + } + + public String getUIClassID() { + if (UIManager.getLookAndFeel() instanceof DarkLaf) { + return "TristateCheckBoxMenuItemUI"; + } else { + return super.getUIClassID(); + } + } + + private void iterateState() { + if (!getModel().isEnabled()) return; + + grabFocus(); + getTristateModel().iterateState(); + repaint(); + + int modifiers = 0; + AWTEvent currentEvent = EventQueue.getCurrentEvent(); + if (currentEvent instanceof InputEvent) { + modifiers = ((InputEvent) currentEvent).getModifiersEx(); + } else if (currentEvent instanceof ActionEvent) { + modifiers = ((ActionEvent) currentEvent).getModifiers(); + } + fireActionPerformed(new ActionEvent(this, + ActionEvent.ACTION_PERFORMED, getText(), + System.currentTimeMillis(), modifiers)); + } + + public TristateButtonModel getTristateModel() { + return (TristateButtonModel) super.getModel(); + } + + @Override + public void setSelected(final boolean b) { + setState(b ? TristateState.SELECTED : TristateState.DESELECTED); + } + + public void setIndeterminate() { + getTristateModel().setIndeterminate(); + } + + public boolean isIndeterminate() { + return getTristateModel().isIndeterminate(); + } + + public boolean getState() { + return getTristateModel().getState() == TristateState.SELECTED; + } + + public void setState(final TristateState state) { + getTristateModel().setState(state); + } + + public TristateState getTristateState() { + return getTristateModel().getState(); + } +} diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/tristate/DarkTristateCheckBoxMenuItemUI.java b/core/src/main/java/com/github/weisj/darklaf/ui/tristate/DarkTristateCheckBoxMenuItemUI.java new file mode 100644 index 00000000..ff1286c0 --- /dev/null +++ b/core/src/main/java/com/github/weisj/darklaf/ui/tristate/DarkTristateCheckBoxMenuItemUI.java @@ -0,0 +1,67 @@ +/* + * MIT License + * + * Copyright (c) 2020 Jannis Weis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.github.weisj.darklaf.ui.tristate; + +import com.github.weisj.darklaf.components.tristate.TristateCheckBox; +import com.github.weisj.darklaf.components.tristate.TristateState; +import com.github.weisj.darklaf.ui.checkbox.DarkCheckBoxMenuItemUI; + +import javax.swing.*; +import javax.swing.plaf.ComponentUI; + +/** + * @author Jannis Weis + */ +public class DarkTristateCheckBoxMenuItemUI extends DarkCheckBoxMenuItemUI { + private Icon checkBoxIndeterminateIcon; + private Icon checkBoxIndeterminateDisabledIcon; + private Icon checkBoxIndeterminateFocusedIcon; + + public static ComponentUI createUI(final JComponent c) { + return new DarkTristateCheckBoxMenuItemUI(); + } + + @Override + public void installDefaults() { + super.installDefaults(); + checkBoxIndeterminateIcon = UIManager.getIcon("CheckBox.indeterminate.icon"); + checkBoxIndeterminateDisabledIcon = UIManager.getIcon("CheckBox.indeterminateDisabled.icon"); + checkBoxIndeterminateFocusedIcon = UIManager.getIcon("CheckBox.indeterminateFocused.icon"); + } + + @Override + protected Icon getCheckBoxIcon(final AbstractButton b) { + if (b instanceof TristateCheckBox) { + TristateState state = ((TristateCheckBox) b).getState(); + if (state == TristateState.INDETERMINATE) { + if (b.isEnabled()) { + return b.hasFocus() ? checkBoxIndeterminateFocusedIcon : checkBoxIndeterminateIcon; + } else { + return checkBoxIndeterminateDisabledIcon; + } + } + } + return super.getCheckBoxIcon(b); + } +} diff --git a/core/src/main/resources/com/github/weisj/darklaf/properties/ui/tristate.properties b/core/src/main/resources/com/github/weisj/darklaf/properties/ui/tristate.properties index f5782258..365034ed 100644 --- a/core/src/main/resources/com/github/weisj/darklaf/properties/ui/tristate.properties +++ b/core/src/main/resources/com/github/weisj/darklaf/properties/ui/tristate.properties @@ -22,4 +22,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # -TristateCheckBoxUI = com.github.weisj.darklaf.ui.tristate.DarkTristateCheckBoxUI \ No newline at end of file +TristateCheckBoxUI = com.github.weisj.darklaf.ui.tristate.DarkTristateCheckBoxUI +TristateCheckBoxMenuItemUI = com.github.weisj.darklaf.ui.tristate.DarkTristateCheckBoxMenuItemUI diff --git a/core/src/test/java/ui/checkBox/CheckBoxDemo.java b/core/src/test/java/ui/checkBox/CheckBoxDemo.java index 1f1a92f3..7330699d 100644 --- a/core/src/test/java/ui/checkBox/CheckBoxDemo.java +++ b/core/src/test/java/ui/checkBox/CheckBoxDemo.java @@ -71,4 +71,13 @@ public class CheckBoxDemo implements ComponentDemo { return "CheckBox Demo"; } + @Override + public JMenuBar createMenuBar() { + JMenuBar menuBar = new JMenuBar(); + menuBar.add(ComponentDemo.createThemeMenu()); + menuBar.add(new JMenu("Demo") {{ + add(new JCheckBoxMenuItem("CheckBox menu item")); + }}); + return menuBar; + } } diff --git a/core/src/test/java/ui/checkBox/TriCheckBoxDemo.java b/core/src/test/java/ui/checkBox/TriCheckBoxDemo.java index b739eba5..7c435897 100644 --- a/core/src/test/java/ui/checkBox/TriCheckBoxDemo.java +++ b/core/src/test/java/ui/checkBox/TriCheckBoxDemo.java @@ -71,4 +71,14 @@ public class TriCheckBoxDemo implements ComponentDemo { public String getTitle() { return "TriCheckBox Demo"; } + + @Override + public JMenuBar createMenuBar() { + JMenuBar menuBar = new JMenuBar(); + menuBar.add(ComponentDemo.createThemeMenu()); + menuBar.add(new JMenu("Demo") {{ + add(new TristateCheckBox("TristateCheckBox menu item")); + }}); + return menuBar; + } } diff --git a/core/src/test/java/ui/radioButton/RadioButtonDemo.java b/core/src/test/java/ui/radioButton/RadioButtonDemo.java index 4e9c8a7a..d1531e5d 100644 --- a/core/src/test/java/ui/radioButton/RadioButtonDemo.java +++ b/core/src/test/java/ui/radioButton/RadioButtonDemo.java @@ -71,4 +71,13 @@ public class RadioButtonDemo implements ComponentDemo { return "RadioButton Demo"; } + @Override + public JMenuBar createMenuBar() { + JMenuBar menuBar = new JMenuBar(); + menuBar.add(ComponentDemo.createThemeMenu()); + menuBar.add(new JMenu("Demo") {{ + add(new JRadioButtonMenuItem("RadioButton menu item")); + }}); + return menuBar; + } }