/* MarkedTimeSpacePanel.java created 2008-01-25
*
*/
package org.signalml.app.view.signal.signalselection;
import static org.signalml.app.util.i18n.SvarogI18n._;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.DefaultComboBoxModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import org.apache.log4j.Logger;
import org.signalml.app.model.components.validation.ValidationErrors;
import org.signalml.app.view.tag.TagIconProducer;
import org.signalml.app.view.tag.TagStyleListCellRenderer;
import org.signalml.domain.signal.space.MarkerTimeSpace;
import org.signalml.domain.signal.space.SignalSpace;
import org.signalml.domain.signal.space.SignalSpaceConstraints;
import org.signalml.plugin.export.signal.TagStyle;
/**
* Panel that allows the user to select the parameters of
* {@link MarkerTimeSpace}.
* Contains two sub-panels:
* <ul>
* <li>{@link #getMarkerPanel() marker panel} which allows to select the
* channel from the list of their names and the {@link TagStyle style} of
* the marker,</li>
* <li>{@link #getSettingsPanel() settings panel} which allows to select
* how many seconds before and after the marker should be taken.</li>
* </ul>
*
* @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o.
*/
public class MarkedTimeSpacePanel extends JPanel {
private static final long serialVersionUID = 1L;
protected static final Logger logger = Logger.getLogger(MarkedTimeSpacePanel.class);
/**
* the panel which allows to select the
* channel from the list of their names and the {@link TagStyle style} of
* the marker
*/
private JPanel markerPanel;
/**
* the panel which allows to select how many seconds before and after the
* marker should be taken
*/
private JPanel settingsPanel;
/**
* the combo-box with the list of names of signal channels
*/
private JComboBox markerChannelComboBox;
/**
* the combo-box with the list of {@link TagStyle#isMarker() marker}
* {@link TagStyle styles}
*/
private JComboBox markerStyleComboBox;
/**
* the spinner which allows to select when, comparing to the marker tag,
* the time selection starts.
*/
private JSpinner startTimeSpinner;
/**
* the spinner which allows to select how many seconds the time selection
* lasts.
*/
private JSpinner lengthSpinner;
/**
* the names of channels,
* at index {@code i} - the name of the channel of index {@code i}
*/
private String[] channels;
/**
* the array of {@link TagStyle#isMarker() marker}
* {@link TagStyle styles}
*/
private TagStyle[] markerStyles;
/**
* the renderer of the elements of {@link #markerStyleComboBox}
*/
private TagStyleListCellRenderer markerStyleCellRenderer;
/**
* Constructor. Initializes the panel.
*/
public MarkedTimeSpacePanel() {
super();
initialize();
}
/**
* Adds two sub-panels to this panel (from top to bottom):
* <ul>
* <li>{@link #markerPanel},</li>
* <li>{@link #settingsPanel}.</li>
* </ul>
*/
private void initialize() {
setLayout(new BorderLayout());
setBorder(new EmptyBorder(3,3,3,3));
add(getMarkerPanel(), BorderLayout.CENTER);
add(getSettingsPanel(), BorderLayout.SOUTH);
}
/**
* Returns the marker panel with the group layout.
* The panel contains two groups:
* <ul>
* <li>horizontal group which has two sub-groups: one for labels and one
* for combo boxes. This group positions the elements in two columns.</li>
* <li>vertical group which has 2 sub-groups - one for every row:
* <ul>
* <li>label and combo-box which allows to select the channel from the list
* of the names of channels,</li>
* <li>label and combo-box which allows to select the marker
* {@link TagStyle style},</li>
* </ul>
* This group positions elements in rows.</li>
* </ul>
* If the panel doesn't exist it is created
* @return the marker panel
*/
public JPanel getMarkerPanel() {
if (markerPanel == null) {
markerPanel = new JPanel();
markerPanel.setBorder(new CompoundBorder(
new TitledBorder(_("Marker channel & style")),
new EmptyBorder(3,3,3,3)
));
GroupLayout layout = new GroupLayout(markerPanel);
markerPanel.setLayout(layout);
layout.setAutoCreateContainerGaps(false);
layout.setAutoCreateGaps(true);
JLabel markerChannelLabel = new JLabel(_("Marker channel"));
JLabel markerStyleLabel = new JLabel(_("Marker style"));
GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
hGroup.addGroup(
layout.createParallelGroup()
.addComponent(markerChannelLabel)
.addComponent(markerStyleLabel)
);
hGroup.addGroup(
layout.createParallelGroup()
.addComponent(getMarkerChannelComboBox())
.addComponent(getMarkerStyleComboBox())
);
layout.setHorizontalGroup(hGroup);
GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
vGroup.addGroup(
layout.createParallelGroup(Alignment.BASELINE)
.addComponent(markerChannelLabel)
.addComponent(getMarkerChannelComboBox())
);
vGroup.addGroup(
layout.createParallelGroup(Alignment.BASELINE)
.addComponent(markerStyleLabel)
.addComponent(getMarkerStyleComboBox())
);
layout.setVerticalGroup(vGroup);
}
return markerPanel;
}
/**
* Returns the combo-box which allows to select the channel from the list
* of the names of channels.
* @return the combo-box which allows to select the channel from the list
* of the names of channels
*/
public JComboBox getMarkerChannelComboBox() {
if (markerChannelComboBox == null) {
markerChannelComboBox = new JComboBox(new Object[0]);
markerChannelComboBox.setPreferredSize(new Dimension(200,25));
}
return markerChannelComboBox;
}
/**
* Returns the combo-box which allows to select the marker
* {@link TagStyle style}
* @return the combo-box which allows to select the marker style
*/
public JComboBox getMarkerStyleComboBox() {
if (markerStyleComboBox == null) {
markerStyleComboBox = new JComboBox(new Object[0]);
markerStyleComboBox.setPreferredSize(new Dimension(200,25));
markerStyleComboBox.setRenderer(getMarkerStyleCellRenderer());
}
return markerStyleComboBox;
}
/**
* Returns the renderer of the elements of {@link #getMarkerStyleComboBox()
* marker style combo-box}.
* @return the renderer of the elements of marker style combo-box
*/
public TagStyleListCellRenderer getMarkerStyleCellRenderer() {
if (markerStyleCellRenderer == null) {
markerStyleCellRenderer = new TagStyleListCellRenderer();
}
return markerStyleCellRenderer;
}
/**
* Returns the settings panel with the group layout.
* The panel contains two groups:
* <ul>
* <li>horizontal group which has two sub-groups: one for labels and one
* for spinners. This group positions the elements in two columns.</li>
* <li>vertical group which has 2 sub-groups - one for every row:
* <ul>
* <li>label and spinner which allows to select the number of seconds
* before the marker that should be used,</li>
* <li>label and spinner which allows to select the number of seconds
* after the marker that should be used,</li>
* </ul>
* This group positions elements in rows.</li>
* </ul>
* If the panel doesn't exist it is created
* @return the settings panel
*/
public JPanel getSettingsPanel() {
if (settingsPanel == null) {
settingsPanel = new JPanel();
settingsPanel.setBorder(new CompoundBorder(
new TitledBorder(_("Settings")),
new EmptyBorder(3,3,3,3)
));
GroupLayout layout = new GroupLayout(settingsPanel);
settingsPanel.setLayout(layout);
layout.setAutoCreateContainerGaps(false);
layout.setAutoCreateGaps(true);
JLabel startTimeLabel = new JLabel(_("Start time"));
JLabel segmentLengthLabel = new JLabel(_("Length"));
GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
hGroup.addGroup(
layout.createParallelGroup()
.addComponent(startTimeLabel)
.addComponent(segmentLengthLabel)
);
hGroup.addGroup(
layout.createParallelGroup(Alignment.TRAILING)
.addComponent(getStartTimeSpinner())
.addComponent(getLengthSpinner())
);
layout.setHorizontalGroup(hGroup);
GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
vGroup.addGroup(
layout.createParallelGroup(Alignment.BASELINE)
.addComponent(startTimeLabel)
.addComponent(getStartTimeSpinner())
);
vGroup.addGroup(
layout.createParallelGroup(Alignment.BASELINE)
.addComponent(segmentLengthLabel)
.addComponent(getLengthSpinner())
);
layout.setVerticalGroup(vGroup);
}
return settingsPanel;
}
public JSpinner getStartTimeSpinner() {
if (startTimeSpinner == null) {
startTimeSpinner = new JSpinner(new SpinnerNumberModel(1.0,-3600.0,3600,0.1));
Dimension fixedSize = new Dimension(200,25);
startTimeSpinner.setPreferredSize(fixedSize);
}
return startTimeSpinner;
}
public JSpinner getLengthSpinner() {
if (lengthSpinner == null) {
lengthSpinner = new JSpinner(new SpinnerNumberModel(1.0,0.1,3600,0.1));
Dimension fixedSize = new Dimension(200,25);
lengthSpinner.setPreferredSize(fixedSize);
}
return lengthSpinner;
}
/**
* Fills the fields of this panel using the {@link MarkerTimeSpace} from
* given {@link SignalSpace}:
* <ul>
* <li>if the MarkerTimeSpace is {@code null} fields are set to default values:
* <ul><li>first entry of combo boxes is set to be active,</li>
* <li>number of seconds before marker is set to {@code 0} and after the
* marker to {@code 1},</li></ul>
* <li>if {@link #getChannels() channels} exist the
* {@link MarkerTimeSpace#getMarkerChannel() active} one is set,</li>
* <li>if {@link #getMarkerStyles() marker styles} exist the
* {@link MarkerTimeSpace#getMarkerStyleName() active} one is set,</li>
* </li>number of seconds {@link MarkerTimeSpace#getStartTime() before}
* and {@link MarkerTimeSpace#getSegmentLength() after} the marker is set
* to spinners.</li>
* </ul>
* @param space the signal space
*/
public void fillPanelFromModel(SignalSpace space) {
MarkerTimeSpace markerTimeSpace = space.getMarkerTimeSpace();
JComboBox channelBox = getMarkerChannelComboBox();
JComboBox styleBox = getMarkerStyleComboBox();
if (markerTimeSpace == null) {
if (channelBox.getModel().getSize() > 0) {
channelBox.setSelectedIndex(0);
}
if (styleBox.getModel().getSize() > 0) {
styleBox.setSelectedIndex(0);
}
getLengthSpinner().setValue(new Double(1));
getStartTimeSpinner().setValue(new Double(0));
} else {
if (channels != null) {
int markerChannel = markerTimeSpace.getMarkerChannel();
if (markerChannel >= channels.length) {
markerChannel = 0;
}
channelBox.setSelectedIndex(markerChannel);
}
if (markerStyles != null) {
String markerStyleName = markerTimeSpace.getMarkerStyleName();
if (markerStyleName != null) {
for (int i=0; i<markerStyles.length; i++) {
if (markerStyleName.equals(markerStyles[i].getName())) {
styleBox.setSelectedItem(markerStyles[i]);
break;
}
}
} else {
channelBox.setSelectedIndex(0);
}
}
getStartTimeSpinner().setValue(markerTimeSpace.getStartTime());
getLengthSpinner().setValue(markerTimeSpace.getSegmentLength());
}
}
/**
* Stores the user input from this dialog to the {@link SignalSpace signal
* space}:
* <ul>
* <li>if the {@link MarkerTimeSpace} {@link SignalSpace#getMarkerTimeSpace()
* in} signal space doesn't exist it is created,</li>
* <li>sets the {@link MarkerTimeSpace#setMarkerChannel(int) marker channel}
* and the {@link MarkerTimeSpace#setMarkerStyleName(String) name} of the
* {@link TagStyle style}</li>
* <li>sets the number of seconds
* {@link MarkerTimeSpace#setStartTime(double) before} and
* {@link MarkerTimeSpace#setSegmentLength(double) after} the marker.</li>
* </ul>
* @param space the singal space in which the data will be stored
*/
public void fillModelFromPanel(SignalSpace space) {
MarkerTimeSpace markerTimeSpace = space.getMarkerTimeSpace();
if (markerTimeSpace == null) {
markerTimeSpace = new MarkerTimeSpace();
}
if (channels != null) {
markerTimeSpace.setMarkerChannel(getMarkerChannelComboBox().getSelectedIndex());
}
if (markerStyles != null) {
markerTimeSpace.setMarkerStyleName(((TagStyle) getMarkerStyleComboBox().getSelectedItem()).getName());
}
markerTimeSpace.setStartTime(((Double) getStartTimeSpinner().getValue()).doubleValue());
markerTimeSpace.setSegmentLength(((Double) getLengthSpinner().getValue()).doubleValue());
space.setMarkerTimeSpace(markerTimeSpace);
}
/**
* Returns the array with the names of channels,
* at index {@code i} - the name of the channel of index {@code i}.
* @return the array with the names of channels
*/
public String[] getChannels() {
return channels;
}
/**
* Sets the array with the names of channels,
* at index {@code i} - the name of the channel of index {@code i}.
* @param labels the array with the names of channels
*/
public void setChannels(String[] labels) {
if (this.channels != labels) {
this.channels = labels;
getMarkerChannelComboBox().setModel(new DefaultComboBoxModel(labels));
}
}
/**
* Returns the array of {@link TagStyle#isMarker() marker}
* {@link TagStyle styles}.
* @return the array of marker styles
*/
public TagStyle[] getMarkerStyles() {
return markerStyles;
}
/**
* Sets the array of {@link TagStyle#isMarker() marker}
* {@link TagStyle styles}.
* @param markerStyles the array of marker styles
*/
public void setMarkerStyles(TagStyle[] markerStyles) {
if (this.markerStyles != markerStyles) {
this.markerStyles = markerStyles;
if (markerStyles == null) {
getMarkerStyleComboBox().setModel(new DefaultComboBoxModel(new TagStyle[0]));
} else {
getMarkerStyleComboBox().setModel(new DefaultComboBoxModel(markerStyles));
}
}
}
/**
* Sets the {@link TagIconProducer producer} of icons for {@link TagStyle
* tag styles}.
* @param tagIconProducer the producer of icons for tag styles
*/
public void setTagIconProducer(TagIconProducer tagIconProducer) {
getMarkerStyleCellRenderer().setTagIconProducer(tagIconProducer);
}
/**
* Sets the {@link SignalSpaceConstraints parameters} of the signal:
* <ul>
* <li>the {@link #setChannels(String[]) names} of channels,</li>
* <li>the {@link #setMarkerStyles(TagStyle[]) styles} of markers,</li>
* <li>the {@link #setTagIconProducer(TagIconProducer) producer} of icons
* for these styles.</li>
* </ul>
* @param constraints the parameters of the signal
*/
public void setConstraints(SignalSpaceConstraints constraints) {
setChannels(constraints.getSourceChannels());
setTagIconProducer(constraints.getTagIconProducer());
setMarkerStyles(constraints.getMarkerStyles());
}
/**
* Validates this panel.
* @param errors the object in which the errors are stored.
*/
public void validatePanel(ValidationErrors errors) {
}
}