All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tinymediamanager.ui.components.TriStateCheckBox Maven / Gradle / Ivy

The newest version!
/*
 * Copyright  -  Manuel Laggner
 *
 * 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 org.tinymediamanager.ui.components;

import java.awt.AWTEvent;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;

import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JToggleButton;
import javax.swing.UIManager;

/**
 * The class TriStateCheckBox ist a JCheckBox which has been enhanced by a third state: Mixed
* BE AWARE: in the mixed state also isSelected() == true * * @author Manuel Laggner */ public class TriStateCheckBox extends JCheckBox implements ActionListener { public static final int STATE_UNSELECTED = 0; public static final int STATE_SELECTED = 1; public static final int STATE_MIXED = 2; public TriStateCheckBox(String text, Icon icon) { super(text, icon); } public TriStateCheckBox(String text) { this(text, null); } public TriStateCheckBox() { this(null); } @Override protected void init(String text, Icon icon) { model = createButtonModel(); setModel(model); addActionListener(this); super.init(text, icon); } /** * Creates the button model. In this case, it is always a TriStateButtonModel. * * @return TristateButtonModel */ protected ButtonModel createButtonModel() { return new TriStateButtonModel(); } @Override public void updateUI() { super.updateUI(); if (isMixed()) { adjustMixedIcon(); } else { restoreMixedIcon(); } } protected void adjustMixedIcon() { setIcon(UIManager.getIcon("TriStateCheckBox.icon")); } protected void restoreMixedIcon() { setIcon(null); } /** * Checks if the check box is in mixed selection state. * * @return true or false. */ public boolean isMixed() { return getState() == STATE_MIXED; } /** * Sets the check box to mixed selection state. * * @param b * true or false. True means mixed state. False means unselected state. */ public void setMixed(boolean b) { if (b) { setState(STATE_MIXED); } else { setState(STATE_UNSELECTED); } } /** * Gets the selection state. It could be one of the three states as defined - {@link #STATE_SELECTED}, {@link #STATE_UNSELECTED} and * {@link #STATE_MIXED}. * * @return one of the three selection states. */ public int getState() { if (model instanceof TriStateButtonModel) return ((TriStateButtonModel) model).getState(); else { throw new IllegalStateException("TriStateButtonModel is required for TriStateCheckBox"); } } /** * Sets the selection state. It could be one of the three states as defined - {@link #STATE_SELECTED}, {@link #STATE_UNSELECTED} and * {@link #STATE_MIXED}. * * @param state * one of the three selection states. */ public void setState(int state) { if (model instanceof TriStateButtonModel) { int old = ((TriStateButtonModel) model).getState(); if (old != state) { ((TriStateButtonModel) model).setState(state); } stateUpdated(state); } else { throw new IllegalStateException("TriStateButtonModel is required for TriStateCheckBox"); } } @Override public void actionPerformed(ActionEvent e) { stateUpdated(getState()); } /** * This method is called when the selection state changes. * * @param state * the new selection state. */ protected void stateUpdated(int state) { if (state == STATE_MIXED) { adjustMixedIcon(); } else { restoreMixedIcon(); } } public static class TriStateButtonModel extends JToggleButton.ToggleButtonModel { private static final long serialVersionUID = 1257832793162900012L; /** * Identifies the "mixed" bit in the bitmask, which indicates that the button is partial selected. */ public final static int MIXED = 1 << 7; public TriStateButtonModel() { } public void setState(int state) { switch (state) { case TriStateCheckBox.STATE_UNSELECTED: setSelected(false); break; case TriStateCheckBox.STATE_SELECTED: setSelected(true); break; case TriStateCheckBox.STATE_MIXED: setMixed(true); break; } } public int getState() { if (isMixed()) { return TriStateCheckBox.STATE_MIXED; } else if (isSelected()) { return TriStateCheckBox.STATE_SELECTED; } else { return TriStateCheckBox.STATE_UNSELECTED; } } /** * We rotate between STATE_UNSELECTED, STATE_SELECTED and STATE_MIXED. * * @param current * the current state * @return the next state of the current state. */ protected int getNextState(int current) { if (current == TriStateCheckBox.STATE_UNSELECTED) { return TriStateCheckBox.STATE_SELECTED; } else if (current == TriStateCheckBox.STATE_SELECTED) { return TriStateCheckBox.STATE_MIXED; } else /* if (current == STATE_MIXED) */ { return TriStateCheckBox.STATE_UNSELECTED; } } @Override public void setPressed(boolean b) { if ((isPressed() == b) || !isEnabled()) { return; } if (!b && isArmed()) { updateState(); } if (b) { stateMask |= PRESSED; } else { stateMask &= ~PRESSED; } fireStateChanged(); if (!isPressed() && isArmed()) { int modifiers = 0; AWTEvent currentEvent = EventQueue.getCurrentEvent(); if (currentEvent instanceof InputEvent) { modifiers = ((InputEvent) currentEvent).getModifiers(); } else if (currentEvent instanceof ActionEvent) { modifiers = ((ActionEvent) currentEvent).getModifiers(); } fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, getActionCommand(), EventQueue.getMostRecentEventTime(), modifiers)); } } /** * Updates the state when the mouse is clicked. */ protected void updateState() { setState(getNextState(getState())); } @Override public void setSelected(boolean b) { boolean mixed = isMixed(); if (mixed) { stateMask &= ~MIXED; internalSetSelected(!isSelected()); } super.setSelected(b); } void internalSetSelected(boolean b) { if (b) { stateMask |= SELECTED; } else { stateMask &= ~SELECTED; } } public boolean isMixed() { return (stateMask & MIXED) != 0; } public void setMixed(boolean b) { if ((isMixed() == b)) { return; } if (b) { stateMask |= MIXED; stateMask |= SELECTED; // make it selected } else { stateMask &= ~MIXED; } fireStateChanged(); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy