source: extensions/jiwigo/trunk/src/main/java/fr/mael/jiwigo/ui/browser/BrowserImagePanel.java @ 6958

Last change on this file since 6958 was 6958, checked in by mlg, 14 years ago

New features

  • When clicking on a category, the category is opened in a tab. When clicking on the same category again, no tab is opened but the previously opened tab is shown. The user can close the tabs (close current tab, close others, close all).
  • Ability to clip the images. There are still some bugs (unable to clip the images when zooming, and the rectangle stays when changing the image).
File size: 10.1 KB
Line 
1package fr.mael.jiwigo.ui.browser;
2
3import java.awt.Dimension;
4import java.awt.Graphics;
5import java.awt.Graphics2D;
6import java.awt.RenderingHints;
7import java.awt.event.MouseEvent;
8import java.awt.event.MouseListener;
9import java.awt.event.MouseMotionListener;
10import java.awt.event.MouseWheelEvent;
11import java.awt.event.MouseWheelListener;
12import java.awt.geom.AffineTransform;
13import java.awt.image.BufferedImage;
14import java.awt.print.PageFormat;
15import java.awt.print.Printable;
16import java.awt.print.PrinterException;
17import java.util.Hashtable;
18
19import javax.swing.JLabel;
20import javax.swing.JOptionPane;
21import javax.swing.JPanel;
22import javax.swing.JSlider;
23import javax.swing.event.ChangeEvent;
24import javax.swing.event.ChangeListener;
25
26import fr.mael.jiwigo.transverse.util.ImagesUtil;
27import fr.mael.jiwigo.transverse.util.Messages;
28
29/**
30   Copyright (c) 2010, Mael
31   All rights reserved.
32
33   Redistribution and use in source and binary forms, with or without
34   modification, are permitted provided that the following conditions are met:
35    * Redistributions of source code must retain the above copyright
36      notice, this list of conditions and the following disclaimer.
37    * Redistributions in binary form must reproduce the above copyright
38      notice, this list of conditions and the following disclaimer in the
39      documentation and/or other materials provided with the distribution.
40    * Neither the name of jiwigo nor the
41      names of its contributors may be used to endorse or promote products
42      derived from this software without specific prior written permission.
43
44   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
45   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47   DISCLAIMED. IN NO EVENT SHALL Mael BE LIABLE FOR ANY
48   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
53   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54   
55 * Panel qui affiche une image
56 * @author mael
57 *
58 */
59public class BrowserImagePanel extends JPanel implements MouseWheelListener, Printable, MouseMotionListener,
60        MouseListener {
61    private BufferedImage image;
62    private double scale = 1.0;
63    boolean flipH = false;
64    boolean flipV = false;
65    private int valueSlider = 16;
66    private boolean clicked = false;
67    private int xTopPosition;
68    private int yTopPosition;
69    private int xDragPosition;
70    private int yDragPosition;
71    private boolean drawSelection = false;
72
73    /**
74     * Constructeur
75     * @param image
76     */
77    public BrowserImagePanel(BufferedImage image) {
78        this.image = image;
79        this.addMouseWheelListener(this);
80        this.addMouseMotionListener(this);
81        this.addMouseListener(this);
82    }
83
84    /* (non-Javadoc)
85     * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
86     */
87    protected void paintComponent(Graphics g) {
88        super.paintComponent(g);
89        Graphics2D g2 = (Graphics2D) g;
90        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
91        double x = (getWidth() - scale * image.getWidth()) / 2;
92        double y = (getHeight() - scale * image.getHeight()) / 2;
93        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
94        if (flipV && !flipH) {
95            at.scale(scale, -scale);
96            at.translate(0, -getHeight() / 2);
97        } else if (flipH && !flipV) {
98            at.scale(-scale, scale);
99            at.translate(-getWidth() / 2, 0);
100        } else if (flipH && flipV) {
101            at.scale(-scale, -scale);
102            at.translate(-getWidth() / 2, -getHeight() / 2);
103        } else {
104            at.scale(scale, scale);
105        }
106        g2.drawRenderedImage(image, at);
107        if (drawSelection) {
108            g2.drawRect(xTopPosition, yTopPosition, xDragPosition - xTopPosition, yDragPosition - yTopPosition);
109        }
110
111    }
112
113    /* (non-Javadoc)
114     * @see javax.swing.JComponent#getPreferredSize()
115     */
116    public Dimension getPreferredSize() {
117        int w = (int) (scale * image.getWidth());
118        int h = (int) (scale * image.getHeight());
119        return new Dimension(w, h);
120    }
121
122    public void rogner() {
123        if (scale == 1.0) {
124            //récupération des dimensions de l'image
125            Double width = getSize().getWidth();
126            Double height = getSize().getHeight();
127            //recuperation du coin haut gauche de l'image
128            Double xZeroImage = ((width - image.getWidth()) / 2);
129            Double yZeroImage = ((height - image.getHeight()) / 2);
130            //les positions du premier clic
131            //sur l'image. Les positions récupérées précédemment étaient
132            //les positions sur le panel, il faut donc calculer les positions sur l'image
133            int positionX, positionY;
134            //largeur et longueur du rognage sur l'image
135            int largeur, longueur;
136            //si jamais la sélection commence avant le début de l'image
137            //en x, on prend comme position 0, sinon, on calcule la position
138            //du clic selon le calcul position sur l'image = position sur le panel - position du x de l'image
139            if (xTopPosition - xZeroImage.intValue() < 0) {
140                positionX = 0;
141            } else {
142                positionX = xTopPosition - xZeroImage.intValue();
143            }
144            //si jamais la sélection commence avant le début de l'image
145            //en y, on prend comme position 0, sinon, on calcule la position
146            //du clic selon le calcul position sur l'image = position sur le panel - position du y de l'image
147            if (yTopPosition - yZeroImage.intValue() < 0) {
148                positionY = 0;
149            } else {
150                positionY = yTopPosition - yZeroImage.intValue();
151            }
152            //on calcule la largeur
153            largeur = xDragPosition - xTopPosition;
154            //si ça dépasse de l'image
155            if ((positionX + largeur) > image.getWidth()) {
156                //on recalcule la largeur
157                largeur = image.getWidth() - positionX;
158            }
159            //on calcule la longueur
160            longueur = yDragPosition - yTopPosition;
161            //si ça dépasse en hauteur
162            if ((positionY + longueur) > image.getHeight()) {
163                //on recalcule la hauteur
164                longueur = image.getHeight() - positionY;
165            }
166            //recuperation de l'image coupée
167            image = image.getSubimage(positionX, positionY, largeur, longueur);
168            repaint();
169            revalidate();
170            drawSelection = false;
171        } else {
172            JOptionPane.showMessageDialog(this, Messages.getMessage("clippingError"), Messages.getMessage("info"),
173                    JOptionPane.INFORMATION_MESSAGE);
174        }
175    }
176
177    /**
178     * Récupération du slider
179     * @return le slider
180     */
181    public JSlider getSlider() {
182        int min = 1, max = 36, inc = 10;
183        final JSlider slider = new JSlider(min, max, 16);
184        slider.setMajorTickSpacing(5);
185        slider.setMinorTickSpacing(1);
186        slider.setPaintTicks(true);
187        slider.setSnapToTicks(true);
188        slider.setLabelTable(getLabelTable(min, max, inc));
189        slider.setPaintLabels(true);
190        slider.addChangeListener(new ChangeListener() {
191            public void stateChanged(ChangeEvent e) {
192                int value = slider.getValue();
193                valueSlider = value;
194                scale = (value + 4) / 20.0;
195                revalidate();
196                repaint();
197            };
198        });
199        return slider;
200    }
201
202    public void zoomIn() {
203
204        scale = (++valueSlider + 4) / 20.0;
205        revalidate();
206        repaint();
207    }
208
209    public void zoomOut() {
210        if (scale > 0) {
211            scale = (--valueSlider + 4) / 20.0;
212            revalidate();
213            repaint();
214        }
215    }
216
217    public void zoomNormal() {
218
219        scale = 1.0;
220        revalidate();
221        repaint();
222    }
223
224    /**
225     * Label du slider
226     * @param min
227     * @param max
228     * @param inc
229     * @return
230     */
231    private Hashtable getLabelTable(int min, int max, int inc) {
232        Hashtable<Integer, JLabel> table = new Hashtable<Integer, JLabel>();
233        for (int j = min; j <= max; j += inc) {
234            String s = String.format("%.2f", (j + 4) / 20.0);
235            table.put(Integer.valueOf(j), new JLabel(s));
236        }
237        return table;
238    }
239
240    /**
241     *  Rotation vers la droite
242     */
243    public void rotationDroite() {
244        setImage(ImagesUtil.rotate(image, Math.PI / 2));
245    }
246
247    /**
248     * Rotation vers la gauche
249     */
250    public void rotationGauche() {
251        setImage(ImagesUtil.rotate(image, -Math.PI / 2));
252    }
253
254    /**
255     * @return the image
256     */
257    public BufferedImage getImage() {
258        return image;
259    }
260
261    /**
262     * @param image the image to set
263     */
264    public void setImage(BufferedImage image) {
265        this.image = image;
266        revalidate();
267        repaint();
268    }
269
270    @Override
271    public void mouseWheelMoved(MouseWheelEvent arg0) {
272        int notches = arg0.getWheelRotation();
273        String message;
274        String newline = "\n";
275        if (notches < 0) {
276            zoomIn();
277
278        } else {
279            zoomOut();
280        }
281
282    }
283
284    @Override
285    public int print(Graphics arg0, PageFormat arg1, int arg2) throws PrinterException {
286        if (arg2 != 0)
287            return NO_SUCH_PAGE;
288        Graphics2D g2 = (Graphics2D) arg0;
289        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
290        double x = (getWidth() - scale * image.getWidth()) / 2;
291        double y = (getHeight() - scale * image.getHeight()) / 2;
292        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
293        if (flipV && !flipH) {
294            at.scale(scale, -scale);
295            at.translate(0, -getHeight() / 2);
296        } else if (flipH && !flipV) {
297            at.scale(-scale, scale);
298            at.translate(-getWidth() / 2, 0);
299        } else if (flipH && flipV) {
300            at.scale(-scale, -scale);
301            at.translate(-getWidth() / 2, -getHeight() / 2);
302        } else {
303            at.scale(scale, scale);
304        }
305
306        g2.drawRenderedImage(image, at);
307        return PAGE_EXISTS;
308    }
309
310    @Override
311    public void mouseDragged(MouseEvent arg0) {
312        if (clicked) {
313            xDragPosition = arg0.getX();
314            yDragPosition = arg0.getY();
315            repaint();
316            revalidate();
317        }
318    }
319
320    @Override
321    public void mouseMoved(MouseEvent arg0) {
322    }
323
324    public void mouseClicked(MouseEvent arg0) {
325    }
326
327    public void mouseEntered(MouseEvent arg0) {
328    }
329
330    public void mouseExited(MouseEvent arg0) {
331    }
332
333    public void mousePressed(MouseEvent arg0) {
334        clicked = true;
335        xTopPosition = arg0.getX();
336        yTopPosition = arg0.getY();
337        drawSelection = true;
338    }
339
340    public void mouseReleased(MouseEvent arg0) {
341        clicked = false;
342    }
343
344}
Note: See TracBrowser for help on using the repository browser.