📄 telephone.java
字号:
gridConstraints.weighty = 0.0; gridbag.setConstraints(_dialButtons[10], gridConstraints); pane.add(_dialButtons[10]); gridConstraints.anchor = GridBagConstraints.CENTER; gridConstraints.gridx = 1; gridConstraints.gridy = 6; gridConstraints.gridwidth = 1; gridConstraints.gridheight = 1; gridConstraints.ipadx = 2; gridConstraints.ipady = 2; gridConstraints.weightx = 0.0; gridConstraints.weighty = 0.0; gridbag.setConstraints(_dialButtons[0], gridConstraints); pane.add(_dialButtons[0]); gridConstraints.anchor = GridBagConstraints.CENTER; gridConstraints.gridx = 2; gridConstraints.gridy = 6; gridConstraints.gridwidth = 1; gridConstraints.gridheight = 1; gridConstraints.ipadx = 2; gridConstraints.ipady = 2; gridConstraints.weightx = 0.0; gridConstraints.weighty = 0.0; gridbag.setConstraints(_dialButtons[11], gridConstraints); pane.add(_dialButtons[11]); return; } private void _soundPhoneNumber(LinkedList audioList) { int i; String digit; AudioData data; // If this is a long distance number, sound out the // area code first. if (_callType == LONG_DISTANCE) { for (i = 0; i < _areaCode.length(); ++i) { digit = _areaCode.substring(i, (i + 1)); data = (AudioData) _audioMap.get(digit); audioList.add(data); } } // All types have an exchange. for (i = 0; i < _exchange.length(); ++i) { digit = _exchange.substring(i, (i + 1)); data = (AudioData) _audioMap.get(digit); audioList.add(data); } // Only long distance and local numbers have a local // portion. if (_callType == LONG_DISTANCE || _callType == LOCAL) { for (i = 0; i < _local.length(); ++i) { digit = _local.substring(i, (i + 1)); data = (AudioData) _audioMap.get(digit); audioList.add(data); } } return; } private void _soundMeridian(int am_pm, LinkedList audioList) { AudioData clip; if (am_pm == Calendar.AM) { clip = (AudioData) _audioMap.get("AM"); } else { clip = (AudioData) _audioMap.get("PM"); } audioList.add(clip); return; } private void _soundNumber(int number, boolean zeroFlag, LinkedList audioList) { AudioData clip; if (number < 10 && zeroFlag == true) { clip = (AudioData) _audioMap.get("oh"); audioList.add(clip); clip = (AudioData) _audioMap.get(Integer.toString(number)); audioList.add(clip); } else if (number < 20) { clip = (AudioData) _audioMap.get(Integer.toString(number)); audioList.add(clip); } else { int onesDigit = number % 10; int tensDigit = number - onesDigit; // Read the ten's digit first and then the // remainder - if not zero. clip = (AudioData) _audioMap.get(Integer.toString(tensDigit)); audioList.add(clip); if (onesDigit != 0) { clip = (AudioData) _audioMap.get(Integer.toString(onesDigit)); audioList.add(clip); } } return; } private void _playbackDone(PlaybackThread thread) { _playbackThread = null; _fsm.PlaybackDone(); } private void _callRoute(int route) { switch (route) { case EMERGENCY: _fsm.Emergency(); break; case NYC_TEMP: _fsm.NYCTemp(); break; case TIME: _fsm.Time(); break; case DEPOSIT_MONEY: _fsm.DepositMoney(); break; case LINE_BUSY: _fsm.LineBusy(); break; case INVALID_NUMBER: _fsm.InvalidNumber(); break; } return; }// Member data. // The telphone state machine. private TelephoneContext _fsm; // The type of call being dialed. private int _callType; // Store dialed numbers here. private String _areaCode; private String _exchange; private String _local; private String _display; // Display the dialed digits here. private JTextField _numberDisplay; // This button is used to pick-up/put-down the receiver. private JButton _receiverButton; // Dialing buttons. private JButton[] _dialButtons; // Zounds! It's sounds! private AudioClip[] _dtmf; private Map _audioMap; private PlaybackThread _playbackThread; // Timer objects. private Map _timerMap; private static Timer _timer; private static Map _timerTransitionMap; // The telephone's time display. private static SimpleDateFormat _ClockFormatter = null; // Constants. public static final int LONG_DISTANCE = 1; public static final int LOCAL = 2; public static final int EMERGENCY = 3; private static final int NYC_TEMP = 4; private static final int TIME = 5; private static final int DEPOSIT_MONEY = 6; private static final int LINE_BUSY = 7; private static final int INVALID_NUMBER = 8; private static final long MILLIS_PER_MINUTE = 60000; static { _timer = new Timer(true); _timerTransitionMap = new HashMap(); _ClockFormatter = new SimpleDateFormat(" HH:mm a MMMM dd, yyyy"); // Fill in the static associations between timer names // and their transition. Class context = TelephoneContext.class; Class[] parameters = new Class[0]; try { _timerTransitionMap.put( "ClockTimer", context.getDeclaredMethod("ClockTimer", parameters) ); _timerTransitionMap.put( "OffHookTimer", context.getDeclaredMethod("OffHookTimer", parameters) ); _timerTransitionMap.put( "LoopTimer", context.getDeclaredMethod("LoopTimer", parameters) ); _timerTransitionMap.put( "RingTimer", context.getDeclaredMethod("RingTimer", parameters) ); } catch (NoSuchMethodException nsmex) { nsmex.printStackTrace(System.out); } }// Inner classes. private final class TelephoneTimer extends TimerTask { // Member methods. public void run() { _owner.issueTimeout(_name); } private TelephoneTimer(String name, long delay, Telephone owner) { _name = name; _delay = delay; _owner = owner; } private long getDelay() { return (_delay); } // Member data. private String _name; private long _delay; private Telephone _owner; } // When playing a series of audio clips, it is neccessary // to wait for one clip to finish before starting the next. // Since Java audio clips don't know how long they are, it // is necessary to store with each sound clip its duration. private final class AudioData { // Member methods. public void play() throws InterruptedException { if (_clip != null || (_clip = Applet.newAudioClip(_url)) != null) { _clip.play(); try { Thread.sleep(_duration); } catch (InterruptedException interrupt) { // Stop the audio clip before rethrowing the // intettupt. _clip.stop(); _clip = null; throw (interrupt); } } return; } public void loop() { if (_clip != null || (_clip = Applet.newAudioClip(_url)) != null) { _clip.loop(); } return; } public void stop() { if (_clip != null) { _clip.stop(); _clip = null; } return; } private AudioData(URL url, long duration) { _url = url; _clip = null; _duration = duration; } private URL getURL() { return (_url); } private long getDuration() { return (_duration); } // Member data. private URL _url; private AudioClip _clip; private long _duration; } // Play several audio clips, one after another in a // separate thread. private final class PlaybackThread extends Thread { // Member methods. public void run() { ListIterator it; AudioData clip = null; _thread = Thread.currentThread(); for (it = _audioList.listIterator(), _continueFlag = true; it.hasNext() == true && _continueFlag == true; ) { clip = (AudioData) it.next(); try { clip.play(); clip = null; } catch (InterruptedException interrupt) { _continueFlag = false; } } // Stop the currently playing sound. if (clip != null) { clip.stop(); } _audioList.clear(); if (_owner != null) { _owner._playbackDone(this); } return; } public void halt() { // Since the telephone object is telling us to // stop, don't tell the telephone that we are // stopped. _owner = null; _continueFlag = false; _thread.interrupt(); return; } private PlaybackThread(LinkedList audioList, Telephone owner) { _audioList = audioList; _owner = owner; _thread = null; _continueFlag = false; } // Member data. private LinkedList _audioList; private Telephone _owner; private boolean _continueFlag; private Thread _thread; } // Call routing needs to be done asynchronouzly in order to // avoid issuing a transition within a transition. private final class CallRoutingThread extends Thread { // Member methods. public void run() { int route; if (_callType == Telephone.EMERGENCY) { route = Telephone.EMERGENCY; } else if (_callType == Telephone.LONG_DISTANCE && _areaCode.compareTo("1212") == 0 && _exchange.compareTo("555") == 0 && _local.compareTo("1234") == 0) { route = Telephone.NYC_TEMP; } else if (_exchange.compareTo("555") == 0) { if (_local.compareTo("1212") == 0) { route = Telephone.TIME; } else { route = Telephone.LINE_BUSY; } } else if (_callType == Telephone.LOCAL) { route = Telephone.DEPOSIT_MONEY; } else { route = Telephone.INVALID_NUMBER; } _areaCode = null; _exchange = null; _local = null; // There is a race condition between this thread // and the main thread which contains the FSM. // Apparently this thread can complete while the // FSM is still in transition, causing an exception. // so sleep a bit before issuing the callback. try { Thread.sleep(1); } catch (InterruptedException interrupt) { // Ignore. } _owner._callRoute(route); return; } private CallRoutingThread(int callType, String areaCode, String exchange, String local, Telephone owner) { _callType = callType; _areaCode = new String(areaCode); _exchange = new String(exchange); _local = new String(local); _owner = owner; } // Member data. private int _callType; private String _areaCode; private String _exchange; private String _local; private Telephone _owner; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -