1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 /***
16 * Modified on Jun 15, 2005, Copyright UC Regents
17 */
18 package org.telscenter.pas.util;
19
20 import java.util.logging.Level;
21 import java.util.logging.Logger;
22
23 import java.awt.BorderLayout;
24 import java.awt.Color;
25 import java.awt.Container;
26 import java.awt.GridLayout;
27 import java.io.IOException;
28 import java.util.Enumeration;
29 import java.util.Vector;
30
31 import javax.jmdns.JmDNS;
32 import javax.jmdns.ServiceEvent;
33 import javax.jmdns.ServiceInfo;
34 import javax.jmdns.ServiceListener;
35 import javax.jmdns.ServiceTypeListener;
36 import javax.swing.DefaultListModel;
37 import javax.swing.JFrame;
38 import javax.swing.JLabel;
39 import javax.swing.JList;
40 import javax.swing.JPanel;
41 import javax.swing.JScrollPane;
42 import javax.swing.JTextArea;
43 import javax.swing.ListSelectionModel;
44 import javax.swing.SwingUtilities;
45 import javax.swing.border.EmptyBorder;
46 import javax.swing.event.ListSelectionEvent;
47 import javax.swing.event.ListSelectionListener;
48 import javax.swing.table.AbstractTableModel;
49
50 /***
51 * User Interface for browsing JmDNS services.
52 *
53 * @author Arthur van Hoff, Werner Randelshofer, turadg
54 */
55 public class JmdnsBrowser extends JPanel implements ServiceListener,
56 ServiceTypeListener, ListSelectionListener {
57 /***
58 * Logger for this class
59 */
60 private static final Logger logger = Logger.getLogger(JmdnsBrowser.class
61 .getName());
62
63 JmDNS jmdns;
64
65 Vector headers;
66
67 String type;
68
69 DefaultListModel types;
70
71 JList typeList;
72
73 DefaultListModel services;
74
75 JList serviceList;
76
77 JTextArea info;
78
79 public JmdnsBrowser(JmDNS jmdns) throws IOException {
80 this.jmdns = jmdns;
81
82 Color bg = new Color(230, 230, 230);
83 EmptyBorder border = new EmptyBorder(5, 5, 5, 5);
84 Container content = this;
85 content.setLayout(new GridLayout(1, 3));
86
87 types = new DefaultListModel();
88 typeList = new JList(types);
89 typeList.setBorder(border);
90 typeList.setBackground(bg);
91 typeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
92 typeList.addListSelectionListener(this);
93
94 JPanel typePanel = new JPanel();
95 typePanel.setLayout(new BorderLayout());
96 typePanel.add("North", new JLabel("Types"));
97 typePanel.add("Center", new JScrollPane(typeList,
98 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
99 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
100 content.add(typePanel);
101
102 services = new DefaultListModel();
103 serviceList = new JList(services);
104 serviceList.setBorder(border);
105 serviceList.setBackground(bg);
106 serviceList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
107 serviceList.addListSelectionListener(this);
108
109 JPanel servicePanel = new JPanel();
110 servicePanel.setLayout(new BorderLayout());
111 servicePanel.add("North", new JLabel("Services"));
112 servicePanel.add("Center", new JScrollPane(serviceList,
113 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
114 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
115 content.add(servicePanel);
116
117 info = new JTextArea();
118 info.setBorder(border);
119 info.setBackground(bg);
120 info.setEditable(false);
121 info.setLineWrap(true);
122
123 JPanel infoPanel = new JPanel();
124 infoPanel.setLayout(new BorderLayout());
125 infoPanel.add("North", new JLabel("Details"));
126 infoPanel.add("Center", new JScrollPane(info,
127 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
128 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
129 content.add(infoPanel);
130
131 jmdns.addServiceTypeListener(this);
132
133
134 String list[] = new String[] { "_http._tcp.local.", "_ftp._tcp.local.",
135 "_tftp._tcp.local.", "_ssh._tcp.local.", "_smb._tcp.local.",
136 "_printer._tcp.local.", "_airport._tcp.local.",
137 "_afpovertcp._tcp.local.", "_ichat._tcp.local.",
138 "_eppc._tcp.local.", "_presence._tcp.local." };
139
140 for (int i = 0; i < list.length; i++) {
141 jmdns.registerServiceType(list[i]);
142 }
143
144 setVisible(true);
145 }
146
147 /***
148 * Add a service.
149 */
150 public void serviceAdded(ServiceEvent event) {
151 final String name = event.getName();
152
153 if (logger.isLoggable(Level.CONFIG)) {
154 logger.config("ADD: " + name);
155 }
156 SwingUtilities.invokeLater(new Runnable() {
157 public void run() {
158 insertSorted(services, name);
159 }
160 });
161 }
162
163 /***
164 * Remove a service.
165 */
166 public void serviceRemoved(ServiceEvent event) {
167 final String name = event.getName();
168
169 if (logger.isLoggable(Level.CONFIG)) {
170 logger.config("REMOVE: " + name);
171 }
172 SwingUtilities.invokeLater(new Runnable() {
173 public void run() {
174 services.removeElement(name);
175 }
176 });
177 }
178
179 /***
180 * A new service type was <discovered.
181 */
182 public void serviceTypeAdded(ServiceEvent event) {
183 final String type = event.getType();
184
185 if (logger.isLoggable(Level.CONFIG)) {
186 logger.config("TYPE: " + type);
187 }
188 SwingUtilities.invokeLater(new Runnable() {
189 public void run() {
190 insertSorted(types, type);
191 }
192 });
193 }
194
195 void insertSorted(DefaultListModel model, String value) {
196 for (int i = 0, n = model.getSize(); i < n; i++) {
197 if (value.compareToIgnoreCase((String) model.elementAt(i)) < 0) {
198 model.insertElementAt(value, i);
199 return;
200 }
201 }
202 model.addElement(value);
203 }
204
205 /***
206 * Resolve a service.
207 */
208 @SuppressWarnings("unchecked")
209 public void serviceResolved(ServiceEvent event) {
210 String name = event.getName();
211 String type = event.getType();
212 ServiceInfo info = event.getInfo();
213
214 if (name.equals(serviceList.getSelectedValue())) {
215 if (info == null) {
216 this.info.setText("service not found");
217 } else {
218
219 StringBuffer buf = new StringBuffer();
220 buf.append(name);
221 buf.append('.');
222 buf.append(type);
223 buf.append('\n');
224 buf.append(info.getServer());
225 buf.append(':');
226 buf.append(info.getPort());
227 buf.append('\n');
228 buf.append(info.getAddress());
229 buf.append(':');
230 buf.append(info.getPort());
231 buf.append('\n');
232 for (Enumeration names = info.getPropertyNames(); names
233 .hasMoreElements();) {
234 String prop = (String) names.nextElement();
235 buf.append(prop);
236 buf.append('=');
237 buf.append(info.getPropertyString(prop));
238 buf.append('\n');
239 }
240
241 this.info.setText(buf.toString());
242 }
243 }
244 }
245
246 /***
247 * List selection changed.
248 */
249 public void valueChanged(ListSelectionEvent e) {
250 if (!e.getValueIsAdjusting()) {
251 if (e.getSource() == typeList) {
252 type = (String) typeList.getSelectedValue();
253 jmdns.removeServiceListener(type, this);
254 services.setSize(0);
255 info.setText("");
256 if (type != null) {
257 jmdns.addServiceListener(type, this);
258 }
259 } else if (e.getSource() == serviceList) {
260 String name = (String) serviceList.getSelectedValue();
261 if (name == null) {
262 info.setText("");
263 } else {
264 if (logger.isLoggable(Level.CONFIG)) {
265 logger
266 .config(this
267 + " valueChanged() type:" + type + " name:" + name);
268 }
269 System.out.flush();
270 ServiceInfo service = jmdns.getServiceInfo(type, name);
271 if (service == null) {
272 info.setText("service not found");
273 } else {
274 jmdns.requestServiceInfo(type, name);
275 }
276 }
277 }
278 }
279 }
280
281 /***
282 * Table data.
283 */
284 class ServiceTableModel extends AbstractTableModel {
285 public String getColumnName(int column) {
286 switch (column) {
287 case 0:
288 return "service";
289 case 1:
290 return "address";
291 case 2:
292 return "port";
293 case 3:
294 return "text";
295 }
296 return null;
297 }
298
299 public int getColumnCount() {
300 return 1;
301 }
302
303 public int getRowCount() {
304 return services.size();
305 }
306
307 public Object getValueAt(int row, int col) {
308 return services.elementAt(row);
309 }
310 }
311
312 /***
313 * Main program.
314 */
315 public static void main(String argv[]) throws IOException {
316 JFrame browserFrame = new JFrame("JmDNS Browser");
317
318 JPanel browser = new JmdnsBrowser(new JmDNS());
319
320 browserFrame.getContentPane().add(browser);
321 browserFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
322 browserFrame.setLocation(100, 100);
323 browserFrame.setSize(600, 400);
324 browserFrame.setVisible(true);
325 }
326 }