/* * Based on "TristateCheckBox Revisited" (2007-05-25) * By Dr. Heinz M. Kabutz * http://www.javaspecialists.co.za/archive/Issue145.html */ package net.vhati.modmanager.ui.tree; import java.awt.AWTEvent; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.ButtonModel; import javax.swing.Icon; import javax.swing.JCheckBox; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.plaf.ActionMapUIResource; import net.vhati.modmanager.ui.tree.TristateButtonModel; import net.vhati.modmanager.ui.tree.TristateButtonModel.TristateState; public class TristateCheckBox extends JCheckBox { private final ChangeListener enableListener; public TristateCheckBox( String text, Icon icon, TristateState initial ) { super( text, icon ); setModel( new TristateButtonModel( initial ) ); enableListener = new ChangeListener() { @Override public void stateChanged( ChangeEvent e ) { TristateCheckBox.this.setFocusable( TristateCheckBox.this.getModel().isEnabled() ); } }; // Add a listener for when the mouse is pressed. super.addMouseListener(new MouseAdapter() { @Override public void mousePressed( MouseEvent e ) { TristateCheckBox.this.iterateState(); } }); // Reset the keyboard action map. ActionMap map = new ActionMapUIResource(); map.put( "pressed", new AbstractAction() { @Override public void actionPerformed( ActionEvent e ) { TristateCheckBox.this.iterateState(); } }); map.put( "released", null ); SwingUtilities.replaceUIActionMap( this, map ); } public TristateCheckBox( String text, TristateState initial ) { this( text, null, initial ); } public TristateCheckBox( String text ) { this( text, null ); } public TristateCheckBox() { this( null ); } public void setIndeterminate() { getTristateModel().setIndeterminate(); } public boolean isIndeterminate() { return getTristateModel().isIndeterminate(); } public void setState( TristateState state ) { getTristateModel().setState( state ); } public TristateState getState() { return getTristateModel().getState(); } @Override public void setModel( ButtonModel newModel ) { super.setModel( newModel ); // Listen for enable changes. if ( model instanceof TristateButtonModel ) { model.addChangeListener( enableListener ); } } @SuppressWarnings("unchecked") public TristateButtonModel getTristateModel() { return (TristateButtonModel)super.getModel(); } /** * No one may add mouse listeners, not even Swing! */ @Override public void addMouseListener( MouseListener l ) { } private void iterateState() { // Maybe do nothing at all? if ( !super.getModel().isEnabled() ) return; this.grabFocus(); // Iterate state. getTristateModel().iterateState(); // Fire ActionEvent. 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, this.getText(), System.currentTimeMillis(), modifiers )); } }