jsugar

Whew, did a lot of stuff:

- Window.java : Worked on automating the method linking process. Still a work in progress, so very volatile in terms of exceptions. - Added my test files, I figured they should be in there as well."

Author
Vngngdn
Date
July 16, 2016, 1:07 p.m.
Hash
a05e76e3c1e4e4821bea9d34af3f60919b75d321
Parent
9f3e9a84cfb79ff7c5fb48b907c08f1b54cf9878
Modified files
Window.java
anotherTest.java
test.java

Window.java

25 additions and 4 deletions.

View changes Hide changes
1
1
 * Window.java - Module to create a new window with JSugar.
2
2
 * Copyright © 2016 Maarten "Vngngdn" Vangeneugden
3
3
 * 
4
4
 * This program is free software: you can redistribute it and/or modify
5
5
 * it under the terms of the GNU General Public License as published by
6
6
 * the Free Software Foundation, either version 3 of the License, or
7
7
 * (at your option) any later version.
8
8
 * 
9
9
 * This program is distributed in the hope that it will be useful,
10
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
12
 * GNU General Public License for more details.
13
13
 * 
14
14
 * You should have received a copy of the GNU General Public License
15
15
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16
16
 */
17
17
18
18
/**
19
19
 * Window class for the program.
20
20
 *
21
21
 * Window contains the necessary data and methods to present the user with what
22
22
 * he's familiar with as being a "window". To make it functional, the developer
23
23
 * can make use of a series of methods to add components to said window, remove
24
24
 * components, and so on.
25
25
 * Currently, Window also contains methods to show dialogs. This will be cleaned
26
26
 * in the near future.
27
27
 * @author Maarten Vangeneugden
28
28
 */
