001: /*
002: * @(#)GScrollPanePeer.java 1.20 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.awt.gtk;
029:
030: import java.awt.*;
031: import java.awt.event.AdjustmentEvent;
032: import sun.awt.peer.*;
033:
034: /**
035: *
036: *
037: * @author Nicholas Allen
038: */
039:
040: class GScrollPanePeer extends GContainerPeer implements ScrollPanePeer {
041: private static native void initIDs();
042:
043: private static int hScrollbarHeight = calculateHScrollbarHeight();
044: private static int vScrollbarWidth = calculateVScrollbarWidth();
045:
046: private static native int calculateHScrollbarHeight();
047:
048: private static native int calculateVScrollbarWidth();
049:
050: private native void enableScrollbarsNative(boolean hBarOn,
051: boolean vBarOn);
052:
053: private boolean ignoreSetValue;
054: private int scrollbarDisplayPolicy;
055: // added for bug #'s 4714727, 4687092, 4689327, 4699570
056: private boolean ignoreDispatchH = false, ignoreDispatchV = false;
057: static {
058: initIDs();
059: }
060:
061: /** Creates a new GScrollPanePeer. */
062:
063: GScrollPanePeer(GToolkit toolkit, ScrollPane target) {
064: super (toolkit, target);
065: connectAdjuster(target.getHAdjustable(), Adjustable.HORIZONTAL);
066: connectAdjuster(target.getVAdjustable(), Adjustable.VERTICAL);
067: scrollbarDisplayPolicy = target.getScrollbarDisplayPolicy();
068: }
069:
070: protected native void create();
071:
072: native void add(GComponentPeer peer);
073:
074: void remove(GComponentPeer peer) {
075: }
076:
077: /** Overidden to calculate insets. This includes any optional scrollbars so
078: we need to dynamically work this out. */
079:
080: public Insets getInsets() {
081: // adjust predicted view size to account for scrollbars
082:
083: Insets inset = new Insets(0, 0, 0, 0);
084: if (scrollbarVisible(Adjustable.VERTICAL))
085: inset.right = vScrollbarWidth;
086: if (scrollbarVisible(Adjustable.HORIZONTAL))
087: inset.bottom = hScrollbarHeight;
088: return inset;
089: }
090:
091: public int getHScrollbarHeight() {
092: return hScrollbarHeight;
093: }
094:
095: public int getVScrollbarWidth() {
096: return vScrollbarWidth;
097: }
098:
099: public void childResized(int w, int h) {
100: boolean hBarOn = false;
101: boolean vBarOn = false;
102: int sw, sh;
103: int hAdj = 0;
104: int wAdj = 0;
105:
106: sw = target.getWidth();
107: sh = target.getHeight();
108:
109: /* GTK peer doesn't do scrollbars right */
110: /* so we enable and disable the scrollbars explictly */
111: if (scrollbarDisplayPolicy == ScrollPane.SCROLLBARS_AS_NEEDED) {
112: if (w > sw) {
113: hBarOn = true;
114: hAdj = hScrollbarHeight;
115: }
116: if (h > sh - hAdj) {
117: vBarOn = true;
118: wAdj = vScrollbarWidth;
119: /* revisit need for horiz. scrollbar */
120: if ((!hBarOn) && (w > sw - wAdj)) {
121: hBarOn = true;
122: }
123:
124: }
125: enableScrollbarsNative(hBarOn, vBarOn);
126: }
127: }
128:
129: public void setUnitIncrement(Adjustable adj, int u) {
130: setUnitIncrementNative(adj.getOrientation(), u);
131: }
132:
133: private native void setUnitIncrementNative(int orientation,
134: int increment);
135:
136: public void setValue(Adjustable adj, int v) {
137: if (ignoreSetValue)
138: return;
139: int orientation = adj.getOrientation();
140: int max = adj.getMaximum();
141: int pageSize = adj.getVisibleAmount();
142: // if-block added for bug #'s 4714727, 4687092, 4689327, 4699570
143: /*
144: For some reason, when the scroll position is set beyond the
145: maximum value, gtk generates a value-changed signal
146: that sends back a value that's one pixel less than the
147: maximum value. This is one reason that the comparison
148: between get and set sometimes fail. This modification
149: attempts to correct the bug by anticipating and inhibiting
150: the value-changed signal from modifying the position value.
151: If gtk does not consistently exhibit this behavior, there
152: will be a problem with missed scroll position value updates.
153: */
154: if (v >= (max - pageSize)) {
155: if (orientation == Adjustable.HORIZONTAL)
156: ignoreDispatchH = true;
157: else
158: ignoreDispatchV = true;
159: }
160: setAdjusterNative(orientation, v, max, pageSize);
161: }
162:
163: class GScrollPaneAdjustableEvent extends AWTEvent implements
164: ActiveEvent {
165: GScrollPanePeer peer;
166: Adjustable adjuster;
167: int value;
168:
169: GScrollPaneAdjustableEvent(GScrollPanePeer src, Adjustable adj,
170: int val) {
171: super (src, 0);
172: peer = src;
173: adjuster = adj;
174: value = val;
175: }
176:
177: public void dispatch() {
178: if (adjuster.getOrientation() == Adjustable.HORIZONTAL) {
179: if (ignoreDispatchH) {
180: ignoreDispatchH = false;
181: return;
182: }
183: } else {
184: if (ignoreDispatchV) {
185: ignoreDispatchV = false;
186: return;
187: }
188: }
189: peer.ignoreSetValue = true;
190: adjuster.setValue(value);
191: peer.ignoreSetValue = false;
192: }
193: }
194:
195: private void postAdjustableEvent(Adjustable adjuster, int value) {
196: GToolkit.postEvent(new GScrollPaneAdjustableEvent(this ,
197: adjuster, value));
198: }
199:
200: public Dimension getPreferredSize() {
201: return target.getSize();
202: }
203:
204: private native void setAdjusterNative(int orientation, int value,
205: int max, int pageSize);
206:
207: private native void connectAdjuster(Adjustable adj, int orientation);
208:
209: private native boolean scrollbarVisible(int orientation);
210: }
|