/* Mjdj MIDI Morph - an extensible MIDI processor and translator. Copyright (C) 2010 Confusionists, LLC (www.confusionists.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. You may contact the author at mjdj_midi_morph [at] confusionists.com */ package com.confusionists.mjdj.ui; import java.util.Hashtable; import javax.swing.JCheckBox; import javax.swing.JOptionPane; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import com.confusionists.mjdj.Universe; import com.confusionists.mjdj.settings.Settings; import com.confusionists.mjdjApi.midiDevice.DeviceWrapper; import com.confusionists.mjdjApi.midiDevice.ReceiverDeviceWrapper; import com.confusionists.swing.RightClickable; public class MidiDeviceCheckbox extends JCheckBox implements ChangeListener, RightClickable { boolean initializing = true; private static final long serialVersionUID = 847604558283904051L; DeviceWrapper wrapper; private Hashtable<String, Boolean> getSettings() { return getSettings(false); } private Hashtable<String, Boolean> getSettings(boolean getOpposite) { boolean useReceiverList = (wrapper instanceof ReceiverDeviceWrapper); if (getOpposite) useReceiverList = !useReceiverList; if (useReceiverList) { return Settings.getInstance().receivers; } else { return Settings.getInstance().transmitters; } } public MidiDeviceCheckbox(DeviceWrapper wrapper) { super(wrapper.getName()); this.wrapper = wrapper; addChangeListener(this); boolean value = Settings.getBoolean(getSettings(), wrapper.toString(), false); if (value != isSelected()) { doClick(); } initializing = false; } public void close() { this.wrapper = null; } @Override public void stateChanged(ChangeEvent e) { boolean valid = validateSelection(); if (!valid) { this.setSelected(Settings.getBoolean(getSettings(), wrapper.toString())); return; } getSettings().put(wrapper.toString(), this.isSelected()); boolean realValue = Settings.getBoolean(getSettings(), wrapper.toString()); wrapper.setActive(realValue); if (realValue != this.isSelected()) { this.setSelected(realValue); // we might loop once here, but it's } } @Override public String getName() { return wrapper.getName(); } /* avoid feedback loops especially for IAC-type ports */ private boolean validateSelection() { if (initializing) return true; if (Settings.getBoolean(getSettings(true), this.getName()) && ((Boolean) this.isSelected()).booleanValue()) { int result = JOptionPane.showConfirmDialog(Universe.instance.main, "About to turn " + this.getName() + " on. The opposite port with the same name is on.\n" + "This could create a feedback loop. Do it anyway?", "Mjdj - Confirm Selection", JOptionPane.OK_CANCEL_OPTION); if (result != JOptionPane.OK_OPTION) return false; } return true; } @Override public void onRightClick() { wrapper.toggleUi(); } @Override public void setEnabled(boolean b) { boolean originalInitializing = initializing; initializing = true; super.setEnabled(b); initializing = originalInitializing; } }