/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo 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. * * OpenFlexo 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 OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.components.widget; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ScrollPaneConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import org.openflexo.foundation.rm.FlexoProject; import org.openflexo.foundation.rm.FlexoProject.ImageFile; import org.openflexo.localization.FlexoLocalization; import org.openflexo.swing.TextFieldCustomPopup; import org.openflexo.swing.layout.WrapLayout; /** * Widget allowing to select a DocItem while browsing the DocResourceCenter * * @author sguerin * */ public class ImageFileSelector extends TextFieldCustomPopup<ImageFile> { private static final Color SELECTION_COLOR = new Color(184, 207, 229); public interface ImageImporter { public void importImage(ActionEvent e); } protected static final String EMPTY_STRING = ""; private FlexoProject project; private ImageFile revertValue; protected ImageImporter importer; protected boolean importedImageOnly; public ImageFileSelector(FlexoProject project, ImageImporter importer, ImageFile docItem, boolean importedImageOnly) { super(docItem); this.project = project; this.importer = importer; this.importedImageOnly = importedImageOnly; this.revertValue = docItem; } @Override public void delete() { super.delete(); importer = null; revertValue = null; project = null; } public FlexoProject getProject() { return project; } public void setProject(FlexoProject project) { this.project = project; } protected class ImageSelectorPanel extends ResizablePanel { private JPanel imagePanel; private JButton applyButton; private JButton cancelButton; private JButton resetButton; private JButton importButton; protected ImageSelectorPanel() { super(); setLayout(new BorderLayout()); imagePanel = new JPanel(new WrapLayout()); JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); applyButton = new JButton(FlexoLocalization.localizedForKey("ok")); applyButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { apply(); } }); cancelButton = new JButton(FlexoLocalization.localizedForKey("cancel")); cancelButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { cancel(); } }); resetButton = new JButton(FlexoLocalization.localizedForKey("reset")); resetButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { setEditedObject(null); apply(); } }); if (importer != null) { importButton = new JButton(FlexoLocalization.localizedForKey("import")); importButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { importer.importImage(e); updateImagePanel(); // Just to be extra sure, but the next lines should not be useful. if (!popupIsShown()) { openPopup(); } } }); } buttonPanel.add(applyButton); buttonPanel.add(cancelButton); buttonPanel.add(resetButton); if (importButton != null) { buttonPanel.add(importButton); } updateImagePanel(); final JScrollPane scroll = new JScrollPane(imagePanel); scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scroll.setPreferredSize(new Dimension(280, 340)); if (scroll.getVerticalScrollBar() != null) { scroll.getVerticalScrollBar().setUnitIncrement(10); scroll.getVerticalScrollBar().setBlockIncrement(30); } scroll.validate(); add(scroll, BorderLayout.CENTER); add(buttonPanel, BorderLayout.SOUTH); validate(); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { Component[] c = imagePanel.getComponents(); for (int i = 0; i < c.length; i++) { ImageView component = (ImageView) c[i]; if (component.file == getEditedObject()) { component.scrollRectToVisible(new Rectangle(component.getSize())); break; } } } }); } private void updateImagePanel() { imagePanel.removeAll(); for (ImageFile file : getProject().getAvailableImageFiles()) { if (importedImageOnly && !file.isImported()) { continue; } imagePanel.add(new ImageView(file)); } imagePanel.validate(); } @Override public Dimension getDefaultSize() { return new Dimension(340, 390); } private class ImageView extends JPanel implements MouseListener { private ImageIcon image; private int imageWidth; private int imageHeight; private double imageRatio; private ImageFile file; protected ImageView(ImageFile file) { this.file = file; image = new ImageIcon(file.getImageFile().getAbsolutePath()); imageWidth = image.getIconWidth(); imageHeight = image.getIconHeight(); imageRatio = imageWidth / imageHeight; setToolTipText(file.getBeautifiedImageName()); addMouseListener(this); setOpaque(true); setPreferredSize(new Dimension(80, 80)); } public ImageFile getFile() { return file; } private boolean isSelected = false; @Override public void paint(Graphics g) { super.paint(g); Rectangle r = getBounds(); int x, y, width, height; double ratio = r.width / r.height; if (r.width > imageWidth && r.height > imageHeight) { height = imageHeight; width = imageWidth; x = (r.width - width) / 2; y = (r.height - height) / 2; } else { if (imageRatio < ratio) { y = 0; height = r.height; width = imageWidth * r.height / imageHeight; x = (r.width - width) / 2; } else if (imageRatio > ratio) { x = 0; width = r.width; height = imageHeight * r.width / imageWidth; y = (r.height - height) / 2; } else { x = 1; y = 1; width = r.width - 1; height = r.height - 1; } } g.drawImage(image.getImage(), x, y, width, height, null); } @Override public Color getBackground() { if (isSelected || getEditedObject() == file) { Color c = UIManager.getDefaults().getColor("TextField.selectionBackground"); if (c == null) { c = SELECTION_COLOR; } return c; } else { return super.getBackground(); } } @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 1) { setEditedObject(file); imagePanel.repaint(); } else { setEditedObject(file); apply(); } } @Override public void mouseEntered(MouseEvent e) { isSelected = true; imagePanel.repaint(); } @Override public void mouseExited(MouseEvent e) { isSelected = false; imagePanel.repaint(); } @Override public void mousePressed(MouseEvent e) { } @Override public void mouseReleased(MouseEvent e) { } } } public ImageFile getRevertValue() { return revertValue; } @Override public void setRevertValue(ImageFile oldValue) { this.revertValue = oldValue; } @Override public void apply() { setRevertValue(getEditedObject()); closePopup(); super.apply(); } @Override public void cancel() { setEditedObject(revertValue); closePopup(); super.cancel(); } @Override public void closePopup() { super.closePopup(); deletePopup(); } @Override public String renderedString(ImageFile editedObject) { if (editedObject == null) { return EMPTY_STRING; } return editedObject.getImageName(); } @Override public void updateCustomPanel(ImageFile editedObject) { } @Override protected ResizablePanel createCustomPanel(ImageFile editedObject) { return new ImageSelectorPanel(); } }