/* * #%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.*; /** * A component showing an image as well as an arbitrary number of overlays. * * @author Kazó Csaba */ class LayeredImageView { private final ImageComponent theImage; private final JLayeredPane layeredPane; public LayeredImageView(ImageComponent theImage) { this.theImage = theImage; layeredPane = new ScrollableLayeredPane(); layeredPane.setLayout(new OverlayLayout()); layeredPane.add(theImage, Integer.valueOf(0)); layeredPane.setOpaque(true); } /** * Returns the component for this layered view. * * @return the Swing component for this view */ public JComponent getComponent() { return layeredPane; } /** * Adds an overlay as the specified layer. * * @param overlay the overlay to add * @param layer the layer to add the overlay to; higher layers are on top of lower layers; * the image resides in layer 0 */ public void addOverlay(Overlay overlay, int layer) { if (overlay == null) throw new NullPointerException(); OverlayComponent c = new OverlayComponent(overlay, theImage); overlay.addOverlayComponent(c); layeredPane.add(c, Integer.valueOf(layer)); layeredPane.revalidate(); layeredPane.repaint(); } /** * Removes an overlay from the image viewer. * * @param overlay the overlay to remove * @throws IllegalArgumentException if the overlay is not in the image viewer */ public void removeOverlay(Overlay overlay) { if (overlay == null) throw new NullPointerException(); for (Component c : layeredPane.getComponents()) { if (c instanceof OverlayComponent && ((OverlayComponent) c).overlay == overlay) { overlay.removeOverlayComponent((OverlayComponent) c); layeredPane.remove(c); layeredPane.revalidate(); layeredPane.repaint(); return; } } throw new IllegalArgumentException("Overlay not part of this viewer"); } /** * This layout manager ensures that the ImageComponent and all the overlays fill the container exactly. */ private class OverlayLayout implements LayoutManager { @Override public void addLayoutComponent(String name, Component comp) { } @Override public void removeLayoutComponent(Component comp) { } @Override public Dimension preferredLayoutSize(Container parent) { return theImage.getPreferredSize(); } @Override public Dimension minimumLayoutSize(Container parent) { return theImage.getMinimumSize(); } @Override public void layoutContainer(Container parent) { for (int i = 0; i < parent.getComponentCount(); i++) { parent.getComponent(i).setBounds(0, 0, parent.getWidth(), parent.getHeight()); } } } private class ScrollableLayeredPane extends JLayeredPane implements Scrollable { @Override public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { return 10; } @Override public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { return 50; } /* * The getScrollableTracksViewportXxx functions below are used by * javax.swing.ScrollPaneLayout to determine whether the scroll bars should * be visible; so these need to be implemented. */ @Override public boolean getScrollableTracksViewportWidth() { return theImage.getResizeStrategy() == ResizeStrategy.SHRINK_TO_FIT || theImage.getResizeStrategy() == ResizeStrategy.RESIZE_TO_FIT; } @Override public boolean getScrollableTracksViewportHeight() { return theImage.getResizeStrategy() == ResizeStrategy.SHRINK_TO_FIT || theImage.getResizeStrategy() == ResizeStrategy.RESIZE_TO_FIT; } /* * The getPreferredScrollableViewportSize does not seem to be used. */ @Override public Dimension getPreferredScrollableViewportSize() { if (theImage.getResizeStrategy() == ResizeStrategy.NO_RESIZE) return getPreferredSize(); else return javax.swing.SwingUtilities.getAncestorOfClass(JViewport.class, this).getSize(); } } }