source: josm/trunk/src/org/openstreetmap/josm/gui/ScrollViewport.java @ 5241

Revision 3083, 6.5 KB checked in by bastiK, 2 years ago (diff)

added svn:eol-style=native to source files

  • Property svn:eol-style set to native
Line 
1// License: GPL. Copyright 2007 by Christian Gallioz (aka khris78)
2
3package org.openstreetmap.josm.gui;
4
5import java.awt.BorderLayout;
6import java.awt.Dimension;
7import java.awt.Point;
8import java.awt.Rectangle;
9import java.awt.event.ActionEvent;
10import java.awt.event.ActionListener;
11import java.awt.event.ComponentAdapter;
12import java.awt.event.ComponentEvent;
13import java.awt.event.MouseAdapter;
14import java.awt.event.MouseEvent;
15import java.util.ArrayList;
16import java.util.List;
17
18import javax.swing.JButton;
19import javax.swing.JComponent;
20import javax.swing.JPanel;
21import javax.swing.JViewport;
22import javax.swing.Timer;
23
24import org.openstreetmap.josm.tools.ImageProvider;
25
26/** A viewport with UP and DOWN arrow buttons, so that the user can make the
27 * content scroll.
28 */
29public class ScrollViewport extends JPanel {
30
31    private static final int NO_SCROLL = 0;
32
33    public static final int UP_DIRECTION = 1;
34    public static final int DOWN_DIRECTION = 2;
35    public static final int LEFT_DIRECTION = 4;
36    public static final int RIGHT_DIRECTION = 8;
37    public static final int VERTICAL_DIRECTION = UP_DIRECTION | DOWN_DIRECTION;
38    public static final int HORIZONTAL_DIRECTION = LEFT_DIRECTION | RIGHT_DIRECTION;
39    public static final int ALL_DIRECTION = HORIZONTAL_DIRECTION | VERTICAL_DIRECTION;
40
41    private class ScrollViewPortMouseListener extends MouseAdapter {
42        private int direction;
43
44        public ScrollViewPortMouseListener(int direction) {
45            this.direction = direction;
46        }
47
48        @Override public void mouseExited(MouseEvent arg0) {
49            ScrollViewport.this.scrollDirection = NO_SCROLL;
50            timer.stop();
51        }
52
53        @Override public void mouseReleased(MouseEvent arg0) {
54            ScrollViewport.this.scrollDirection = NO_SCROLL;
55            timer.stop();
56        }
57
58        @Override public void mousePressed(MouseEvent arg0) {
59            ScrollViewport.this.scrollDirection = direction;
60            scroll();
61            timer.restart();
62        }
63
64    }
65
66    private JViewport vp = new JViewport();
67    private JComponent component = null;
68
69    private List<JButton> buttons = new ArrayList<JButton>();
70
71    private Timer timer = new Timer(100, new ActionListener() {
72        public void actionPerformed(ActionEvent arg0) {
73            ScrollViewport.this.scroll();
74        }
75    });
76
77    private int scrollDirection = NO_SCROLL;
78
79    public ScrollViewport(JComponent c, int direction) {
80        this(direction);
81        add(c);
82    }
83
84    public ScrollViewport(int direction) {
85        setLayout(new BorderLayout());
86
87        JButton button;
88
89        // UP
90        if ((direction & UP_DIRECTION) > 0) {
91            button = new JButton();
92            button.addMouseListener(new ScrollViewPortMouseListener(UP_DIRECTION));
93            button.setPreferredSize(new Dimension(10,10));
94            button.setIcon(ImageProvider.get("svpUp"));
95            add(button, BorderLayout.NORTH);
96            buttons.add(button);
97        }
98
99        // DOWN
100        if ((direction & DOWN_DIRECTION) > 0) {
101            button = new JButton();
102            button.addMouseListener(new ScrollViewPortMouseListener(DOWN_DIRECTION));
103            button.setPreferredSize(new Dimension(10,10));
104            button.setIcon(ImageProvider.get("svpDown"));
105            add(button, BorderLayout.SOUTH);
106            buttons.add(button);
107        }
108
109        // LEFT
110        if ((direction & LEFT_DIRECTION) > 0) {
111            button = new JButton();
112            button.addMouseListener(new ScrollViewPortMouseListener(LEFT_DIRECTION));
113            button.setPreferredSize(new Dimension(10,10));
114            button.setIcon(ImageProvider.get("svpLeft"));
115            add(button, BorderLayout.WEST);
116            buttons.add(button);
117        }
118
119        // RIGHT
120        if ((direction & RIGHT_DIRECTION) > 0) {
121            button = new JButton();
122            button.addMouseListener(new ScrollViewPortMouseListener(RIGHT_DIRECTION));
123            button.setPreferredSize(new Dimension(10,10));
124            button.setIcon(ImageProvider.get("svpRight"));
125            add(button, BorderLayout.EAST);
126            buttons.add(button);
127        }
128
129        add(vp, BorderLayout.CENTER);
130
131        this.addComponentListener(new ComponentAdapter() {
132            @Override public void  componentResized(ComponentEvent e) {
133                showOrHideButtons();
134            }
135        });
136
137        showOrHideButtons();
138
139        timer.setRepeats(true);
140        timer.setInitialDelay(400);
141    }
142
143    public synchronized void scroll() {
144        int direction = scrollDirection;
145
146        if (component == null || direction == NO_SCROLL)
147            return;
148
149        Rectangle viewRect = vp.getViewRect();
150
151        int deltaX = 0;
152        int deltaY = 0;
153
154        if (direction < LEFT_DIRECTION) {
155            deltaY = viewRect.height * 2 / 7;
156        } else {
157            deltaX = viewRect.width * 2 / 7;
158        }
159
160        switch (direction) {
161        case UP_DIRECTION :
162            deltaY *= -1;
163            break;
164        case LEFT_DIRECTION :
165            deltaX *= -1;
166            break;
167        }
168
169        scroll(deltaX, deltaY);
170    }
171    public synchronized void scroll(int deltaX, int deltaY) {
172        if (component == null)
173            return;
174        Dimension compSize = component.getSize();
175        Rectangle viewRect = vp.getViewRect();
176
177        int newX = viewRect.x + deltaX;
178        int newY = viewRect.y + deltaY;
179
180        if (newY < 0) {
181            newY = 0;
182        }
183        if (newY > compSize.height - viewRect.height) {
184            newY = compSize.height - viewRect.height;
185        }
186        if (newX < 0) {
187            newX = 0;
188        }
189        if (newX > compSize.width - viewRect.width) {
190            newX = compSize.width - viewRect.width;
191        }
192
193        vp.setViewPosition(new Point(newX, newY));
194    }
195
196    /**
197     * Update the visibility of the buttons
198     * Only show them if the Viewport is too small for the content.
199     */
200    public void showOrHideButtons() {
201        boolean needButtons = vp.getViewSize().height > vp.getViewRect().height ||
202        vp.getViewSize().width > vp.getViewRect().width;
203        for (JButton b : buttons) {
204            b.setVisible(needButtons);
205        }
206    }
207
208    public Rectangle getViewRect() {
209        return vp.getViewRect();
210    }
211
212    public Dimension getViewSize() {
213        return vp.getViewSize();
214    }
215
216    public Point getViewPosition() {
217        return vp.getViewPosition();
218    }
219
220    public void add(JComponent c) {
221        vp.removeAll();
222        this.component = c;
223        vp.add(c);
224    }
225}
Note: See TracBrowser for help on using the repository browser.