001package jmri.util.com.sun; 002 003import java.awt.event.ActionEvent; 004import javax.swing.JToggleButton; 005 006// import org.slf4j.Logger; 007// import org.slf4j.LoggerFactory; 008 009/** 010 * ToggleOrPressButtonModel handles the storage and maintenance of the 011 * state of the button. 012 * <p> 013 * Changes the state of the function 014 * depending on the locking state of the button. 015 * <p> 016 * Modified from http://developer.classpath.org/doc/javax/swing/JToggleButton-source.html 017 * <p> 018 * Updates the button state depending if is lockable. 019 * @since 4.19.6 020 * @author Steve Young 021 * 022 */ 023public class ToggleOrPressButtonModel extends javax.swing.JToggleButton.ToggleButtonModel { 024 025 private final JToggleButton _button; 026 private boolean _isLockable; 027 028 /** 029 * Create a new ToggleOrPressButtonModel. 030 * @param button the button being controlled. 031 * @param startLockable true to start as a toggle button, 032 * false to start as a click on / release off button. 033 */ 034 public ToggleOrPressButtonModel(JToggleButton button, boolean startLockable){ 035 super(); 036 _button = button; 037 _isLockable = startLockable; 038 } 039 040 /** 041 * Set button lockable state. 042 * <p> 043 * Lockable on - Normal Toggle button. 044 * Lockable off - push on, release off. 045 * <p> 046 * If button is set unlocked when pressed, is de-pressed. 047 * @param lockable true for lockable, else false. 048 */ 049 public void setLockable(boolean lockable) { 050 _isLockable = lockable; 051 if (!_isLockable && isSelected()){ 052 stateMask = ( stateMask | PRESSED ); // mark button pressed without creating event 053 setPressed(false); // depress button creating event. 054 } 055 } 056 057 /** 058 * Get if Button is Lockable. 059 * @return true if normal toggle button, false if push on release off. 060 */ 061 public boolean getLockable() { 062 return _isLockable; 063 } 064 065 /** 066 * An external change has happened so we update. 067 * @param p new Selected state. 068 */ 069 public void updateSelected(boolean p){ 070 setSelected(p); 071 } 072 073 /** 074 * Sets the pressed state of the button. 075 * <p> 076 * The selected state 077 * of the button also changes following the button being pressed. 078 * 079 * @param p true if the button is pressed down. 080 */ 081 @Override 082 public void setPressed(boolean p) { 083 // cannot change PRESSED state unless button is enabled 084 if (! isEnabled()) 085 return; 086 087 // if this call does not represent a CHANGE in state, then return 088 if ((p && isPressed()) || (!p && !isPressed())) 089 return; 090 091 stateMask = ( p ? ( stateMask | PRESSED) : (stateMask & (~PRESSED))); 092 093 // The JDK first fires events in the following order: 094 // 1. ChangeEvent for selected 095 // 2. ChangeEvent for pressed 096 // 3. ActionEvent 097 098 if (_isLockable) { // if we were armed, we flip the selected state. 099 if (!p ) { // only change state on button release 100 setSelected (! isSelected()); // flip the selected state. 101 _button.setSelected(isSelected()); 102 } 103 } 104 else { 105 setSelected(p); 106 _button.setSelected(isSelected()); 107 } 108 109 // notify interested ChangeListeners 110 fireStateChanged(); 111 fireActionPerformed(new ActionEvent(this, 112 ActionEvent.ACTION_PERFORMED, actionCommand)); 113 114 } 115 116 // private final static Logger log = LoggerFactory.getLogger(ToggleOrPressButtonModel.class); 117 118}