001    /**
002     * planningtool - A Planning Tool with Critiquing Support.
003     * 
004     * Copyright (C) 2006 olale
005    
006     * This program is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU General Public License
008     * as published by the Free Software Foundation; either version 2
009     * of the License, or (at your option) any later version.
010    
011     * This program is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014     * GNU General Public License for more details.
015    
016     * You should have received a copy of the GNU General Public License
017     * along with this program; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019    
020     * Contact information: 
021     * E-mail: olale@ida.liu.se
022     *         olale@lysator.liu.se
023     */
024    package se.liu.ida.critiquer.gui;
025    
026    import java.awt.Color;
027    import java.awt.Dimension;
028    import java.awt.Graphics;
029    import java.awt.Point;
030    import java.awt.Rectangle;
031    import java.awt.event.MouseEvent;
032    import java.awt.event.MouseListener;
033    import java.awt.event.MouseMotionListener;
034    
035    import javax.swing.ImageIcon;
036    import javax.swing.JLabel;
037    import javax.swing.JOptionPane;
038    import javax.swing.Scrollable;
039    import javax.swing.SwingConstants;
040    
041    import se.liu.ida.critiquer.activities.parameters.Location;
042    import se.liu.ida.critiquer.activities.parameters.LocationParameter;
043    
044    /**
045     * This class implements the graphical representation of a map, along with
046     * functionality for recognizing mouse gestures that define the location
047     * parameter values
048     * 
049     * @author olale
050     * 
051     */
052    public class ScrollableMap extends JLabel implements Scrollable, MouseMotionListener, MouseListener {
053    
054            /**
055         * 
056         */
057            private static final long serialVersionUID  = 1L;
058    
059            private int                        maxUnitIncrement  = 1;
060    
061            private boolean            missingPicture       = false;
062    
063            private int                        scale;
064    
065            private Point                    t0;
066    
067            private Point                    t1;
068    
069            private LocationParameter locationParam  = null;
070    
071            private boolean            drawTempRectangle = false;
072    
073            /**
074         * 
075         * Paint both the map and the location
076         * 
077         * @see javax.swing.JComponent#paint(java.awt.Graphics)
078         */
079            @Override
080            public void paint(Graphics g) {
081                    super.paint(g);
082    
083                    if (locationParam != null && locationParam.hasValue()) {
084                            
085                            Color oldColor = g.getColor();
086                            g.setColor(Color.BLACK);
087    
088                            Rectangle rect = locationParam.getValue().getArea();
089                            g.drawRect(rect.x, rect.y, rect.width, rect.height);
090    
091                            g.setColor(oldColor);
092    
093                    }
094                    if (drawTempRectangle) {
095                            Color oldColor = g.getColor();
096                            g.setColor(Color.BLACK);
097                            g.drawRect(t0.x, t0.y, t1.x - t0.x, t1.y - t0.y);
098                            g.setColor(oldColor);
099                    }
100    
101            }
102    
103            public ScrollableMap(ImageIcon i, int scale) {
104                    super(i);
105                    if (i == null) {
106                            missingPicture = true;
107                            setText("No picture found.");
108                            setHorizontalAlignment(CENTER);
109                            setOpaque(true);
110                            setBackground(Color.white);
111                    }
112                    maxUnitIncrement = 10;
113                    this.scale = scale;
114                    t0 = new Point();
115                    t1 = new Point();
116                    // Let the user scroll by dragging to outside the window.
117                    setAutoscrolls(true); // enable synthetic drag events
118                    addMouseMotionListener(this); // handle mouse drags
119                    addMouseListener(this);
120            }
121    
122            // Methods required by the MouseMotionListener interface:
123            public void mouseMoved(MouseEvent e) {
124                    Point tmp = new Point();
125    
126                    if (!(t0.equals(tmp) && t1.equals(tmp)) && locationParam != null
127                            && (JOptionPane.showConfirmDialog(this,
128                                            "Set " + locationParam.getName() + " to rectangle?",
129                                            "Determine location",
130                                            JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)) {
131                            drawTempRectangle = false;
132                            /**
133                 * Create a rectangular area between t0 and t1 and assign it as a
134                 * value to the currently selected LocationParameter
135                 */
136                            Location l = locationParam.getValue();
137                            l.setArea(new Rectangle(t0, new Dimension(t1.x - t0.x, t1.y - t0.y)));
138    
139                            t0 = new Point();
140                            t1 = new Point();
141    
142                    }
143            }
144    
145            public void mouseDragged(MouseEvent e) {
146                    // The user is dragging us, so scroll!
147    
148                    if (t0.equals(t1) && t0.equals(new Point())) {
149                            t0 = t1 = e.getPoint();
150                    } else {
151                            t1 = e.getPoint();
152                            drawTempRectangle = true;
153                            repaint();
154                    }
155    
156                    Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
157                    scrollRectToVisible(r);
158            }
159    
160            public Dimension getPreferredSize() {
161                    if (missingPicture) {
162                            return new Dimension(320, 480);
163                    } else {
164                            return super.getPreferredSize();
165                    }
166            }
167    
168            public Dimension getPreferredScrollableViewportSize() {
169                    return getPreferredSize();
170            }
171    
172            public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
173                    // Get the current position.
174                    int currentPosition = 0;
175                    if (orientation == SwingConstants.HORIZONTAL) {
176                            currentPosition = visibleRect.x;
177                    } else {
178                            currentPosition = visibleRect.y;
179                    }
180    
181                    // Return the number of pixels between currentPosition
182                    // and the nearest tick mark in the indicated direction.
183                    if (direction < 0) {
184                            int newPosition = currentPosition - (currentPosition / maxUnitIncrement) * maxUnitIncrement;
185                            return (newPosition == 0) ? maxUnitIncrement : newPosition;
186                    } else {
187                            return ((currentPosition / maxUnitIncrement) + 1) * maxUnitIncrement - currentPosition;
188                    }
189            }
190    
191            public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
192                    if (orientation == SwingConstants.HORIZONTAL) {
193                            return visibleRect.width - maxUnitIncrement;
194                    } else {
195                            return visibleRect.height - maxUnitIncrement;
196                    }
197            }
198    
199            public boolean getScrollableTracksViewportWidth() {
200                    return false;
201            }
202    
203            public boolean getScrollableTracksViewportHeight() {
204                    return false;
205            }
206    
207            public void setMaxUnitIncrement(int pixels) {
208                    maxUnitIncrement = pixels;
209            }
210    
211            public void mouseClicked(MouseEvent e) {
212    
213            }
214    
215            public void mousePressed(MouseEvent e) {
216                    // TODO Auto-generated method stub
217    
218            }
219    
220            public void mouseReleased(MouseEvent e) {
221                    // TODO Auto-generated method stub
222    
223            }
224    
225            public void mouseEntered(MouseEvent e) {
226                    // TODO Auto-generated method stub
227    
228            }
229    
230            public void mouseExited(MouseEvent e) {
231                    // TODO Auto-generated method stub
232    
233            }
234    
235            /**
236         * @return Returns the param.
237         */
238            public LocationParameter getLocationParam() {
239                    return locationParam;
240            }
241    
242            /**
243         * @param param
244         *            The param to set.
245         */
246            public void setLocationParam(LocationParameter param) {
247                    this.locationParam = param;
248            }
249    }