/* CheckSignalDialog.java created 2010-10-24 * */ package org.signalml.app.view.document.monitor.signalchecking; import static org.signalml.app.util.i18n.SvarogI18n._; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.EnumMap; import java.util.HashMap; import java.util.List; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.Timer; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import org.signalml.app.document.MonitorSignalDocument; import org.signalml.app.document.signal.SignalDocument; import org.signalml.app.model.montage.ElectrodeType; import org.signalml.app.model.montage.MontageDescriptor; import org.signalml.app.view.common.components.panels.AbstractPanel; import org.signalml.app.view.common.dialogs.AbstractDialog; import org.signalml.app.view.montage.visualreference.VisualReferenceModel; import org.signalml.domain.montage.Montage; import org.signalml.domain.montage.SourceMontage; import org.signalml.plugin.export.SignalMLException; /** * Checks and represents the signal state. * * @author Tomasz Sawicki */ public class CheckSignalDialog extends AbstractDialog { /** * Minimum windows size. */ private static final int WINDOW_HEIGHT = 750; private static final int WINDOW_WIDTH = 950; /** * The current montage. */ private Montage currentMontage; /** * The currently open document. */ private MonitorSignalDocument monitorSignalDocument; /** * A component showing the signal status. */ private CheckSignalDisplay checkSignalDisplay; /** * A current visual reference model. */ private VisualReferenceModel visualReferenceModel; private JComboBox electrodeTypeComboBox; /** * Timer used to invoke {@link #timerClass} {@link TimerClass#run()}. */ private Timer timer; /** * Object which periodically does all the checking. */ private TimerClass timerClass; AmplifierValidationRules validationRules; public CheckSignalDialog(Window w, boolean isModal) { super(w, isModal); } /** * Sets window's title and size, then calls {@link AbstractDialog#initialize()}. */ @Override protected void initialize() { setTitle(_("Check Signal")); super.initialize(); setMinimumSize(new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT)); } /** * Creates the interface - a panel with {@link #checkSignalDisplay}. * * @return the interface */ @Override public JComponent createInterface() { JPanel interfacePanel = new JPanel(new BorderLayout()); JPanel editorPanel = new JPanel(new BorderLayout()); visualReferenceModel = new VisualReferenceModel(); checkSignalDisplay = new CheckSignalDisplay(visualReferenceModel); checkSignalDisplay.setBackground(Color.WHITE); JScrollPane editorScrollPane = new JScrollPane(checkSignalDisplay, JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); checkSignalDisplay.setViewport(editorScrollPane.getViewport()); editorPanel.setBorder(new CompoundBorder(new TitledBorder(_("Channels")), new EmptyBorder(3, 3, 3, 3))); editorPanel.add(editorScrollPane, BorderLayout.CENTER); JPanel parametersPanel = new AbstractPanel(_("Electrodes type")); electrodeTypeComboBox = new JComboBox(ElectrodeType.values()); electrodeTypeComboBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { HashMap<String,Object> parameters = validationRules.getMethods().get(SignalCheckingMethod.DC); ElectrodeType electrodeType = (ElectrodeType) electrodeTypeComboBox.getSelectedItem(); parameters.put(DCDiagnosis.ELECTRODE_TYPE, electrodeType); timerClass.actionPerformed(null); } }); parametersPanel.add(electrodeTypeComboBox); interfacePanel.add(editorPanel, BorderLayout.CENTER); interfacePanel.add(parametersPanel, BorderLayout.EAST); return interfacePanel; } /** * Sets the montage and starts the {@link #timer}. * * @param model model the model from which this dialog will be filled * @throws SignalMLException TODO when it is thrown */ @Override public void fillDialogFromModel(Object model) throws SignalMLException { MontageDescriptor descriptor = (MontageDescriptor) model; Montage montage = descriptor.getMontage(); SignalDocument signalDocument = descriptor.getSignalDocument(); if (montage == null) { currentMontage = new Montage(new SourceMontage(signalDocument)); } else { currentMontage = new Montage(montage); } getOkButton().setVisible(true); getRootPane().setDefaultButton(getOkButton()); setMontage(currentMontage); monitorSignalDocument = (MonitorSignalDocument) signalDocument; validationRules = getAmplifierValidationRules(); timerClass = new TimerClass(checkSignalDisplay, monitorSignalDocument, validationRules); timerClass.actionPerformed(null); timer = new Timer(validationRules.getDelay(), timerClass); timer.start(); } @Override public void fillModelFromDialog(Object model) throws SignalMLException { MontageDescriptor descriptor = (MontageDescriptor) model; descriptor.setMontage(currentMontage); } /** * Sets the montage for the component. * * @param montage {@link Montage} object */ private void setMontage(Montage montage) { visualReferenceModel.setMontage(montage); } /** * Returns validation rules of current signal. * * @return validation rules of current signal. */ private AmplifierValidationRules getAmplifierValidationRules() { // TODO currently returning a constant object, should obtain // the rules from signal or something EnumMap<SignalCheckingMethod, HashMap<String, Object>> methodList = new EnumMap<SignalCheckingMethod, HashMap<String, Object>>(SignalCheckingMethod.class); HashMap<String, Object> ampNullParameters = new HashMap<String, Object>(); ampNullParameters.put(GenericAmplifierDiagnosis.SAMPLES_TESTED_FACTOR, 1.0); ampNullParameters.put(AmplifierNullDiagnosis.TEST_TOLERANCE, 0.99); methodList.put(SignalCheckingMethod.AMPNULL, ampNullParameters); HashMap<String, Object> dcNullParameters = new HashMap<String, Object>(); dcNullParameters.put(GenericAmplifierDiagnosis.SAMPLES_TESTED_FACTOR, 1.0); dcNullParameters.put(DCDiagnosis.ELECTRODE_TYPE, electrodeTypeComboBox.getSelectedItem()); methodList.put(SignalCheckingMethod.DC, dcNullParameters); /*HashMap<String, Object> fftNullParameters = new HashMap<String, Object>(); fftNullParameters.put(FFTDiagnosis.ELECTRODE_TYPE, electrodeTypeComboBox.getSelectedItem()); fftNullParameters.put(GenericAmplifierDiagnosis.SAMPLES_TESTED_FACTOR, 0.5); methodList.put(SignalCheckingMethod.FFT, fftNullParameters);*/ return new AmplifierValidationRules("TMSI-porti7", methodList, 3000); } /** * Stops the timer on dialog close. Then calls {@link AbstractDialog#onDialogClose()}. */ @Override protected void onDialogClose() { super.onDialogClose(); timer.stop(); setMontage(null); } /** * Is not cancellable. * @return false */ @Override public boolean isCancellable() { return false; } /** * Whether the model is a montage object. * @param clazz model's class * @return true if clazz is montage */ @Override public boolean supportsModelClass(Class<?> clazz) { return MontageDescriptor.class.isAssignableFrom(clazz); } /** * This class' instance is passed to the {@link Timer} object of a {@link CheckSignalDialog}. * It gets a {@link GenericAmplifierDiagnosis} object and calls it's {@link GenericAmplifierDiagnosis#signalState()} method * constantly in a seperate thread with a given delay. */ private class TimerClass implements ActionListener { /** * Amplifier diagnosis' list. */ private List<GenericAmplifierDiagnosis> amplifierDiagnosis; /** * The display to update. */ private CheckSignalDisplay checkSignalDisplay; /** * Constructor which gets a {@link GenericAmplifierDiagnosis} based on a {@link MonitorSignalDocument} object * for a given amplifier model. * * @param checkSignalDisplay A {@link CheckSignalDisplay} object to which the information from a amplifier diagnosis will be passed * @param monitorSignalDocument A document representing the signal from an amplifier * @param validationRules amplifier validation rules */ public TimerClass(CheckSignalDisplay checkSignalDisplay, MonitorSignalDocument monitorSignalDocument, AmplifierValidationRules validationRules) { this.checkSignalDisplay = checkSignalDisplay; amplifierDiagnosis = new ArrayList<GenericAmplifierDiagnosis>(); for (SignalCheckingMethod method : validationRules.getMethods().keySet()) amplifierDiagnosis.add(AmplifierDignosisManufacture.getAmplifierDiagnosis(method, monitorSignalDocument, validationRules.getMethods().get(method))); } /** * Calls the {@link #run()} method in a seperate thread. * * @param e {@link ActionEvent} object */ @Override public void actionPerformed(ActionEvent e) { List<HashMap<String, ChannelState>> channels = new ArrayList<HashMap<String, ChannelState>>(); for (GenericAmplifierDiagnosis diagnosis : amplifierDiagnosis) channels.add(diagnosis.signalState()); checkSignalDisplay.setChannelsState(channels); } } }