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