001: /*/////////////////////////////////////////////////////////////////////
002:
003: Copyright (C) 2006 TiVo Inc. All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions are met:
007:
008: + Redistributions of source code must retain the above copyright notice,
009: this list of conditions and the following disclaimer.
010: + Redistributions in binary form must reproduce the above copyright notice,
011: this list of conditions and the following disclaimer in the documentation
012: and/or other materials provided with the distribution.
013: + Neither the name of TiVo Inc nor the names of its contributors may be
014: used to endorse or promote products derived from this software without
015: specific prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
018: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
019: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
020: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
021: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
022: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
023: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
024: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
025: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
026: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
027: POSSIBILITY OF SUCH DAMAGE.
028:
029: /////////////////////////////////////////////////////////////////////*/
030:
031: package com.tivo.jipviewer;
032:
033: import java.awt.Component;
034: import java.awt.Container;
035: import java.awt.event.ActionEvent;
036: import java.awt.event.ActionListener;
037: import java.io.BufferedOutputStream;
038: import java.io.IOException;
039: import java.io.OutputStream;
040: import java.net.Socket;
041:
042: import javax.swing.BoxLayout;
043: import javax.swing.JButton;
044: import javax.swing.JLabel;
045: import javax.swing.JOptionPane;
046: import javax.swing.JSpinner;
047: import javax.swing.JTextField;
048: import javax.swing.SpinnerNumberModel;
049:
050: class RemoteController extends Container implements ActionListener {
051: JTextField mHostname;
052: SpinnerNumberModel mPortModel;
053: JTextField mState;
054: JButton mButton;
055: Boolean mIsRunning = null;
056: Boolean mNextIsRunning = null;
057:
058: RemoteController() {
059: mPortModel = new SpinnerNumberModel(15599, 0, 65355, 1);
060: JSpinner portSpinner = new JSpinner(mPortModel);
061:
062: mHostname = makeTextInput("localhost");
063: mState = makeTextOutput("state");
064: mButton = makeButton("start/stop");
065:
066: Container pair = makePair(makeLabel("server hostname"),
067: mHostname);
068: add(pair);
069:
070: pair = makePair(makeLabel("server port"), portSpinner);
071: add(pair);
072:
073: pair = makePair(makeLabel("state"), mState);
074: add(pair);
075:
076: add(mButton);
077:
078: updateState();
079:
080: setLayout(new BoxLayout(this , BoxLayout.Y_AXIS));
081: }
082:
083: private void updateState() {
084: String state = "unknown";
085: String buttonLabel = "stop";
086: if (mIsRunning == null || mIsRunning.booleanValue()) {
087: if (mIsRunning != null) {
088: state = "running";
089: }
090: buttonLabel = "stop";
091: mNextIsRunning = false;
092: } else {
093: state = "stopped";
094: buttonLabel = "start";
095: mNextIsRunning = true;
096: }
097: mState.setText(state);
098: mButton.setText(buttonLabel);
099:
100: String btnCmd = buttonLabel;
101: mButton.setActionCommand(btnCmd);
102: }
103:
104: public void actionPerformed(ActionEvent e) {
105: String cmd = e.getActionCommand();
106: if (cmd.equals("start") || cmd.equals("stop")) {
107: changeState(cmd);
108: } else {
109: throw new RuntimeException("unexpected button cmd (" + cmd
110: + ")");
111: }
112: }
113:
114: // snarfed from ClientHelper.java
115: void changeState(String command) {
116: String hostname = mHostname.getText();
117: int port = mPortModel.getNumber().intValue();
118: if (send(command, hostname, port)) {
119: // i'm assuming that if we didn't get a socket error from
120: // send, then the profiler changed state. ymmv.
121: mIsRunning = mNextIsRunning;
122: updateState();
123: }
124: }
125:
126: /**
127: * sends the given message to the given server:port.
128: * returns true iff there were no *detectable* errors.
129: * (note that this doesn't mean there weren't errors!)
130: */
131: static boolean send(String command, String server, int port) {
132: try {
133: Socket socket = new Socket(server, port);
134: OutputStream os = socket.getOutputStream();
135: BufferedOutputStream out = new BufferedOutputStream(os);
136: out.write(command.getBytes());
137: out.write('\r');
138: out.flush();
139: socket.close();
140: return true;
141: } catch (IOException e) {
142: String msg = ("Trouble sending '" + command + "' to "
143: + server + ":" + port + ":\n" + e);
144: String title = "error";
145: JOptionPane.showMessageDialog(null, msg, title,
146: JOptionPane.ERROR_MESSAGE);
147: return false;
148: }
149: }
150:
151: private Container makePair(Component left, Component right) {
152: Container pair = new Container();
153: pair.add(left);
154: pair.add(makeLabel(" ")); // inelegant spacer!
155: pair.add(right);
156: pair.setLayout(new BoxLayout(pair, BoxLayout.X_AXIS));
157: return pair;
158: }
159:
160: private JButton makeButton(String text) {
161: JButton button = new JButton(text);
162: button.addActionListener(this );
163: return button;
164: }
165:
166: private JLabel makeLabel(String text) {
167: JLabel label = new JLabel(text);
168: return label;
169: }
170:
171: private JTextField makeTextInput(String text) {
172: JTextField field = new JTextField(text);
173: return field;
174: }
175:
176: private JTextField makeTextOutput(String text) {
177: JTextField field = new JTextField(text);
178: field.setEditable(false);
179: return field;
180: }
181: };
|