/* CompareTagsPopupDialog.java created 2007-11-13 * */ package org.signalml.app.view.signal.popup; import static org.signalml.app.util.i18n.SvarogI18n._; import static org.signalml.app.util.i18n.SvarogI18n._R; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.List; import javax.swing.AbstractAction; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import org.signalml.app.document.TagDocument; import org.signalml.app.model.tag.TagComparisonDescriptor; import org.signalml.app.util.IconUtils; import org.signalml.app.view.common.components.TitledCrossBorder; import org.signalml.app.view.signal.SignalView; import org.signalml.app.view.tag.comparison.TagComparisonDialog; import org.signalml.exception.SanityCheckException; import org.signalml.plugin.export.SignalMLException; import org.signalml.plugin.export.view.AbstractPopupDialog; /** CompareTagsPopupDialog * * * @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o. */ public class CompareTagsPopupDialog extends AbstractPopupDialog { private static final long serialVersionUID = 1L; private SignalView signalView; private JRadioButton compareOffRadio; private JRadioButton compareOnRadio; private JCheckBox[] checkBoxes; private TagDocument[] tagDocuments; private AnalyzeAction analyzeAction; private JButton analyzeButton; private TagComparisonDialog tagComparisonDialog; public CompareTagsPopupDialog(Window w, boolean isModal) { super(w, isModal); } public SignalView getSignalView() { return signalView; } public void setSignalView(SignalView signalView) { this.signalView = signalView; } public TagComparisonDialog getTagComparisonDialog() { return tagComparisonDialog; } public void setTagComparisonDialog(TagComparisonDialog tagComparisonDialog) { this.tagComparisonDialog = tagComparisonDialog; } @Override public JComponent createInterface() { List<TagDocument> tags = signalView.getDocument().getTagDocuments(); int cnt = tags.size(); if (cnt < 2) { throw new SanityCheckException("Too few tag documents"); } tagDocuments = new TagDocument[cnt]; tags.toArray(tagDocuments); analyzeAction = new AnalyzeAction(); JPanel graphicalComparePanel = new JPanel(); graphicalComparePanel.setLayout(new BoxLayout(graphicalComparePanel, BoxLayout.Y_AXIS)); graphicalComparePanel.setBorder(new CompoundBorder( new TitledCrossBorder(_("Graphical comparison"), true), new EmptyBorder(3,3,3,3) )); compareOnRadio = new JRadioButton(_("Comparison mode enabled")); compareOffRadio = new JRadioButton(_("Comparison mode disabled")); ButtonGroup compareGroup = new ButtonGroup(); compareGroup.add(compareOffRadio); compareGroup.add(compareOnRadio); compareOnRadio.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { fillModelFromDialog(getCurrentModel()); } }); graphicalComparePanel.add(compareOffRadio); graphicalComparePanel.add(compareOnRadio); JPanel chooseTagsPanel = new JPanel(); chooseTagsPanel.setLayout(new GridLayout(cnt, 1, 3, 3)); chooseTagsPanel.setBorder(new CompoundBorder( new TitledBorder(_("Choose tag documents (2 required)")), new EmptyBorder(3,3,3,3) )); checkBoxes = new JCheckBox[cnt]; CheckBoxCoordinator checkBoxCoordinator = new CheckBoxCoordinator(); for (int i=0; i<cnt; i++) { final String message; if (tagDocuments[i].getBackingFile() == null) { message = _R("New tag {0}", tagDocuments[i].getName()); } else { message = tagDocuments[i].getName(); } checkBoxes[i] = new JCheckBox(message); chooseTagsPanel.add(checkBoxes[i]); checkBoxes[i].addItemListener(checkBoxCoordinator); } checkBoxes[0].setSelected(true); checkBoxes[1].setSelected(true); JPanel buttonPanel = new JPanel(new BorderLayout()); buttonPanel.setBorder(new EmptyBorder(3,0,0,0)); analyzeButton = new JButton(analyzeAction); buttonPanel.add(analyzeButton, BorderLayout.CENTER); JPanel interfacePanel = new JPanel(new BorderLayout()); interfacePanel.add(graphicalComparePanel, BorderLayout.NORTH); interfacePanel.add(chooseTagsPanel, BorderLayout.CENTER); interfacePanel.add(buttonPanel, BorderLayout.SOUTH); Dimension size = chooseTagsPanel.getPreferredSize(); if (size.width < 270) { size.width = 270; } chooseTagsPanel.setPreferredSize(size); return interfacePanel; } @Override public void fillDialogFromModel(Object model) throws SignalMLException { TagDocument[] comparedDocuments = signalView.getComparedTags(); if (comparedDocuments == null) { compareOffRadio.setSelected(true); } else { for (int i=0; i<tagDocuments.length; i++) { if (tagDocuments[i] == comparedDocuments[0] || tagDocuments[i] == comparedDocuments[1]) { checkBoxes[i].setSelected(true); // any deselection is handled by coordinator } } compareOnRadio.setSelected(true); } } @Override public void fillModelFromDialog(Object model) { if (compareOnRadio.isSelected()) { TagDocument[] tags = new TagDocument[2]; int cnt = 0; for (int i=0; i<checkBoxes.length; i++) { if (checkBoxes[i].isSelected()) { if (cnt > 1) { throw new SanityCheckException("More than 2 tags selected"); } tags[cnt] = tagDocuments[i]; cnt++; } } if (cnt == 2) { signalView.setComparedTags(tags[0], tags[1]); } else { signalView.setComparedTags(null, null); } } else { signalView.setComparedTags(null, null); } } @Override public boolean supportsModelClass(Class<?> clazz) { return (clazz == null); } @Override public boolean isControlPanelEquipped() { return false; } @Override public boolean isCancellable() { return true; } @Override public boolean isFormClickApproving() { return true; } private class CheckBoxCoordinator implements ItemListener { private JCheckBox penultimateSelection; private JCheckBox ultimateSelection; private boolean lock = false; @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { if (penultimateSelection != null) { try { lock = true; penultimateSelection.setSelected(false); // deselect the tag selected first } finally { lock = false; } } penultimateSelection = ultimateSelection; ultimateSelection = (JCheckBox) e.getSource(); } else { // compensate for manual deselection if (!lock) { Object source = e.getSource(); if (source == penultimateSelection) { penultimateSelection = null; } else if (source == ultimateSelection) { ultimateSelection = penultimateSelection; penultimateSelection = null; } } } if (!lock) { int selCnt = 0; for (JCheckBox checkBox : checkBoxes) { if (checkBox.isSelected()) { selCnt++; } } boolean canCompare = (selCnt == 2); // enable if two tags selected analyzeAction.setEnabled(canCompare); if (!canCompare) { compareOffRadio.setSelected(true); } compareOffRadio.setEnabled(canCompare); compareOnRadio.setEnabled(canCompare); if (canCompare && compareOnRadio.isSelected()) { fillModelFromDialog(getCurrentModel()); } } } } protected class AnalyzeAction extends AbstractAction { private static final long serialVersionUID = 1L; public AnalyzeAction() { super(_("Analyze tag differences")); putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/analyze.png")); putValue(AbstractAction.SHORT_DESCRIPTION,_("Show analytical comparison summary")); } public void actionPerformed(ActionEvent ev) { TagComparisonDescriptor descriptor = new TagComparisonDescriptor(signalView.getDocument()); descriptor.setTagIconProducer(signalView.getTagIconProducer()); int selCnt = 0; int i; for (i=0; i<checkBoxes.length; i++) { if (checkBoxes[i].isSelected()) { if (selCnt == 0) { descriptor.setTopTagDocument(tagDocuments[i]); } else if (selCnt == 1) { descriptor.setBottomTagDocument(tagDocuments[i]); break; } selCnt++; } } // temporarily hide the popup setVisible(false); tagComparisonDialog.showDialog(descriptor, true); TagDocument topDocument = descriptor.getTopTagDocument(); TagDocument bottomDocument = descriptor.getBottomTagDocument(); for (i=0; i<tagDocuments.length; i++) { if (tagDocuments[i] == topDocument || tagDocuments[i] == bottomDocument) { checkBoxes[i].setSelected(true); } } // restore the popup setVisible(true); } } }