1/*
2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.lwawt;
27
28import javax.swing.*;
29import javax.swing.event.ChangeListener;
30import javax.swing.event.ChangeEvent;
31import java.awt.*;
32import java.awt.event.MouseWheelEvent;
33import java.awt.peer.ScrollPanePeer;
34import java.util.List;
35
36/**
37 * Lightweight implementation of {@link ScrollPanePeer}. Delegates most of the
38 * work to the {@link JScrollPane}.
39 */
40final class LWScrollPanePeer extends LWContainerPeer<ScrollPane, JScrollPane>
41        implements ScrollPanePeer, ChangeListener {
42
43    LWScrollPanePeer(final ScrollPane target,
44                     final PlatformComponent platformComponent) {
45        super(target, platformComponent);
46    }
47
48    @Override
49    JScrollPane createDelegate() {
50        final JScrollPane sp = new JScrollPane();
51        final JPanel panel = new JPanel();
52        panel.setOpaque(false);
53        panel.setVisible(false);
54        sp.getViewport().setView(panel);
55        sp.setBorder(BorderFactory.createEmptyBorder());
56        sp.getViewport().addChangeListener(this);
57        return sp;
58    }
59
60    @Override
61    public void handleEvent(AWTEvent e) {
62        if (e instanceof MouseWheelEvent) {
63            MouseWheelEvent wheelEvent = (MouseWheelEvent) e;
64            //java.awt.ScrollPane consumes the event
65            // in case isWheelScrollingEnabled() is true,
66            // forcibly send the consumed event to the delegate
67            if (getTarget().isWheelScrollingEnabled() && wheelEvent.isConsumed()) {
68                sendEventToDelegate(wheelEvent);
69            }
70        } else {
71            super.handleEvent(e);
72        }
73    }
74
75    @Override
76    public void stateChanged(final ChangeEvent e) {
77        SwingUtilities.invokeLater(new Runnable() {
78            @Override
79            public void run() {
80                final LWComponentPeer<?, ?> viewPeer = getViewPeer();
81                if (viewPeer != null) {
82                    final Rectangle r;
83                    synchronized (getDelegateLock()) {
84                        r = getDelegate().getViewport().getView().getBounds();
85                    }
86                    viewPeer.setBounds(r.x, r.y, r.width, r.height, SET_BOUNDS,
87                                       true, true);
88                }
89            }
90        });
91    }
92
93    @Override
94    void initializeImpl() {
95        super.initializeImpl();
96        final int policy = getTarget().getScrollbarDisplayPolicy();
97        synchronized (getDelegateLock()) {
98            getDelegate().getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
99            getDelegate().setVerticalScrollBarPolicy(convertVPolicy(policy));
100            getDelegate().setHorizontalScrollBarPolicy(convertHPolicy(policy));
101        }
102    }
103
104    LWComponentPeer<?, ?> getViewPeer() {
105        final List<LWComponentPeer<?, ?>> peerList = getChildren();
106        return peerList.isEmpty() ? null : peerList.get(0);
107    }
108
109    @Override
110    Rectangle getContentSize() {
111        Rectangle viewRect = getDelegate().getViewport().getViewRect();
112        return new Rectangle(viewRect.width, viewRect.height);
113    }
114
115    @Override
116    public void layout() {
117        super.layout();
118        synchronized (getDelegateLock()) {
119            final LWComponentPeer<?, ?> viewPeer = getViewPeer();
120            if (viewPeer != null) {
121                Component view = getDelegate().getViewport().getView();
122                view.setBounds(viewPeer.getBounds());
123                view.setPreferredSize(viewPeer.getPreferredSize());
124                view.setMinimumSize(viewPeer.getMinimumSize());
125                getDelegate().invalidate();
126                getDelegate().validate();
127                viewPeer.setBounds(view.getBounds());
128            }
129        }
130    }
131
132    @Override
133    public void setScrollPosition(int x, int y) {
134    }
135
136    @Override
137    public int getHScrollbarHeight() {
138        synchronized (getDelegateLock()) {
139            return getDelegate().getHorizontalScrollBar().getHeight();
140        }
141    }
142
143    @Override
144    public int getVScrollbarWidth() {
145        synchronized (getDelegateLock()) {
146            return getDelegate().getVerticalScrollBar().getWidth();
147        }
148    }
149
150    @Override
151    public void childResized(int w, int h) {
152        synchronized (getDelegateLock()) {
153            getDelegate().invalidate();
154            getDelegate().validate();
155        }
156    }
157
158    @Override
159    public void setUnitIncrement(Adjustable adj, int u) {
160    }
161
162    @Override
163    public void setValue(Adjustable adj, int v) {
164    }
165
166    private static int convertHPolicy(final int policy) {
167        switch (policy) {
168            case ScrollPane.SCROLLBARS_NEVER:
169                return ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER;
170            case ScrollPane.SCROLLBARS_ALWAYS:
171                return ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS;
172            default:
173                return ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
174        }
175    }
176
177    private static int convertVPolicy(final int policy) {
178        switch (policy) {
179            case ScrollPane.SCROLLBARS_NEVER:
180                return ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER;
181            case ScrollPane.SCROLLBARS_ALWAYS:
182                return ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS;
183            default:
184                return ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
185        }
186    }
187}
188