1: import java.io.*;
2: import java.net.*;
3:
4: public class RemoteFileCopier {
5: public RemoteFileCopier(File name, Socket connection) throws java.io.IOException {
6: OutputStream out = connection.getOutputStream();
7: InputStream in = new FileInputStream(name);
8:
9: int ch;
10:
11: while ((ch = in.read()) != -1)
12: out.write(ch);
13:
14: in.close(); out.close();
15: }
16: }
Anyhow, there are a lot of things Swing can do, namely that it is much simpler than the native Win32 API – heck, I suppose there are WYSIWYG Java GUI builders out there, but Swing (and the AWT) provide an easy way to build complex GUIs in code. Check this little snippet out, taken from this website.
1: // file: EmptyFrame.java
2: // Adapted from Core Java, vol.1, by Horstmann & Cornell
3:
4: import javax.swing.*;
5:
6: class MyFrame extends JFrame {
7: public MyFrame() {
8: setTitle("My Empty Frame");
9: setSize(300,200); // default size is 0,0
10: setLocation(10,200); // default is 0,0 (top left corner)
11: }
12:
13: public static void main(String[] args) {
14: JFrame f = new MyFrame();
15: f.show();
16: }
17: }
This class extends the JFrame class, so it doesn’t have to create an instance of it and can call its public methods directly.
Deprecation Warning: If your Java compiler complains about line 15 being “deprecated”, and you want to shut it up, change it to f.setVisible(true);Now that code snippet created a window with a size of 300 pixels by 200 pixels. However, it’s rather empty. Let’s add a small push button.
1: // file: EmptyFrame.java
2: // Adapted from Core Java, vol.1, by Horstmann & Cornell
3:
4: import javax.swing.*;
5:
6: class MyFrame extends JFrame {
7: public MyFrame() {
8: setTitle("My Empty Frame");
9: setSize(300,200); // default size is 0,0
10: setLocation(10,200); // default is 0,0 (top left corner)
11: Container pane = getContentPane();
12: JButton button = new JButton("CHANGE THIS TEXT");
13: pane.add(button);
14: }
15:
16: public static void main(String[] args) {
17: JFrame f = new MyFrame();
18: f.show();
19: }
20: }
Now the entire window will be filled with a button. I hope now you see what Swing is capable of – in fact, you can obviously use Swing to create a GUI for a previously command line run application. And because it’s Java, it’ll work in every operating system that has a JVM, though the controls will look a bit different depending on your OS.
To demonstrate this point, here’s a simple terminal application using two text fields. It’s actually a small part of a large module I’m writing for yet another project called Tracker.
1: import javax.swing.*;
2: import java.awt.event.*;
3: import java.awt.*;
4: import java.util.StringTokenizer;
5:
6: public class CommandWindowDialog extends JDialog implements ActionListener {
7:
8: private JTextArea log = new JTextArea(5, 40);
9: private JTextField prompt = new JTextField();
10:
11: private static final String COMMANDS = "help (h) - shows this window.\n" +
12: "quit (exit) <exit code> - exit the program with error code. if error not specified, command ignored.\n" +
13: "clear (cls) - clears the screen.\n" +
14: "what - displays information.\n" +
15: "echo <message> - echos the message.\n" +
16: "exec <program name> - executes the specified program.\n";
17:
18: public CommandWindowDialog(Tracker parent) {
19: super(parent, "Command Window", false);
20: setSize(500, 250);
21:
22: log.setText("Type <help> for a list of commands.\n\n");
23: log.setEditable(false);
24:
25: addComponents();
26:
27: setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
28: setVisible(true);
29: }
30:
31: private void addComponents() {
32: Container c = getContentPane();
33: c.add("Center", new JScrollPane(log));
34: c.add("South", prompt);
35:
36: prompt.addActionListener(this);
37: }
38:
39: public void actionPerformed(ActionEvent e) {
40: try {
41: CommandWindowDialog.processCommand(prompt.getText(), log);
42: prompt.setText("");
43: }
44: catch (java.io.IOException exec) { JOptionPane.showMessageDialog(this, exec.getMessage()); }
45: }
46:
47: public static void processCommand(String command, JTextArea log) throws java.io.IOException {
48: StringTokenizer parser = new StringTokenizer(command);
49:
50: String head = parser.nextToken();
51:
52: if (head.equals("quit") || head.equals("exit")) {
53: if ((JOptionPane.showConfirmDialog(null, "This will immediatly kill your current connection. Okay?") == JOptionPane.YES_OPTION)) {
54: System.exit(Integer.parseInt(parser.nextToken()));
55: }
56: }
57:
58: if (head.equals("cls") || head.equals("clear")) {
59: log.setText("");
60: }
61:
62: if (head.equals("help") || head.equals("h")) {
63: log.setText(log.getText() + "Understood Commands:\n" + COMMANDS + "\n");
64: }
65:
66: if (head.equals("what")) {
67: log.setText(log.getText() + "This is the Tracker command window. Here you can see various processes and enter commands.\n");
68: }
69:
70: if (head.equals("echo")) {
71: log.setText(log.getText() + command.substring(5) + "\n");
72: }
73:
74: if (head.equals("exec")) {
75: Process p = new ProcessBuilder(command.substring(5), null).start();
76: p = null; //Prevent memory leaks.
77: }
78: }
79: }
If you strip out the vast majority of the input-processing code, what you’re left with is actually the GUI-building code:
1: import javax.swing.*;
2: import java.awt.event.*;
3: import java.awt.*;
4: import java.util.StringTokenizer;
5:
6: public class CommandWindowDialog extends JDialog implements ActionListener {
7:
8: private JTextArea log = new JTextArea(5, 40);
9: private JTextField prompt = new JTextField();
10:
11: ...
12:
13: public CommandWindowDialog(Tracker parent) {
14: super(parent, "Command Window", false);
15: setSize(500, 250);
16:
17: log.setText("Type <help> for a list of commands.\n\n");
18: log.setEditable(false);
19:
20: addComponents();
21:
22: setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
23: setVisible(true);
24: }
25:
26: private void addComponents() {
27: Container c = getContentPane();
28: c.add("Center", new JScrollPane(log));
29: c.add("South", prompt);
30:
31: prompt.addActionListener(this);
32: }
33:
34: ...
35:
36: }
Although some of you may find this cumbersome, it is certainly much simpler when compared to the native Win32 API, whose code looks like this (when coded in C):
1: ...
2:
3: LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
4: {
5: switch(Message)
6: {
7: case WM_CREATE:
8: {
9: HMENU hMenu, hSubMenu;
10: HICON hIcon, hIconSm;
11:
12: hMenu = CreateMenu();
13:
14: hSubMenu = CreatePopupMenu();
15: AppendMenu(hSubMenu, MF_STRING, ID_FILE_ADD, "&Add File");
16: //hSubMenu = CreatePopupMenu();
17: //AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "E&xit");
18: AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File");
19:
20: hSubMenu = CreatePopupMenu();
21: AppendMenu(hSubMenu, MF_STRING, ID_STUFF_GO, "&Go");
22: AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Control");
23:
24: SetMenu(hwnd, hMenu);
25:
26: hIcon = (HICON)LoadImage(NULL, "menu_two.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
27: if(hIcon)
28: {
29: SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
30: }
31: else
32: {
33: MessageBox(hwnd, "Failed to load large file icon. It should be in same directory as program.", "Error", MB_OK | MB_ICONERROR);
34: }
35:
36: hIconSm = (HICON)LoadImage(NULL, "menu_two.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
37: if(hIconSm)
38: {
39: SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
40: }
41: else
42: {
43: MessageBox(hwnd, "Failed to load small file icon. It should be in same directory as program.", "Error", MB_OK | MB_ICONERROR);
44: }
45: }
46: break;
47: case WM_COMMAND:
48: switch(LOWORD(wParam))
49: {
50: case ID_FILE_EXIT:
51: PostMessage(hwnd, WM_CLOSE, 0, 0);
52: break;
53: case ID_STUFF_GO:
54: if (strcmp (szFileName,"") != 0) {
55: IncinerateFiles(hwnd); }
56: else {
57: MessageBox(hwnd, "No file selected. Select a file using File > Add File.", "Error", MB_OK | MB_ICONERROR); }
58: break;
59: case ID_FILE_ADD:
60: GetNameOfTarget(hwnd);
61: break;
62: case ID_STUFF_ABOUT:
63: MessageBox(hwnd, "(c) 2011 Subversion Systems. All rights reserved.\n\nNot responsible for any potential illegal use of program.", "About", MB_OK);
64: break;
65: }
66: break;
67: case WM_CLOSE:
68: DestroyWindow(hwnd);
69: break;
70: case WM_DESTROY:
71: PostQuitMessage(0);
72: break;
73: default:
74: return DefWindowProc(hwnd, Message, wParam, lParam);
75: }
76: return 0;
77: }
78:
79: int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
80: LPSTR lpCmdLine, int nCmdShow)
81: {
82: WNDCLASSEX wc;
83: HWND hwnd;
84: MSG Msg;
85:
86: wc.cbSize = sizeof(WNDCLASSEX);
87: wc.style = 0;
88: wc.lpfnWndProc = WndProc;
89: wc.cbClsExtra = 0;
90: wc.cbWndExtra = 0;
91: wc.hInstance = hInstance;
92: wc.hIcon = NULL;
93: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
94: wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
95: wc.lpszMenuName = NULL;
96: wc.lpszClassName = g_szClassName;
97: wc.hIconSm = NULL;
98:
99: if(!RegisterClassEx(&wc))
100: {
101: MessageBox(NULL, "Window Registration Failed!", "Error!",
102: MB_ICONEXCLAMATION | MB_OK);
103: return 0;
104: }
105:
106: hwnd = CreateWindowEx(
107: WS_EX_CLIENTEDGE,
108: g_szClassName,
109: "Incinerator",
110: WS_OVERLAPPEDWINDOW,
111: CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
112: NULL, NULL, hInstance, NULL);
113:
114: if(hwnd == NULL)
115: {
116: MessageBox(NULL, "Window Creation Failed!", "Error!",
117: MB_ICONEXCLAMATION | MB_OK);
118: return 0;
119: }
120:
121: ShowWindow(hwnd, nCmdShow);
122: UpdateWindow(hwnd);
123:
124: while(GetMessage(&Msg, NULL, 0, 0) > 0)
125: {
126: TranslateMessage(&Msg);
127: DispatchMessage(&Msg);
128: }
129: return Msg.wParam;
130: }
Now isn't that a good old fashioned pain in the ass? So, sure, you could use Visual C, which I hear has a drag and drop GUI builder (correct me if I’m wrong), but that requires .NET, which has dependencies and requires the system to be installed for the end user. Java, although it requires a JVM, requires no such other dependencies, so you’re set on a new PC install.
Also, you’ll notice just code size. The C Win32 implementation required 130 lines (the actual code is bigger due to trimming of irrelevant parts). That’s a lot of code for a programmer to write, debug, and maintain.
So, in essence Swing is a much easier GUI creation tool in nearly every way. If you want to full API docs, the version 7 link is here.
That’s all for tonight, folks. You can grab our RSS feed to subscribe and always stay up to date. Hopefully we’ll have more Java talks in the future! Thank you, and goodnight.
-SevenBits