/* * 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.component.sequence; import icy.image.IcyBufferedImage; import icy.image.IcyBufferedImageUtil; import icy.sequence.SequenceModel; import icy.sequence.SequenceModel.SequenceModelListener; import icy.system.thread.ThreadUtil; import icy.util.GraphicsUtil; import icy.util.StringUtil; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.SwingConstants; import javax.swing.border.EmptyBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class SequencePreviewPanel extends JPanel implements ChangeListener, SequenceModelListener { /** * */ private static final long serialVersionUID = 4985194381532600393L; private class CustomPanel extends JPanel implements Runnable { /** * */ private static final long serialVersionUID = 6307431557815572470L; private BufferedImage cache; public CustomPanel() { super(); cache = null; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); final int w = getWidth(); final int h = getHeight(); final Graphics2D g2 = (Graphics2D) g.create(); g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2.setFont(g2.getFont().deriveFont(Font.BOLD, 22)); if (cache == null) GraphicsUtil.drawCenteredString(g2, "No image", w / 2, h / 2, false); else if ((w > 0) && (h > 0)) { final int sw = getSizeX(); final int sh = getSizeY(); final int iw = cache.getWidth(); final int ih = cache.getHeight(); final int fiw; final int fih; if (fitToView) { final double ratio1 = Math.max((double) iw / (double) sw, (double) ih / (double) sh); final double ratio2 = Math.max((double) sw / (double) w, (double) sh / (double) h); fiw = (int) (iw / (ratio1 * ratio2)); fih = (int) (ih / (ratio1 * ratio2)); } else { final double ratio = Math.max((double) sw / (double) w, (double) sh / (double) h); fiw = (int) (iw / ratio); fih = (int) (ih / ratio); } g2.drawImage(cache, (w - fiw) / 2, (h - fih) / 2, fiw, fih, null); } g2.dispose(); } public void imageChanged() { // request rebuild cache ThreadUtil.runSingle(this); } int getSizeX() { if (model != null) return model.getSizeX(); if (cache != null) return cache.getWidth(); return 0; } int getSizeY() { if (model != null) return model.getSizeY(); if (cache != null) return cache.getHeight(); return 0; } @Override public void run() { // rebuild cache and repaint final BufferedImage img = getImage(); if (img instanceof IcyBufferedImage) cache = IcyBufferedImageUtil.toBufferedImage((IcyBufferedImage) img, BufferedImage.TYPE_INT_ARGB); else cache = img; repaint(); } } protected boolean autoHideSliders; protected boolean fitToView; protected JSlider tSlider; protected JSlider zSlider; protected CustomPanel imagePanel; protected SequenceModel model; protected JLabel titleLabel; protected JPanel mainPanel; protected JPanel zPanel; protected JPanel tPanel; protected JLabel lblZ; protected JLabel lblT; protected JLabel lblZValue; protected JLabel lblTValue; /** * Create the panel. */ public SequencePreviewPanel(String title, boolean autoHideSliders) { super(); this.autoHideSliders = autoHideSliders; fitToView = true; model = null; initializeGui(); if (autoHideSliders) { zPanel.setVisible(false); tPanel.setVisible(false); } setMaxZ(0); setMaxT(0); zSlider.addChangeListener(this); tSlider.addChangeListener(this); setTitle(title); // setMinimumSize(new Dimension(320, 200)); setPreferredSize(new Dimension(280, 200)); validate(); } /** * Create the panel. */ public SequencePreviewPanel(boolean autoHideSliders) { this(null, autoHideSliders); } /** * Create the panel. */ public SequencePreviewPanel(String title) { this(title, true); } /** * Create the panel. */ public SequencePreviewPanel() { this(null, true); } private void initializeGui() { setLayout(new BorderLayout(0, 0)); titleLabel = new JLabel("Title"); titleLabel.setBorder(new EmptyBorder(2, 0, 4, 0)); titleLabel.setFont(new Font("Tahoma", Font.BOLD, 13)); titleLabel.setHorizontalAlignment(SwingConstants.CENTER); add(titleLabel, BorderLayout.NORTH); mainPanel = new JPanel(); add(mainPanel, BorderLayout.CENTER); GridBagLayout gbl_mainPanel = new GridBagLayout(); gbl_mainPanel.columnWidths = new int[] {0, 0, 0}; gbl_mainPanel.rowHeights = new int[] {0, 0, 0}; gbl_mainPanel.columnWeights = new double[] {0.0, 1.0, Double.MIN_VALUE}; gbl_mainPanel.rowWeights = new double[] {1.0, 0.0, Double.MIN_VALUE}; mainPanel.setLayout(gbl_mainPanel); imagePanel = new CustomPanel(); GridBagConstraints gbc_imagePanel = new GridBagConstraints(); gbc_imagePanel.insets = new Insets(0, 0, 5, 5); gbc_imagePanel.fill = GridBagConstraints.BOTH; gbc_imagePanel.gridx = 1; gbc_imagePanel.gridy = 0; mainPanel.add(imagePanel, gbc_imagePanel); zPanel = new JPanel(); GridBagConstraints gbc_zPanel = new GridBagConstraints(); gbc_zPanel.insets = new Insets(0, 0, 5, 5); gbc_zPanel.fill = GridBagConstraints.BOTH; gbc_zPanel.gridx = 0; gbc_zPanel.gridy = 0; mainPanel.add(zPanel, gbc_zPanel); GridBagLayout gbl_zPanel = new GridBagLayout(); gbl_zPanel.columnWidths = new int[] {0, 0}; gbl_zPanel.rowHeights = new int[] {0, 0, 0, 0}; gbl_zPanel.columnWeights = new double[] {0.0, Double.MIN_VALUE}; gbl_zPanel.rowWeights = new double[] {0.0, 1.0, 0.0, Double.MIN_VALUE}; zPanel.setLayout(gbl_zPanel); lblZ = new JLabel("Z"); GridBagConstraints gbc_lblZ = new GridBagConstraints(); gbc_lblZ.fill = GridBagConstraints.BOTH; gbc_lblZ.insets = new Insets(0, 0, 5, 0); gbc_lblZ.gridx = 0; gbc_lblZ.gridy = 0; zPanel.add(lblZ, gbc_lblZ); lblZ.setFont(new Font("Tahoma", Font.BOLD, 12)); lblZ.setHorizontalAlignment(SwingConstants.CENTER); zSlider = new JSlider(SwingConstants.VERTICAL); GridBagConstraints gbc_zSlider = new GridBagConstraints(); gbc_zSlider.fill = GridBagConstraints.BOTH; gbc_zSlider.insets = new Insets(0, 0, 5, 0); gbc_zSlider.gridx = 0; gbc_zSlider.gridy = 1; zPanel.add(zSlider, gbc_zSlider); // zSlider.setFocusable(false); lblZValue = new JLabel("0"); GridBagConstraints gbc_lblZValue = new GridBagConstraints(); gbc_lblZValue.fill = GridBagConstraints.BOTH; gbc_lblZValue.gridx = 0; gbc_lblZValue.gridy = 2; zPanel.add(lblZValue, gbc_lblZValue); lblZValue.setHorizontalAlignment(SwingConstants.CENTER); lblZValue.setFont(new Font("Tahoma", Font.BOLD, 11)); tPanel = new JPanel(); GridBagConstraints gbc_tPanel = new GridBagConstraints(); gbc_tPanel.fill = GridBagConstraints.BOTH; gbc_tPanel.gridx = 1; gbc_tPanel.gridy = 1; mainPanel.add(tPanel, gbc_tPanel); GridBagLayout gbl_tPanel = new GridBagLayout(); gbl_tPanel.columnWidths = new int[] {0, 0, 0, 0}; gbl_tPanel.rowHeights = new int[] {0, 0}; gbl_tPanel.columnWeights = new double[] {0.0, 1.0, 0.0, Double.MIN_VALUE}; gbl_tPanel.rowWeights = new double[] {1.0, Double.MIN_VALUE}; tPanel.setLayout(gbl_tPanel); lblTValue = new JLabel("0"); lblTValue.setMaximumSize(new Dimension(1000, 14)); lblTValue.setPreferredSize(new Dimension(20, 14)); lblTValue.setMinimumSize(new Dimension(20, 14)); GridBagConstraints gbc_lblTValue = new GridBagConstraints(); gbc_lblTValue.fill = GridBagConstraints.BOTH; gbc_lblTValue.insets = new Insets(0, 0, 0, 5); gbc_lblTValue.gridx = 0; gbc_lblTValue.gridy = 0; tPanel.add(lblTValue, gbc_lblTValue); lblTValue.setHorizontalAlignment(SwingConstants.CENTER); lblTValue.setFont(new Font("Tahoma", Font.BOLD, 11)); tSlider = new JSlider(SwingConstants.HORIZONTAL); GridBagConstraints gbc_tSlider = new GridBagConstraints(); gbc_tSlider.fill = GridBagConstraints.BOTH; gbc_tSlider.insets = new Insets(0, 0, 0, 5); gbc_tSlider.gridx = 1; gbc_tSlider.gridy = 0; tPanel.add(tSlider, gbc_tSlider); // tSlider.setFocusable(false); lblT = new JLabel("T"); lblT.setPreferredSize(new Dimension(20, 14)); lblT.setMaximumSize(new Dimension(1000, 14)); lblT.setMinimumSize(new Dimension(20, 14)); GridBagConstraints gbc_lblT = new GridBagConstraints(); gbc_lblT.fill = GridBagConstraints.BOTH; gbc_lblT.gridx = 2; gbc_lblT.gridy = 0; tPanel.add(lblT, gbc_lblT); lblT.setFont(new Font("Tahoma", Font.BOLD, 12)); lblT.setHorizontalAlignment(SwingConstants.CENTER); validate(); } /** * @return the main panel */ public JPanel getMainPanel() { return mainPanel; } /** * @return the zPanel */ public JPanel getZPanel() { return zPanel; } /** * @return the tPanel */ public JPanel getTPanel() { return tPanel; } public boolean getAutoHideSliders() { return autoHideSliders; } public void setAutoHideSliders(boolean value) { if (autoHideSliders != value) { autoHideSliders = value; zPanel.setVisible((zSlider.getMaximum() > 0) && value); tPanel.setVisible((tSlider.getMaximum() > 0) && value); } } public void setFitToView(boolean value) { if (fitToView != value) { fitToView = value; imagePanel.imageChanged(); } } public void setPositionZ(int z) { zSlider.setValue(z); imageChanged(); } public void setPositionT(int t) { tSlider.setValue(t); imageChanged(); } private void setMaxZ(int value) { zSlider.setMaximum(Math.max(0, value)); if (autoHideSliders) zPanel.setVisible(value > 0); } private void setMaxT(int value) { tSlider.setMaximum(Math.max(0, value)); if (autoHideSliders) tPanel.setVisible(value > 0); } /** * @return the image provider */ public SequenceModel getModel() { return model; } public void setModel(SequenceModel model) { if (this.model != model) { if (this.model != null) this.model.removeSequenceModelListener(this); this.model = model; if (model != null) model.addSequenceModelListener(this); dimensionChanged(); } } public void setTitle(String value) { if (!titleLabel.getText().equals(value)) { titleLabel.setText(value); titleLabel.setVisible(!StringUtil.isEmpty(value)); } } @Override public void dimensionChanged() { if (model != null) { setMaxZ(model.getSizeZ() - 1); setMaxT(model.getSizeT() - 1); } else { setMaxZ(0); setMaxT(0); } imagePanel.imageChanged(); } @Override public void imageChanged() { imagePanel.imageChanged(); } BufferedImage getImage() { if (model == null) return null; return model.getImage(tSlider.getValue(), zSlider.getValue()); } @Override public void stateChanged(ChangeEvent e) { imagePanel.imageChanged(); lblZValue.setText(Integer.toString(zSlider.getValue())); lblTValue.setText(Integer.toString(tSlider.getValue())); } }