/*
* Copyright 2010-2015 Institut Pasteur.
*
* This file is part of Icy.
*
* Icy 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.
*
* Icy 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 Icy. If not, see <http://www.gnu.org/licenses/>.
*/
package icy.gui.sequence;
import icy.file.FileUtil;
import icy.gui.component.button.IcyButton;
import icy.gui.frame.GenericFrame;
import icy.gui.main.ActiveSequenceListener;
import icy.main.Icy;
import icy.math.UnitUtil;
import icy.math.UnitUtil.UnitPrefix;
import icy.resource.ResourceUtil;
import icy.resource.icon.IcyIcon;
import icy.sequence.Sequence;
import icy.sequence.SequenceEvent;
import icy.system.IcyExceptionHandler;
import icy.system.SystemUtil;
import icy.system.thread.ThreadUtil;
import icy.util.EventUtil;
import icy.util.StringUtil;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* @author Stephane
*/
public class SequenceInfosPanel extends JPanel implements ActiveSequenceListener
{
/**
*
*/
private static final long serialVersionUID = -6123324347914804260L;
// GUI
private JLabel dimensionLabel;
private JLabel resXLabel;
private JLabel resYLabel;
private JLabel resZLabel;
private JLabel resTLabel;
private JLabel sizeLabel;
private JLabel channelLabel;
private IcyButton editBtn;
private IcyButton detailBtn;
private JLabel pathLabel;
JTextField pathField;
private JTextField nameField;
// internals
private final Runnable infosRefresher;
public SequenceInfosPanel()
{
super();
initialize();
editBtn.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// it should be the current focused sequence
final Sequence seq = Icy.getMainInterface().getActiveSequence();
if (seq != null)
new SequencePropertiesDialog(seq);
}
});
detailBtn.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// it should be the current focused sequence
final Sequence seq = Icy.getMainInterface().getActiveSequence();
if (seq != null)
{
final GenericFrame g = new GenericFrame(seq.getName() + " - Metadata", new SequenceMetadataPanel(
seq));
g.addToDesktopPane();
g.center();
g.requestFocus();
}
}
});
infosRefresher = new Runnable()
{
@Override
public void run()
{
ThreadUtil.invokeNow(new Runnable()
{
@Override
public void run()
{
updateInfosInternal(Icy.getMainInterface().getActiveSequence());
}
});
}
};
updateInfosInternal(null);
}
public void initialize()
{
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[] {0, 40, 40, 40, 0};
gridBagLayout.rowHeights = new int[] {18, 0, 18, 18, 18, 18, 18, 18, 0};
gridBagLayout.columnWeights = new double[] {0.0, 1.0, 1.0, 1.0, Double.MIN_VALUE};
gridBagLayout.rowWeights = new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
setLayout(gridBagLayout);
JLabel lbl_name = new JLabel("Name");
lbl_name.setToolTipText("Sequence name");
GridBagConstraints gbc_lbl_name = new GridBagConstraints();
gbc_lbl_name.anchor = GridBagConstraints.WEST;
gbc_lbl_name.fill = GridBagConstraints.VERTICAL;
gbc_lbl_name.insets = new Insets(0, 0, 5, 5);
gbc_lbl_name.gridx = 0;
gbc_lbl_name.gridy = 0;
add(lbl_name, gbc_lbl_name);
nameField = new JTextField()
{
@Override
public Dimension getPreferredSize()
{
final Dimension result = super.getPreferredSize();
// prevent enlarging panel
result.width = 100;
return result;
}
};
nameField.setOpaque(false);
nameField.setBorder(null);
nameField.setEditable(false);
GridBagConstraints gbc_scrollPane = new GridBagConstraints();
gbc_scrollPane.fill = GridBagConstraints.BOTH;
gbc_scrollPane.gridwidth = 3;
gbc_scrollPane.insets = new Insets(0, 0, 5, 0);
gbc_scrollPane.gridx = 1;
gbc_scrollPane.gridy = 0;
add(nameField, gbc_scrollPane);
pathLabel = new JLabel("Path");
pathLabel.setToolTipText("Sequence file path");
GridBagConstraints gbc_pathLabel = new GridBagConstraints();
gbc_pathLabel.fill = GridBagConstraints.VERTICAL;
gbc_pathLabel.anchor = GridBagConstraints.WEST;
gbc_pathLabel.insets = new Insets(0, 0, 5, 5);
gbc_pathLabel.gridx = 0;
gbc_pathLabel.gridy = 1;
add(pathLabel, gbc_pathLabel);
pathField = new JTextField()
{
@Override
public Dimension getPreferredSize()
{
final Dimension result = super.getPreferredSize();
// prevent enlarging panel
result.width = 100;
return result;
}
};
pathField.setOpaque(false);
pathField.setBorder(null);
pathField.setEditable(false);
pathField.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
if (e.isConsumed())
return;
if (EventUtil.isLeftMouseButton(e) && (e.getClickCount() == 2))
{
try
{
SystemUtil.openFolder(FileUtil.getDirectory(pathField.getText()));
}
catch (IOException e1)
{
IcyExceptionHandler.showErrorMessage(e1, false, false);
}
e.consume();
}
}
});
GridBagConstraints gbc_scrollPane_1 = new GridBagConstraints();
gbc_scrollPane_1.fill = GridBagConstraints.BOTH;
gbc_scrollPane_1.gridwidth = 3;
gbc_scrollPane_1.insets = new Insets(0, 0, 5, 5);
gbc_scrollPane_1.gridx = 1;
gbc_scrollPane_1.gridy = 1;
add(pathField, gbc_scrollPane_1);
JLabel lbl_dim = new JLabel("Dimension");
lbl_dim.setToolTipText("Size of X, Y, Z and T dimension");
GridBagConstraints gbc_lbl_dim = new GridBagConstraints();
gbc_lbl_dim.anchor = GridBagConstraints.WEST;
gbc_lbl_dim.fill = GridBagConstraints.VERTICAL;
gbc_lbl_dim.insets = new Insets(0, 0, 5, 5);
gbc_lbl_dim.gridx = 0;
gbc_lbl_dim.gridy = 2;
add(lbl_dim, gbc_lbl_dim);
dimensionLabel = new JLabel();
dimensionLabel.setText("---");
GridBagConstraints gbc_dimensionLabel = new GridBagConstraints();
gbc_dimensionLabel.anchor = GridBagConstraints.WEST;
gbc_dimensionLabel.gridwidth = 3;
gbc_dimensionLabel.fill = GridBagConstraints.VERTICAL;
gbc_dimensionLabel.insets = new Insets(0, 0, 5, 0);
gbc_dimensionLabel.gridx = 1;
gbc_dimensionLabel.gridy = 2;
add(dimensionLabel, gbc_dimensionLabel);
JLabel lbl_channel = new JLabel("Channel");
lbl_channel.setToolTipText("Number of channel - data type");
GridBagConstraints gbc_lbl_channel = new GridBagConstraints();
gbc_lbl_channel.anchor = GridBagConstraints.WEST;
gbc_lbl_channel.fill = GridBagConstraints.VERTICAL;
gbc_lbl_channel.insets = new Insets(0, 0, 5, 5);
gbc_lbl_channel.gridx = 0;
gbc_lbl_channel.gridy = 3;
add(lbl_channel, gbc_lbl_channel);
channelLabel = new JLabel();
channelLabel.setText("---");
GridBagConstraints gbc_channelLabel = new GridBagConstraints();
gbc_channelLabel.anchor = GridBagConstraints.WEST;
gbc_channelLabel.gridwidth = 3;
gbc_channelLabel.fill = GridBagConstraints.VERTICAL;
gbc_channelLabel.insets = new Insets(0, 0, 5, 0);
gbc_channelLabel.gridx = 1;
gbc_channelLabel.gridy = 3;
add(channelLabel, gbc_channelLabel);
JLabel lbl_size = new JLabel("Size");
lbl_size.setToolTipText("Size");
GridBagConstraints gbc_lbl_size = new GridBagConstraints();
gbc_lbl_size.anchor = GridBagConstraints.WEST;
gbc_lbl_size.fill = GridBagConstraints.VERTICAL;
gbc_lbl_size.insets = new Insets(0, 0, 5, 5);
gbc_lbl_size.gridx = 0;
gbc_lbl_size.gridy = 4;
add(lbl_size, gbc_lbl_size);
sizeLabel = new JLabel();
sizeLabel.setText("---");
GridBagConstraints gbc_sizeLabel = new GridBagConstraints();
gbc_sizeLabel.anchor = GridBagConstraints.WEST;
gbc_sizeLabel.gridwidth = 3;
gbc_sizeLabel.fill = GridBagConstraints.VERTICAL;
gbc_sizeLabel.insets = new Insets(0, 0, 5, 0);
gbc_sizeLabel.gridx = 1;
gbc_sizeLabel.gridy = 4;
add(sizeLabel, gbc_sizeLabel);
JLabel lbl_psx = new JLabel("Pixel size");
lbl_psx.setToolTipText("Pixel size for X, Y, Z dimension");
GridBagConstraints gbc_lbl_psx = new GridBagConstraints();
gbc_lbl_psx.anchor = GridBagConstraints.WEST;
gbc_lbl_psx.fill = GridBagConstraints.VERTICAL;
gbc_lbl_psx.insets = new Insets(0, 0, 5, 5);
gbc_lbl_psx.gridx = 0;
gbc_lbl_psx.gridy = 5;
add(lbl_psx, gbc_lbl_psx);
resXLabel = new JLabel();
resXLabel.setText("---");
GridBagConstraints gbc_resXLabel = new GridBagConstraints();
gbc_resXLabel.anchor = GridBagConstraints.WEST;
gbc_resXLabel.fill = GridBagConstraints.VERTICAL;
gbc_resXLabel.insets = new Insets(0, 0, 5, 5);
gbc_resXLabel.gridx = 1;
gbc_resXLabel.gridy = 5;
add(resXLabel, gbc_resXLabel);
resYLabel = new JLabel();
resYLabel.setText("---");
GridBagConstraints gbc_resYLabel = new GridBagConstraints();
gbc_resYLabel.anchor = GridBagConstraints.WEST;
gbc_resYLabel.fill = GridBagConstraints.VERTICAL;
gbc_resYLabel.insets = new Insets(0, 0, 5, 5);
gbc_resYLabel.gridx = 2;
gbc_resYLabel.gridy = 5;
add(resYLabel, gbc_resYLabel);
resZLabel = new JLabel();
resZLabel.setText("---");
GridBagConstraints gbc_resZLabel = new GridBagConstraints();
gbc_resZLabel.anchor = GridBagConstraints.WEST;
gbc_resZLabel.fill = GridBagConstraints.VERTICAL;
gbc_resZLabel.insets = new Insets(0, 0, 5, 0);
gbc_resZLabel.gridx = 3;
gbc_resZLabel.gridy = 5;
add(resZLabel, gbc_resZLabel);
JLabel lbl_time = new JLabel("Time interval");
lbl_time.setToolTipText("Time Interval");
GridBagConstraints gbc_lbl_time = new GridBagConstraints();
gbc_lbl_time.anchor = GridBagConstraints.WEST;
gbc_lbl_time.fill = GridBagConstraints.VERTICAL;
gbc_lbl_time.insets = new Insets(0, 0, 5, 5);
gbc_lbl_time.gridx = 0;
gbc_lbl_time.gridy = 6;
add(lbl_time, gbc_lbl_time);
resTLabel = new JLabel();
resTLabel.setText("---");
GridBagConstraints gbc_resTLabel = new GridBagConstraints();
gbc_resTLabel.anchor = GridBagConstraints.WEST;
gbc_resTLabel.gridwidth = 3;
gbc_resTLabel.fill = GridBagConstraints.VERTICAL;
gbc_resTLabel.insets = new Insets(0, 0, 5, 0);
gbc_resTLabel.gridx = 1;
gbc_resTLabel.gridy = 6;
add(resTLabel, gbc_resTLabel);
editBtn = new IcyButton("Edit", new IcyIcon(ResourceUtil.ICON_DOCEDIT));
editBtn.setToolTipText("Edit sequence properties");
GridBagConstraints gbc_editBtn = new GridBagConstraints();
gbc_editBtn.gridwidth = 2;
gbc_editBtn.fill = GridBagConstraints.BOTH;
gbc_editBtn.insets = new Insets(0, 0, 0, 5);
gbc_editBtn.gridx = 0;
gbc_editBtn.gridy = 7;
add(editBtn, gbc_editBtn);
detailBtn = new IcyButton("Show metadata", new IcyIcon(ResourceUtil.ICON_PROPERTIES));
detailBtn.setText("Metadata");
detailBtn.setToolTipText("Show all associated metadata informations");
GridBagConstraints gbc_detailBtn = new GridBagConstraints();
gbc_detailBtn.gridwidth = 2;
gbc_detailBtn.fill = GridBagConstraints.BOTH;
gbc_detailBtn.gridx = 2;
gbc_detailBtn.gridy = 7;
add(detailBtn, gbc_detailBtn);
}
public void updateInfos()
{
ThreadUtil.runSingle(infosRefresher);
}
public void updateInfosInternal(Sequence sequence)
{
if (sequence != null)
{
final int sizeX = sequence.getSizeX();
final int sizeY = sequence.getSizeY();
final int sizeZ = sequence.getSizeZ();
final int sizeT = sequence.getSizeT();
final int sizeC = sequence.getSizeC();
final double pxSizeX = sequence.getPixelSizeX();
final double pxSizeY = sequence.getPixelSizeY();
final double pxSizeZ = sequence.getPixelSizeZ();
final String path = sequence.getFilename();
nameField.setText(sequence.getName());
// path
if (StringUtil.isEmpty(path))
{
pathLabel.setVisible(false);
pathField.setVisible(false);
}
else
{
pathLabel.setVisible(true);
pathField.setVisible(true);
pathField.setText(path);
}
dimensionLabel.setText(sizeX + " x " + sizeY + " x " + sizeZ + " x " + sizeT);
channelLabel.setText(sizeC + " - " + sequence.getDataType_().toLongString());
sizeLabel.setText(UnitUtil.getBytesString((double) sizeX * (double) sizeY * sizeZ * sizeT * sizeC
* sequence.getDataType_().getSize()));
resXLabel.setText(UnitUtil.getBestUnitInMeters(pxSizeX, 2, UnitPrefix.MICRO));
resYLabel.setText(UnitUtil.getBestUnitInMeters(pxSizeY, 2, UnitPrefix.MICRO));
resZLabel.setText(UnitUtil.getBestUnitInMeters(pxSizeZ, 2, UnitPrefix.MICRO));
resTLabel.setText(UnitUtil.displayTimeAsStringWithUnits(sequence.getTimeInterval() * 1000d, false));
nameField.setToolTipText(sequence.getName());
pathField.setToolTipText(path + " (double click to see file location)");
dimensionLabel.setToolTipText("Size X : " + sizeX + " Size Y : " + sizeY + " Size Z : " + sizeZ
+ " Size T : " + sizeT);
if (sizeC > 1)
channelLabel.setToolTipText(sizeC + " channels - " + sequence.getDataType_());
else
channelLabel.setToolTipText(sizeC + " channel - " + sequence.getDataType_());
sizeLabel.setToolTipText(sizeLabel.getText());
resXLabel.setToolTipText("X pixel resolution: " + resXLabel.getText());
resYLabel.setToolTipText("Y pixel resolution: " + resYLabel.getText());
resZLabel.setToolTipText("Z pixel resolution: " + resZLabel.getText());
resTLabel.setToolTipText("T time resolution: " + resTLabel.getText());
editBtn.setEnabled(true);
detailBtn.setEnabled(true);
}
else
{
pathLabel.setVisible(false);
pathField.setVisible(false);
nameField.setText("-");
dimensionLabel.setText("-");
channelLabel.setText("-");
sizeLabel.setText("-");
resXLabel.setText("-");
resYLabel.setText("-");
resZLabel.setText("-");
resTLabel.setText("-");
nameField.setToolTipText("");
dimensionLabel.setToolTipText("");
channelLabel.setToolTipText("");
sizeLabel.setToolTipText("");
resXLabel.setToolTipText("X pixel resolution");
resYLabel.setToolTipText("Y pixel resolution");
resZLabel.setToolTipText("Z pixel resolution");
resTLabel.setToolTipText("T time resolution");
editBtn.setEnabled(false);
detailBtn.setEnabled(false);
}
revalidate();
}
@Override
public void sequenceActivated(Sequence sequence)
{
updateInfos();
}
@Override
public void sequenceDeactivated(Sequence sequence)
{
// nothing to do here
}
@Override
public void activeSequenceChanged(SequenceEvent event)
{
switch (event.getSourceType())
{
case SEQUENCE_DATA:
case SEQUENCE_TYPE:
case SEQUENCE_META:
updateInfos();
break;
}
}
}