29
29
import javax.swing.*; // FIXME: Maybe namespacing it to "javax.swing;" is a better idea.
30
30
import java.util.NoSuchElementException;
31
31
import java.lang.reflect.Method;
32
32
33
33
class Window {
34
34
	private JPanel panel; // The panel that contains all the components.
35
35
	private JFrame frame; // The "window" being presented to the user.
36
36
37
37
	/**
38
38
	 * Constructor of Window.
39
39
	 * By creating a new Window instance, this constructor will automatically
40
40
	 * start the initialization of the GUI. After doing so, the caller can
41
41
	 * start adding components to the window as pleased.
42
42
	 * @param title The title to be shown in the window's title bar.
43
43
	 */
44
44
	public Window() {
45
45
		this.panel = new JPanel();
46
46
		// TODO: The current title is "Hello world!" but that will become caller
47
47
		// defined soon.
48
48
		JFrame frame = new JFrame("Hello world!");
49
49
		// Makes it so that if the user clicks the X in the titlebar, the window
50
50
		// closes:
51
51
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
52
52
		//frame.getContentPane().add(lblHelloWorld); // So you use a get() in order to set() data? #JavaWTF
53
53
		frame.setContentPane(this.panel); // Connecting the component panel to the window.
54
54
		// Makes the window fit to the necessary width and height, so it can show all "subcomponents".
55
55
		frame.pack(); 	
56
56
		frame.setVisible(true); // Makes the window visible to the user.
57
57
		this.frame = frame;
58
58
	}
59
59
60
60
	/**
61
61
	 * Resizes the window to fit all components.
62
62
	 * By calling this method, the window will evaluate the currently visible
63
63
	 * components, and resize itself so that all components become properly
64
64
	 * visible.
65
65
	 */
66
66
	private void updateWindow() {
67
67
		this.frame.pack();
68
68
	}
69
69
70
70
	/**
+
71
	 * A series of tests for method and class handling.
+
72
	 * When a caller presents certain methods with data concerning reflection,
+
73
	 * the Java classes you need to use for that are quite opaque, and don't
+
74
	 * offer much safety in any way.
+
75
	 * The solution therefore, is run some validation checks, but these take up
+
76
	 * a decent amount of space in terms of LoC.
+
77
	 * This method takes care of all that. Call this function whenever data
+
78
	 * needs to be validated.
+
79
	/**
71
80
	 * Creates a button in the GUI for interaction.
72
81
	 * This function offers a convenient way to create a button, that can be
73
82
	 * directly interacted with by the user. After creation, the button itself
74
83
	 * is returned to the caller, if he wishes to do something else with it.
75
84
	 * @param text The text that will be displayed in the button.
76
85
	 * @param action The action that will be returned to the action listener.
77
86
	 * @param triggerMethod The method that will be called when an action is
78
-
	 * @param triggerObject The object instance that contains the given method.
79
-
	 * This may only be a null pointer if triggerMethod is not an instance
+
87
	 * action is triggered.
+
88
	 * @param objectInstance The object instance that contains the given method.
+
89
	 * This may only be a null pointer if triggerMethod is not an instance
80
90
	 * method.
81
91
	 * performed. This method may accept an ActionEvent parameter as its only
82
92
	 * parameter, or no parameters at all.
83
93
	 * @throws NullPointerException if triggerMethod is a null pointer.
84
-
	 * @throws IllegalArgumentException if triggerMethod has more than 1
+
94
	 * the empty String was given.
+
95
	 * @throws IllegalArgumentException if triggerMethod has more than 1
85
96
	 * parameter, or the 1 required parameter is not of type ActionEvent.
86
97
	 * @return The button that was created.
87
98
	 * @see java.awt.event.ActionEvent
88
99
	 * @see java.lang.reflect.Method.invoke()
89
100
	 */
90
101
	public JButton createButton(String text, String action, Method triggerMethod, Object triggerObject) {
91
-
		// For starters, we first assert that the given parameters are valid:
+
102
		Method triggerMethod;
+
103
		try {
+
104
			triggerMethod = triggerObject.getMethod(methodName, null);
+
105
		}
+
106
		catch (Exception e) {
+
107
			throw new IllegalArgumentException("The given method name does not exist in the given class.");
+
108
		}
+
109
+
110
+
111
		// For starters, we first assert that the given parameters are valid:
92
112
		if (text == null) {
93
113
			text = "";
94
114
		}
95
115
		if (action == null) {
96
116
			action = "";
97
117
		}
98
118
		if (triggerMethod == null) {
99
119
			throw new NullPointerException("The given method was a null pointer. All buttons need a functionality.");
100
120
		}
101
121
		Class<?>[] parameters = triggerMethod.getParameterTypes();
102
122
		if (parameters.length > 1) {
103
123
			throw new IllegalArgumentException("The given method needs more than 1 parameter, which is not allowed.");
104
124
		}
105
125
		if (parameters.length != 0) {
106
126
			if (parameters[0] != java.awt.event.ActionEvent.class) {
107
127
				throw new IllegalArgumentException("The given method has a parameter, but that parameter is not of type java.awt.event.ActionEvent.");
108
128
			}
109
129
		}
110
130
		
111
131
		// When the method gets here, everything's been validated correctly.
112
132
		JButton button = new JButton(text);
113
133
		button.setActionCommand(action);
114
134
		button.addActionListener(
115
135
				new java.awt.event.ActionListener() {
116
136
					public void actionPerformed(java.awt.event.ActionEvent event) {
117
137
						try {
118
138
							if (parameters.length == 0) {
+
139
							if (parameters.length == 0) {
119
140
								// FIXME: Next line throws a warning?
120
141
								triggerMethod.invoke(triggerObject, null);
121
142
							}
122
143
							else {
123
144
								triggerMethod.invoke(triggerObject, new Object[]{event});
124
145
							}
125
146
						}
126
147
						catch (Exception useless) {
127
148
							/*
128
149
							 * XXX: Some info on why I don't just throw said
129
150
							 * Exception to the caller:
130
151
							 * Java has this awful language constraint, which
131
152
							 * forces every damn exception that isn't a subclass
132
153
							 * of RuntimeException, to be declared in the method
133
154
							 * declaration. This tends to infect all underlying
134
155
							 * methods as well, and all that for reasons I can't
135
156
							 * comprehend. In order to keep JSugar a simple and
136
157
							 * clean library, I'll rather just handle it here,
137
158
							 * and throw a RuntimeException with appropriate
138
159
							 * details.
139
160
							 */
140
161
							throw new IllegalArgumentException("triggerMethod is not accessible from this context.");
141
162
						}
142
163
					}
143
164
				});
144
165
		this.panel.add(button);
145
166
		this.frame.pack();
146
167
		return button;
147
168
	}
148
169
149
170
	/**
150
171
	 * Ask the user for input through a dialog box.
151
172
	 * This method presents the user with an input field, that can accept
152
173
	 * textual input. The method will return the given input after the user's
153
174
	 * clicked a button to send.
154
175
	 * @param text The text/question to be asked to the user.
155
176
	 * @return A String, equal to what the user entered.
156
177
	 * @throws NullPointerException if text is a null pointer.
157
178
	 */
158
179
	public String inputDialog(String text) {
159
180
		if (text == null) {
160
181
			throw new NullPointerException("The given text/question was a null pointer.");
161
182
		}
162
183
		return JOptionPane.showInputDialog(text);
163
184
	}
164
185
165
186
	/**
166
187
	 * Give the user a dialog box.
167
188
	 * This method can be used to provide a simple dialog to the user.
168
189
	 * This will show the user the given question, after which a boolean value
169
190
	 * is returned, holding the choice.
170
191
	 * @param text The text/question to be asked to the user.
171
192
	 * @return True if the user confirms, False if he denies.
172
193
	 * @throws NullPointerException if text is a null pointer.
173
194
	 */
174
195
	public boolean confirmDialog(String text) {
175
196
		if (text == null) {
176
197
			throw new NullPointerException("The given text/question was a null pointer.");
177
198
		}
178
199
		final int ACCEPTED = 0;
179
200
		final int DENIED = 1;
180
201
		int result = this.choiceDialog(text, new String[]{"Confirm", "Deny"});
181
202
		if (result == ACCEPTED) {
182
203
			return true;
183
204
		}
184
205
		else {
185
206
			return false;
186
207
		}
187
208
	}
188
209
189
210
	/**
190
211
	 * Give the user a choice dialog box.
191
212
	 * This method gives the user a simple dialog with predefined choices.
192
213
	 * These choices are to be provided by the caller in a simple array.
193
214
	 * Tip: This method works extremely well with arbitrary created choices.
194
215
	 * That is: if the outcome of the dialog is trivial (e.g. Only 1 choice),
195
216
	 * then that value is immediately returned.
196
217
	 * @param text The text/question to be asked to the user.
197
218
	 * @param choices An array of Strings, containing the choices the user can
198
219
	 * pick.
199
220
	 * @return The index value of the picked choice, or -1 if no choices were
200
221
	 * given.
201
222
	 * @throws NullPointerException if text is a null pointer.
202
223
	 */
203
224
	public int choiceDialog(String text, String[] choices) {
204
225
		if (text == null) {
205
226
			throw new NullPointerException("The given text/question was a null pointer.");
206
227
		}
207
228
		// First: handling the trivial cases:
208
229
		if (choices.length == 0) {
209
230
			return -1;
210
231
		}
211
232
		else if (choices.length == 1) {
212
233
			return 0;
213
234
		}
214
235
		int answer = JOptionPane.CLOSED_OPTION;
215
236
		// The dialog needs to be shown again until the user has made a possible
216
237
		// choice, i.e. Chickening out using the close button is not possible
217
238
		// (Because that returns CLOSED_OPTION).
218
239
		while (answer == JOptionPane.CLOSED_OPTION) {
219
240
				JOptionPane.showOptionDialog(
220
241
					null, // The parent component. May become the panel?
221
242
					text, // The text/question to describe the goal
222
243
					"Dialog", // The text in the title bar
223
244
					JOptionPane.DEFAULT_OPTION, // The kind of available options
224
245
					JOptionPane.QUESTION_MESSAGE, // The type of message
225
246
					null, // The icon to show
226
247
					choices, // The possible choices
227
248
					choices[0] // The standard choice
228
249
					);
229
250
		}
230
251
		return answer;
231
252
	}
232
253
		
233
254
234
255
	/**
235
256
	 * Creates a label in the GUI for interaction.
236
257
	 * This function offers a convenient way to create a label, that can be
237
258
	 * directly interacted with by the user. After creation, the label itself
238
259
	 * is returned to the caller, if he wishes to do something else with it.
239
260
	 * @param text The text that will be displayed in the label.
240
261
	 * @return The label that was created.
241
262
	 */
242
263
	public JLabel createLabel(String text) {
243
264
		JLabel label = new JLabel(text);
244
265
		this.panel.add(label);
245
266
		return label;
246
267
	}
247
268
248
269
	/**
249
270
	 * Removes the given component from the GUI.
250
271
	 * This method allows its caller to remove a component from the GUI.
251
272
	 * @param component The component to be removed.
252
273
	 * @throws NoSuchElementException if the given component does not exist in
253
274
	 * the GUI.
254
275
	 * @throws NullPointerException if the given component is a null pointer.
255
276
	 */
256
277
	public void removeComponent(JComponent component) {
257
278
		int originalSize = this.panel.getComponentCount();
258
279
		this.panel.remove(component);
259
280
		int newSize = this.panel.getComponentCount();
260
281
		if (originalSize != newSize+1) {
261
282
			throw new NoSuchElementException("The given component does not exist in the GUI.");
262
283
		}
263
284
	}
264
285
}
265
286

anotherTest.java

24 additions and 0 deletions.

View changes Hide changes
+
1
import java.lang.reflect.Method;
+
2
public class anotherTest {
+
3
	public anotherTest() {
+
4
		Window window = new Window();
+
5
		JButton button = new JButton(); // Yeah, have to initialize that, because Java.
+
6
		try {
+
7
		button = window.createButton("Knopje!!", "???", "printSomething",  this);
+
8
		} catch(Exception e) {}
+
9
		try {
+
10
			Thread.sleep(1000);
+
11
		} catch (InterruptedException e){
+
12
			e.printStackTrace();
+
13
		}
+
14
		button.setText("LOL");
+
15
		System.out.println("Done.");
+
16
+
17
		System.out.println("Okay, that worked...");
+
18
	}
+
19
+
20
	public void printSomething() {
+
21
		System.out.println("Okay, I can print stuff.");
+
22
	}
+
23
}
+
24

test.java

16 additions and 0 deletions.

View changes Hide changes
+
1
	public static void main(String[] args) {
+
2
			anotherTest bup = new anotherTest();
+
3
		for (int i = 0; i < 10; i++) {
+
4
			try {
+
5
				Thread.sleep(1000);
+
6
			} catch (InterruptedException e){
+
7
				e.printStackTrace();
+
8
			}
+
9
		}
+
10
	}
+
11
+
12
	public static void printingSomething() {
+
13
		System.out.println("OMG");
+
14
	}
+
15
}
+
16