/*
* #%L
* gitools-ui-platform
* %%
* Copyright (C) 2013 Universitat Pompeu Fabra - Biomedical Genomics group
* %%
* 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/gpl-3.0.html>.
* #L%
*/
package org.gitools.ui.platform.imageviewer;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* A component for displaying a series of images. Supports paging through GUI as well as setting the current
* position via function {@link #setPosition(int)}. When the position is changed, the {@link #positionChanged()}
* method is called. Subclasses should override this method to update the image according to the new position.
*
* @author Kazó Csaba
*/
public class ImageSequenceViewer {
private final ImageViewer imageViewer;
private int number, position;
private JButton forwardButton, backwardButton;
private JLabel locationLabel;
private JPanel panel = new JPanel(new BorderLayout()) {
/**
* Overridden to call {@link #positionChanged()}.
*/
@Override
public void addNotify() {
super.addNotify();
positionChanged();
}
};
/**
* Creates a new sequence viewer that can display the specified number of images.
*
* @param number the number of images
* @throws IllegalArgumentException if the number is negative
*/
public ImageSequenceViewer(int number) {
this(number, 0);
}
/**
* Creates a new sequence viewer that can display the specified number of images.
*
* @param number the number of images
* @param startPos the initial position of the viewer
* @throws IllegalArgumentException if the number is negative or the starting position is not valid
*/
public ImageSequenceViewer(int number, int startPos) {
if (number <= 0 || startPos < 0 || startPos >= number)
throw new IllegalArgumentException();
imageViewer = new ImageViewer();
this.number = number;
this.position = startPos;
panel.add(imageViewer.getComponent(), BorderLayout.CENTER);
forwardButton = new JButton(">");
backwardButton = new JButton("<");
JPanel locationPanel = new JPanel(new FlowLayout());
locationPanel.add(backwardButton);
locationPanel.add(createLocationDefinition());
locationPanel.add(forwardButton);
forwardButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setPosition(position + 1);
}
});
backwardButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setPosition(position - 1);
}
});
panel.add(locationPanel, BorderLayout.NORTH);
setPosition(position);
}
/**
* Returns the Swing component for this sequence viewer.
*
* @return the component
*/
public JComponent getComponent() {
return panel;
}
/**
* Called when the current position of the viewer has changed. The default implementation does nothing.
* Subclasses should override this method to update the image.
* <p/>
* This method is not called from the constructor, but it is called before the viewer is made visible,
* so subclasses can safely use this method to set the initial image.
*/
protected void positionChanged() {
}
public ImageViewer getImageViewer() {
return imageViewer;
}
/**
* Sets the position of the viewer.
*
* @param pos the new position of the viewer
* @throws IllegalArgumentException if the position is not valid
*/
public void setPosition(int pos) {
if (pos < 0 || pos >= number)
throw new IllegalArgumentException("Position " + pos + " out of range");
position = pos;
updateLocationDefinition(position);
forwardButton.setEnabled(position < number - 1);
backwardButton.setEnabled(position > 0);
if (panel.getParent() != null) positionChanged();
}
/**
* Returns the current position of this image sequence shower.
*/
public int getPosition() {
return position;
}
/**
* Creates and returns the component that displays the current position to the user. The default implementation
* creates a <code>JLabel</code>.
*
* @return the location component
*/
protected JComponent createLocationDefinition() {
locationLabel = new JLabel();
return locationLabel;
}
/**
* Called when the current position changes to update the location component.
*
* @param pos the current position
*/
protected void updateLocationDefinition(int pos) {
locationLabel.setText(String.format("%d/%d", pos + 1, number));
}
}