xref: /titanic_44/usr/src/cmd/krb5/kadmin/gui/dchanger/DCPanel.java (revision 2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1f)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * ident	"%Z%%M%	%I%	%E% SMI"
24  *
25  * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
26  * All rights reserved.
27  */
28 
29     import java.awt.*;
30     import java.awt.event.*;
31 
32     /**
33      * Creates a panel with two buttons (+ and - side by side on it). The
34      * panel registers a DCListener with it that gets notified whenever
35      * these butons are clicked. <bold>The buttons may also be kept continously
36      * pressed for faster increments/decrements.</bold>
37      * <para>
38      * On a single click of the button, the listener is notified to
39      * increment/decrement itself by a small amount. When the button is kept
40      * pressed the following notifications are sent out for larger
41      * increments/decrements. (It is up to the listener to decide the
42      * increment/decrement corresponding to large/small.) Moreover, these
43      * notifications will be sent out much faster if the button is kept
44      * pressed.
45      */
46 
47     // The panel waits for a period of BIG_SLEEP_TIME before the faster
48     // increments are sent out. They, in turn, are sent out after
49     // intervals of SMALL_SLEEP_TIME. Therfore, an instance of this class
50     // is associated with 2 timers - a longer one that starts off and then
51     // schedules the shorter one. The shorter one keeps scheduling itself
52     // every time it wakes up.
53 
54     public class DCPanel extends Panel {
55 
56     private Button plusButton;
57     private Button minusButton;
58 
59     private DCListener listener = null;
60 
61     private Timer bigTimer;
62     private Timer smallTimer;
63 
64     private static int BIG_SLEEP_TIME   = 1000;
65     private static int SMALL_SLEEP_TIME = 100;
66 
67     private boolean incrementFlag;
68 
69     public DCPanel() {
70 
71     setLayout(new GridLayout(1, 2));
72 
73     bigTimer     = new BigTimer();
74     smallTimer   = new SmallTimer();
75 
76     bigTimer.start();
77     smallTimer.start();
78 
79     plusButton = new DCButton("+");
80     minusButton = new DCButton("-");
81 
82     add(plusButton);
83     add(minusButton);
84 
85     }
86 
87     /**
88      * Ensures that this component is not brought into focus by
89      * tabbing. This prevents the tab focus from moving in here instead
90      * of going to a text field.
91      * @return false always.
92      */
93     public boolean isFocusTraversable() {
94     return false;
95     }
96 
97     /**
98      * Sets the listener for this tab.
99      * @param listener the DCListener that needs to be notified when the
100      * buttons on this panel are pressed.
101      * @return the old listener
102      */
103     public DCListener setListener(DCListener listener) {
104     DCListener oldListener = this.listener;
105     this.listener = listener;
106     return oldListener;
107     }
108 
109     /**
110      * Removes the listener when it no longer need to be notified.
111      * @return the old listener
112      */
113     public DCListener removeListener() {
114     return setListener(null);
115     }
116 
117     /**
118      * Kicks the times into action. Is called when a button is pressed.
119      */
120     private void startAction() {
121     bigTimer.request();
122     }
123 
124     /**
125      * Stops the timers. Is called when a button is released.
126      */
127     private void stopAction() {
128     smallTimer.cancel();
129     bigTimer.cancel();
130     }
131 
132     /**
133      * Notifies the listener about whether to increment or decrement and
134      * by how much.
135      * @param bigFlag true if the listener needs to increment/decrement
136      * by a large amount, false otherwise.
137      */
138     private void informListener(boolean bigFlag) {
139     // System.out.println("DCPanel.informListener: " + bigFlag);
140 
141         if (listener != null) {
142 
143             if (bigFlag) {
144 	    // request a big change
145 	    if (incrementFlag)
146 	        listener.bigIncrement();
147 	    else
148 	        listener.bigDecrement();
149             } else {
150 	    // request a small change
151 	    if (incrementFlag)
152 	        listener.increment();
153 	    else
154 	        listener.decrement();
155             }
156 
157         }
158 
159     } // informListener
160 
161 
162     // ***********************************************
163     // 	 I N N E R    C L A S S E S   F O L L O W
164     // ***********************************************
165 
166     /**
167      * A timer class since java does not have one.
168      */
169     private abstract class Timer extends Thread {
170     private boolean running = false;
171 
172     /**
173      * Sleeps till the timer's services are requested using wait() and
174      * notify(). Then it does its task and goes back to sleep. And
175      * loops forever like this.
176      */
177     public void run() {
178         while (true) {
179 	try {
180 	  synchronized (this) {
181 	    running = false;
182 	    // Wait till the timer is required
183 	    wait();
184 	    running = true;
185 	  }
186 	  doTask();
187 	} catch (InterruptedException e) {}
188         } // while loop
189     } // run method
190 
191     protected void doTask() {} // bug in java workshop
192 
193     /**
194      * Wakes up the timer.
195      */
196     public synchronized void request() {
197         notify();
198     }
199 
200     /**
201      * Cancels the timer if it is running.
202      */
203     public void cancel() {
204         if (running) {
205 	interrupt();
206         }
207     }
208 
209     }// class Timer
210 
211     /**
212      * The first stage of timer - is a longer timer. Wait to see if the
213      * user really wants to amek the increments/decrements go by fast.
214      */
215     private class BigTimer extends Timer {
216 
217     /**
218      * Sleep for the long amount of time. Then inform the listener
219      * to have a bigIncrement/bigDecrement. After that, your job is
220      * done, schedule the smaller (faster) timer from this point on.
221      */
222     protected void doTask() {
223         try {
224 	sleep(BIG_SLEEP_TIME);
225 	informListener(true);
226 	smallTimer.request();
227         } catch (InterruptedException e) {
228 	informListener(false);
229         }
230     }
231 
232     } // class BigTimer
233 
234 
235     /**
236      * The second stage of timers. This timer keeps rescheduling itself
237      * everytime it wakes up. In between this, it sends a notification
238      * to the listener to do a big Increment/Decrement.
239      */
240     private class SmallTimer extends Timer {
241 
242     protected void doTask() {
243         try {
244 	// loop forever and keep rescheduling yourself
245 	while (true) {
246 	  sleep(SMALL_SLEEP_TIME);
247 	  informListener(true);
248 	    }
249         } catch (InterruptedException e) {}
250     } // doTask method
251 
252     } // class SmallTimer
253 
254     /**
255      * A mouse listener to detect when a button has been
256      * pressed/released. One instance of this is bound to the plus
257      * button and the other instance to the minus button.
258      */
259     private class DCMouseListener extends MouseAdapter {
260     private boolean plusOrMinus;
261 
262     /**
263      * Constructor for DCMouseListener.
264      * @param plusOrMinus true if this is a listener for the plus
265      *     button, false if it is for the minus button.
266      */
267     public DCMouseListener(boolean plusOrMinus) {
268         this.plusOrMinus = plusOrMinus;
269     }
270 
271     /**
272      * Kicks in when the mouse is pressed.
273      */
274     public void mousePressed(MouseEvent e) {
275         incrementFlag = plusOrMinus;
276         DCPanel.this.startAction();
277     }
278 
279     /**
280      * Kicks in when the mouse is released.
281      */
282     public void mouseReleased(MouseEvent e) {
283         incrementFlag = plusOrMinus;
284         DCPanel.this.stopAction();
285         }
286     }
287 
288     /**
289      * The button used by this DCPanel.
290      */
291     private class DCButton extends Button {
292     public DCButton(String text) {
293         super(text);
294         if (text.equals("+"))
295            addMouseListener(new DCMouseListener(true));
296         else
297         addMouseListener(new DCMouseListener(false));
298     }
299 
300     /**
301      * Make the button non-focus traversable so that it cannot be
302      * tabbed in to.
303      */
304     public boolean isFocusTraversable() {
305         return false;
306     }
307 
308     } // DCButton
309 
310 
311     /**
312      * Test method for DCPanel class to see appearance.
313      */
314     public static void main(String args[]) {
315     Frame f = new Frame("Testing DCPanel");
316     f.add(new DCPanel());
317     f.setBounds(new Rectangle(100, 100, 100, 100));
318     f.setVisible(true);
319     }
320 
321 }
322