001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.gui.sequence.tools;
020
021import icy.gui.component.sequence.SequencePreviewPanel;
022import icy.sequence.DimensionId;
023import icy.sequence.Sequence;
024import icy.sequence.SequenceModel;
025
026import java.awt.GridBagConstraints;
027import java.awt.GridBagLayout;
028import java.awt.Insets;
029import java.awt.event.ActionEvent;
030import java.awt.event.ActionListener;
031
032import javax.swing.JCheckBox;
033import javax.swing.JLabel;
034import javax.swing.JPanel;
035import javax.swing.JSpinner;
036import javax.swing.SpinnerNumberModel;
037import javax.swing.SwingConstants;
038import javax.swing.border.TitledBorder;
039import javax.swing.event.ChangeEvent;
040import javax.swing.event.ChangeListener;
041
042/**
043 * @author Stephane
044 */
045public class SequenceDimensionExtendPanel extends JPanel
046{
047    static class SequenceChannelEntry
048    {
049        final Sequence sequence;
050        final int c;
051
052        /**
053         * @param sequence
054         * @param c
055         */
056        public SequenceChannelEntry(Sequence sequence, int c)
057        {
058            super();
059
060            this.sequence = sequence;
061            this.c = c;
062        }
063
064        public SequenceChannelEntry(Sequence sequence)
065        {
066            this(sequence, -1);
067        }
068
069        @Override
070        public String toString()
071        {
072            if (c == -1)
073                return sequence.toString();
074
075            return sequence.toString() + "    [channel " + c + "]";
076        }
077    }
078
079    /**
080     * 
081     */
082    private static final long serialVersionUID = -5908902915282090447L;
083    protected SequencePreviewPanel sequencePreview;
084    private JLabel lblInsertPosition;
085    JSpinner insertPositionSpinner;
086    private JLabel lblNewZSize;
087    private JSpinner newSizeSpinner;
088    private JLabel lblImages;
089    JSpinner duplicateSpinner;
090    JCheckBox duplicateCheckBox;
091
092    // internals
093    protected final DimensionId dim;
094
095    /**
096     * Create the panel.
097     */
098    public SequenceDimensionExtendPanel(DimensionId dim)
099    {
100        super();
101
102        if ((dim != DimensionId.Z) && (dim != DimensionId.T))
103            throw new IllegalArgumentException("Only Z or T dimension allowed");
104
105        this.dim = dim;
106
107        initialize();
108
109        newSizeSpinner.addChangeListener(new ChangeListener()
110        {
111            @Override
112            public void stateChanged(ChangeEvent e)
113            {
114                previewDimensionChanged();
115                fireChangedEvent();
116            }
117        });
118
119        final ChangeListener changeListener = new ChangeListener()
120        {
121            @Override
122            public void stateChanged(ChangeEvent e)
123            {
124                previewImageChanged();
125                fireChangedEvent();
126            }
127        };
128
129        insertPositionSpinner.addChangeListener(changeListener);
130        duplicateSpinner.addChangeListener(changeListener);
131
132        duplicateCheckBox.addActionListener(new ActionListener()
133        {
134            @Override
135            public void actionPerformed(ActionEvent e)
136            {
137                duplicateSpinner.setEnabled(duplicateCheckBox.isSelected());
138
139                previewImageChanged();
140                fireChangedEvent();
141            }
142        });
143
144        refreshButtonsState();
145    }
146
147    private void initialize()
148    {
149        GridBagLayout gridBagLayout = new GridBagLayout();
150        gridBagLayout.columnWidths = new int[] {20, 0, 20, 0, 0, 0, 0};
151        gridBagLayout.rowHeights = new int[] {0, 0, 0, 174, 0};
152        gridBagLayout.columnWeights = new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};
153        gridBagLayout.rowWeights = new double[] {0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};
154        setLayout(gridBagLayout);
155
156        lblNewZSize = new JLabel("New size");
157        lblNewZSize.setToolTipText("New dimension size");
158        lblNewZSize.setHorizontalAlignment(SwingConstants.TRAILING);
159        GridBagConstraints gbc_lblNewZSize = new GridBagConstraints();
160        gbc_lblNewZSize.fill = GridBagConstraints.BOTH;
161        gbc_lblNewZSize.insets = new Insets(0, 0, 5, 5);
162        gbc_lblNewZSize.gridx = 1;
163        gbc_lblNewZSize.gridy = 0;
164        add(lblNewZSize, gbc_lblNewZSize);
165
166        newSizeSpinner = new JSpinner();
167        newSizeSpinner.setToolTipText("Enter new size");
168        newSizeSpinner.setModel(new SpinnerNumberModel(0, 0, 99999, 1));
169        GridBagConstraints gbc_newSizeSpinner = new GridBagConstraints();
170        gbc_newSizeSpinner.fill = GridBagConstraints.BOTH;
171        gbc_newSizeSpinner.insets = new Insets(0, 0, 5, 5);
172        gbc_newSizeSpinner.gridx = 3;
173        gbc_newSizeSpinner.gridy = 0;
174        add(newSizeSpinner, gbc_newSizeSpinner);
175
176        lblInsertPosition = new JLabel("Insert position");
177        lblInsertPosition.setToolTipText("Index where to add the new image(s)");
178        lblInsertPosition.setHorizontalAlignment(SwingConstants.TRAILING);
179        GridBagConstraints gbc_lblInsertPosition = new GridBagConstraints();
180        gbc_lblInsertPosition.fill = GridBagConstraints.BOTH;
181        gbc_lblInsertPosition.insets = new Insets(0, 0, 5, 5);
182        gbc_lblInsertPosition.gridx = 1;
183        gbc_lblInsertPosition.gridy = 1;
184        add(lblInsertPosition, gbc_lblInsertPosition);
185
186        insertPositionSpinner = new JSpinner();
187        insertPositionSpinner.setToolTipText("Index where to add the new image(s)");
188        insertPositionSpinner.setModel(new SpinnerNumberModel(0, 0, 99999, 1));
189        GridBagConstraints gbc_insertPositionSpinner = new GridBagConstraints();
190        gbc_insertPositionSpinner.fill = GridBagConstraints.BOTH;
191        gbc_insertPositionSpinner.insets = new Insets(0, 0, 5, 5);
192        gbc_insertPositionSpinner.gridx = 3;
193        gbc_insertPositionSpinner.gridy = 1;
194        add(insertPositionSpinner, gbc_insertPositionSpinner);
195
196        duplicateCheckBox = new JCheckBox("Duplicate last");
197        duplicateCheckBox.setToolTipText("Duplicate last images in new images");
198        GridBagConstraints gbc_duplicateCheckBox = new GridBagConstraints();
199        gbc_duplicateCheckBox.fill = GridBagConstraints.BOTH;
200        gbc_duplicateCheckBox.insets = new Insets(0, 0, 5, 5);
201        gbc_duplicateCheckBox.gridx = 1;
202        gbc_duplicateCheckBox.gridy = 2;
203        add(duplicateCheckBox, gbc_duplicateCheckBox);
204
205        duplicateSpinner = new JSpinner();
206        duplicateSpinner.setToolTipText("Number of last images to duplicate");
207        duplicateSpinner.setEnabled(false);
208        duplicateSpinner.setModel(new SpinnerNumberModel(1, 1, 99999, 1));
209        GridBagConstraints gbc_duplicateSpinner = new GridBagConstraints();
210        gbc_duplicateSpinner.fill = GridBagConstraints.BOTH;
211        gbc_duplicateSpinner.insets = new Insets(0, 0, 5, 5);
212        gbc_duplicateSpinner.gridx = 3;
213        gbc_duplicateSpinner.gridy = 2;
214        add(duplicateSpinner, gbc_duplicateSpinner);
215
216        lblImages = new JLabel("image(s)");
217        GridBagConstraints gbc_lblImages = new GridBagConstraints();
218        gbc_lblImages.gridwidth = 2;
219        gbc_lblImages.fill = GridBagConstraints.BOTH;
220        gbc_lblImages.insets = new Insets(0, 0, 5, 0);
221        gbc_lblImages.gridx = 4;
222        gbc_lblImages.gridy = 2;
223        add(lblImages, gbc_lblImages);
224
225        sequencePreview = new SequencePreviewPanel();
226        sequencePreview
227                .setBorder(new TitledBorder(null, "Preview", TitledBorder.LEADING, TitledBorder.TOP, null, null));
228        GridBagConstraints gbc_sequencePreview = new GridBagConstraints();
229        gbc_sequencePreview.gridwidth = 6;
230        gbc_sequencePreview.fill = GridBagConstraints.BOTH;
231        gbc_sequencePreview.gridx = 0;
232        gbc_sequencePreview.gridy = 3;
233        add(sequencePreview, gbc_sequencePreview);
234    }
235
236    public DimensionId getDimensionId()
237    {
238        return dim;
239    }
240
241    void refreshButtonsState()
242    {
243    }
244
245    /**
246     * @return the image provider
247     */
248    public SequenceModel getModel()
249    {
250        return sequencePreview.getModel();
251    }
252
253    public void setModel(SequenceModel model)
254    {
255        sequencePreview.setModel(model);
256    }
257
258    public void previewDimensionChanged()
259    {
260        sequencePreview.dimensionChanged();
261    }
262
263    public void previewImageChanged()
264    {
265        sequencePreview.imageChanged();
266    }
267
268    public int getNewSize()
269    {
270        return ((Integer) newSizeSpinner.getValue()).intValue();
271    }
272
273    public int getInsertPosition()
274    {
275        return ((Integer) insertPositionSpinner.getValue()).intValue();
276    }
277
278    public int getDuplicateNumber()
279    {
280        if (!duplicateCheckBox.isSelected())
281            return 0;
282
283        return ((Integer) duplicateSpinner.getValue()).intValue();
284    }
285
286    public void setNewSize(int size)
287    {
288        newSizeSpinner.setModel(new SpinnerNumberModel(size, size, 99999, 1));
289        insertPositionSpinner.setModel(new SpinnerNumberModel(size, 0, size, 1));
290    }
291
292    public void setInsertPosition(int position)
293    {
294        insertPositionSpinner.setValue(Integer.valueOf(position));
295    }
296
297    public void setMaxDuplicate(int max)
298    {
299        duplicateSpinner.setModel(new SpinnerNumberModel(1, 1, Math.max(max, 1), 1));
300    }
301
302    protected void fireChangedEvent()
303    {
304        final ChangeEvent event = new ChangeEvent(SequenceDimensionExtendPanel.this);
305
306        for (ChangeListener listener : getListeners(ChangeListener.class))
307            listener.stateChanged(event);
308    }
309
310    public void addChangeListener(ChangeListener listener)
311    {
312        listenerList.add(ChangeListener.class, listener);
313    }
314
315    public void removeChangeListener(ChangeListener listener)
316    {
317        listenerList.remove(ChangeListener.class, listener);
318    }
319
320}