swing_paradise 0.1.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of swing_paradise might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/README.md +1557 -0
- data/doc/README.gen +1510 -0
- data/lib/swing_paradise/autoinclude.rb +3 -0
- data/lib/swing_paradise/awt/README.md +1 -0
- data/lib/swing_paradise/awt/color.rb +45 -0
- data/lib/swing_paradise/base_module/base_module.rb +993 -0
- data/lib/swing_paradise/classes +1 -0
- data/lib/swing_paradise/examples/001_quit_button_example.rb +55 -0
- data/lib/swing_paradise/examples/002_text_area_example.rb +55 -0
- data/lib/swing_paradise/examples/003_combo_box_example.rb +57 -0
- data/lib/swing_paradise/examples/004_jpanel_left_bound_example.rb +41 -0
- data/lib/swing_paradise/examples/005_box_layout_example.rb +39 -0
- data/lib/swing_paradise/examples/006_frame_example.rb +33 -0
- data/lib/swing_paradise/examples/007_textarea_responding_to_enter_key_example.rb +28 -0
- data/lib/swing_paradise/examples/008_scrolled_window_example.rb +41 -0
- data/lib/swing_paradise/examples/009_font_size_example.rb +39 -0
- data/lib/swing_paradise/examples/010_counter_example.rb +183 -0
- data/lib/swing_paradise/examples/011_button_with_image_example.rb +58 -0
- data/lib/swing_paradise/examples/012_quit_on_escape_key_being_pressed.rb +37 -0
- data/lib/swing_paradise/examples/013_simple_box_example.rb +38 -0
- data/lib/swing_paradise/examples/014_mouse_events_example.rb +41 -0
- data/lib/swing_paradise/examples/015_menu_example.rb +77 -0
- data/lib/swing_paradise/examples/016_file_chooser_example.rb +96 -0
- data/lib/swing_paradise/examples/017_buttons_example.rb +56 -0
- data/lib/swing_paradise/examples/018_colour_chooser_example.rb +51 -0
- data/lib/swing_paradise/examples/019_jeditorpane_example.rb +61 -0
- data/lib/swing_paradise/examples/020_table_example.rb +77 -0
- data/lib/swing_paradise/examples/021_jsplitpane_example.rb +66 -0
- data/lib/swing_paradise/examples/022_drawing_oval_example.rb +51 -0
- data/lib/swing_paradise/examples/023_show_message_dialog_example.rb +57 -0
- data/lib/swing_paradise/java_classes/border_factory/border_factory.rb +19 -0
- data/lib/swing_paradise/java_classes/box/box.rb +72 -0
- data/lib/swing_paradise/java_classes/button +1 -0
- data/lib/swing_paradise/java_classes/checkbox +1 -0
- data/lib/swing_paradise/java_classes/combobox +1 -0
- data/lib/swing_paradise/java_classes/default_table_model/default_table_model.rb +18 -0
- data/lib/swing_paradise/java_classes/frame +1 -0
- data/lib/swing_paradise/java_classes/jbutton/jbutton.rb +199 -0
- data/lib/swing_paradise/java_classes/jcheckbox/jcheckbox.rb +28 -0
- data/lib/swing_paradise/java_classes/jcombobox/jcombobox.rb +31 -0
- data/lib/swing_paradise/java_classes/jcomponent/jcomponent.rb +253 -0
- data/lib/swing_paradise/java_classes/jeditorpane/jeditorpane.rb +23 -0
- data/lib/swing_paradise/java_classes/jfilechooser/jfilechooser.rb +22 -0
- data/lib/swing_paradise/java_classes/jframe/jframe.rb +319 -0
- data/lib/swing_paradise/java_classes/jlabel/jlabel.rb +171 -0
- data/lib/swing_paradise/java_classes/jmenu/jmenu.rb +13 -0
- data/lib/swing_paradise/java_classes/jmenubar/jmenubar.rb +13 -0
- data/lib/swing_paradise/java_classes/jpanel/jpanel.rb +115 -0
- data/lib/swing_paradise/java_classes/jscrollpane/jscrollpane.rb +84 -0
- data/lib/swing_paradise/java_classes/jspinner/jspinner.rb +17 -0
- data/lib/swing_paradise/java_classes/jtextarea/jtextarea.rb +120 -0
- data/lib/swing_paradise/java_classes/jtextfield/jtextfield.rb +314 -0
- data/lib/swing_paradise/java_classes/label +1 -0
- data/lib/swing_paradise/java_classes/panel +1 -0
- data/lib/swing_paradise/java_classes/spinner +1 -0
- data/lib/swing_paradise/java_classes/textarea +1 -0
- data/lib/swing_paradise/misc/misc.rb +57 -0
- data/lib/swing_paradise/prototype/prototype.rb +79 -0
- data/lib/swing_paradise/requires/require_the_project.rb +15 -0
- data/lib/swing_paradise/toplevel_methods/misc.rb +293 -0
- data/lib/swing_paradise/version/version.rb +17 -0
- data/lib/swing_paradise/widget_collection/README.md +2 -0
- data/lib/swing_paradise/widget_collection/text_viewer.rb +160 -0
- data/lib/swing_paradise.rb +1 -0
- data/swing_paradise.gemspec +42 -0
- metadata +120 -0
data/doc/README.gen
ADDED
@@ -0,0 +1,1510 @@
|
|
1
|
+
DEFAULT_HEADER
|
2
|
+
|
3
|
+
## Introduction to the swing_paradise project and its different goals
|
4
|
+
|
5
|
+
In the last some months of the year 2023/2024 I thought about the
|
6
|
+
goals of this project. This made me re-arrange the introductionary
|
7
|
+
section here. I will keep a numbered list of the goals of the
|
8
|
+
swing_paradise project.
|
9
|
+
|
10
|
+
(1) This gem contains some add-on bindings to jruby-Swing. This
|
11
|
+
is the primary goal.
|
12
|
+
|
13
|
+
<b>Swing</b> is an extension of the <b>Abstract Window Toolkit</b> (AWT),
|
14
|
+
a GUI (graphical user interface).
|
15
|
+
|
16
|
+
As Swing depends on Java, this project here really only makes
|
17
|
+
sense for use via <b>jruby</b>.
|
18
|
+
|
19
|
+
At present the project is fairly incomplete, but over the
|
20
|
+
coming months this should be improved. Right now this project
|
21
|
+
is beta-quality and I do not recommend anyone to use this
|
22
|
+
project. However had, for some limited scope, this project may
|
23
|
+
be fairly useful even if incomplete.
|
24
|
+
|
25
|
+
(2) Note that while the primary focus of this project will be on
|
26
|
+
Swing-based applications and add-on improvements, to make working
|
27
|
+
with jruby and Swing suck less, there is a secondary focus for
|
28
|
+
this project as well, in that I will attempt to create as many
|
29
|
+
Swing-based applications as possible, to make working on Windows
|
30
|
+
suck less. Most of these add-ons will reside under
|
31
|
+
<b>swing_paradise/widget_collection/</b>, but some may be grouped
|
32
|
+
into different gems, under either gui/jruby/ or gui/universal_widgets.
|
33
|
+
The latter will probably become more relevant in the future,
|
34
|
+
whereas for now, gui/jruby/ will be where most of the gui-relevant
|
35
|
+
bindings reside under.
|
36
|
+
|
37
|
+
With "Swing-based applications" I specifically mean being able to
|
38
|
+
use custom, ad-hoc widgets that solve certain problems, such
|
39
|
+
as "I want to delete the first page of this .pdf file,
|
40
|
+
via a GUI", on windows. In fact, that has been one major use
|
41
|
+
case why I intensified code for this project in October
|
42
|
+
2023 - I had to use windows as primary operating system
|
43
|
+
every now and then, and it always annoyed me compared
|
44
|
+
to Linux, so I decided to create widgets (and describe
|
45
|
+
them, too) that will help me on windows. Also note that
|
46
|
+
this is an ongoing effort - I can not predict how useful
|
47
|
+
and extensive this will be. Stay tuned nonetheless.
|
48
|
+
|
49
|
+
(3) Another focus of this project is to provide useful documentation
|
50
|
+
in regards to Swing, as well as jruby. This helps me as a mnemonic,
|
51
|
+
but it may also be helpful to new users, in what they can do
|
52
|
+
with the project here in the long run. When I started this
|
53
|
+
project there was next to no project that documented
|
54
|
+
Swing + jruby. So one aim of this project has been to
|
55
|
+
polish the documentation as much as possible.
|
56
|
+
|
57
|
+
## Terminology
|
58
|
+
|
59
|
+
In Java-Swing, a window is called a <b>frame</b>, which is represented
|
60
|
+
by class <b>JFrame</b>.
|
61
|
+
|
62
|
+
The default layout for Java-Swing components is a border layout.
|
63
|
+
|
64
|
+
## SwingParadise::BaseModule
|
65
|
+
|
66
|
+
SwingParadise::BaseModule is the core helper module of
|
67
|
+
this gem.
|
68
|
+
|
69
|
+
You can include it, since it is a module, via:
|
70
|
+
|
71
|
+
require 'swing_paradise/base_module/base_module.rb'
|
72
|
+
include SwingParadise::BaseModule
|
73
|
+
|
74
|
+
See also the distributed examples if you want to know
|
75
|
+
more about how to use this in practice.
|
76
|
+
|
77
|
+
Since as of 29th October 2023, this will also automatically
|
78
|
+
pull in most of the important java-swing methods. I found
|
79
|
+
this easier to work with, than have to remember which
|
80
|
+
widgets I need.
|
81
|
+
|
82
|
+
This is done via java_import statements, such as:
|
83
|
+
|
84
|
+
java_import javax.swing.JPasswordField
|
85
|
+
|
86
|
+
So basically you can omit a few lines in your application
|
87
|
+
by tapping into the BaseModule module.
|
88
|
+
|
89
|
+
## Simplified quitting
|
90
|
+
|
91
|
+
Use the following method to <b>quit</b> easily:
|
92
|
+
|
93
|
+
do_quit
|
94
|
+
|
95
|
+
For instance, a <b>quit button</b> could then be done in this
|
96
|
+
manner:
|
97
|
+
|
98
|
+
quit_button.on_clicked {
|
99
|
+
do_quit
|
100
|
+
}
|
101
|
+
|
102
|
+
## Useful java_import headers
|
103
|
+
|
104
|
+
include Java
|
105
|
+
|
106
|
+
java_import javax.swing.JButton
|
107
|
+
java_import javax.swing.JFrame
|
108
|
+
java_import javax.swing.JLabel
|
109
|
+
java_import javax.swing.JPanel
|
110
|
+
java_import javax.swing.JTextArea
|
111
|
+
java_import javax.swing.JScrollBar
|
112
|
+
java_import javax.swing.JTextField
|
113
|
+
java_import javax.swing.JSpinner
|
114
|
+
java_import javax.swing.SpinnerNumberModel
|
115
|
+
java_import java.lang.System
|
116
|
+
java_import java.awt.Font
|
117
|
+
|
118
|
+
## Usage example for setBounds
|
119
|
+
|
120
|
+
_.setBounds(10, 20, 200, 40) /* is: x-coordinate, y-coordinate, width, height) */
|
121
|
+
_.set_bounds(10, 20, 200, 40) /* is: x-coordinate, y-coordinate, width, height) */
|
122
|
+
|
123
|
+
Note that both variants work. I prefer <b>.set_bounds()</b>.
|
124
|
+
|
125
|
+
<!---
|
126
|
+
|
127
|
+
https://www.rubydoc.info/gems/swing_paradise/0.1.13#jtextarea
|
128
|
+
|
129
|
+
-->
|
130
|
+
## JTextArea
|
131
|
+
|
132
|
+
First, let's have a look as to how a JTextArea may look like (on Windows):
|
133
|
+
|
134
|
+
<img src="https://i.imgur.com/CWVYskn.png" style="margin: 1em">
|
135
|
+
|
136
|
+
The <b>JTextArea class</b> provides a component that displays multiple lines of
|
137
|
+
text.
|
138
|
+
|
139
|
+
If only one line of input is required from the user, then a <b>text field</b>
|
140
|
+
should be used rather than JTextArea.
|
141
|
+
|
142
|
+
In <b>raw Java</b>, the code for instantiating a new JTextArea goes like this:
|
143
|
+
|
144
|
+
text_area = new JTextArea(5, 20);
|
145
|
+
JScrollPane scroll_pane = new JScrollPane(text_area);
|
146
|
+
text_area.setEditable(false);
|
147
|
+
|
148
|
+
In the code above, the API for JTextArea() follows this
|
149
|
+
signature: <b>JTextArea(int rows, int columns)</b> - so you first
|
150
|
+
pass in the number of rows, and then pass in the number of columns.
|
151
|
+
|
152
|
+
In Java, you can set the background colour to a colour of your choosing via:
|
153
|
+
|
154
|
+
import java.awt.Color;
|
155
|
+
Color color = new Color(255,0,0); /* This is red. */
|
156
|
+
text_area.setBackground(color);
|
157
|
+
|
158
|
+
The textarea is quite flexible. For instance, you can force it to
|
159
|
+
ignore newlines entered by the user, thus making it essentially
|
160
|
+
a single-line input entry:
|
161
|
+
|
162
|
+
textview = create_textarea
|
163
|
+
textview.getDocument.putProperty('filterNewlines', true)
|
164
|
+
|
165
|
+
As this is a bit annoying to remember, I added this method:
|
166
|
+
|
167
|
+
textview.filter_newlines
|
168
|
+
|
169
|
+
As always, you need to include SwingParadise::BaseModule for
|
170
|
+
this add-on functionality.
|
171
|
+
|
172
|
+
Most of the time you probably don't want this behaviour though.
|
173
|
+
|
174
|
+
To set to a different background colour, use something like this:
|
175
|
+
|
176
|
+
textview.setBackground(Color::GREEN)
|
177
|
+
|
178
|
+
Line-wrapping and wrap-style can also be set:
|
179
|
+
|
180
|
+
textview.setLineWrap(true)
|
181
|
+
textview.setWrapStyleWord(false)
|
182
|
+
|
183
|
+
## JComboBox - working with combo-boxes in Java swing and jruby
|
184
|
+
|
185
|
+
You can instantiate a new combo box via:
|
186
|
+
|
187
|
+
combo_box = JComboBox.new
|
188
|
+
|
189
|
+
Now, in order to fill it up, you can use something like this:
|
190
|
+
|
191
|
+
array = %w( apple bird cat dog eagle ferret )
|
192
|
+
array.each {|this_item|
|
193
|
+
combo_box.addItem(this_item)
|
194
|
+
}
|
195
|
+
|
196
|
+
So .addItem() can be used to add more elements to the combo-box.
|
197
|
+
|
198
|
+
As the above is a bit cumbersome, if you make use of
|
199
|
+
<b>SwingParadise::BaseModule</b>, you can use the following API
|
200
|
+
instead:
|
201
|
+
|
202
|
+
array = %w( apple bird cat dog eagle ferret )
|
203
|
+
combo_box(array) # So you can simply pass in the full Array here
|
204
|
+
|
205
|
+
To select a specific index, that is, a specific entry on that
|
206
|
+
combo box, you can use the method <b>.setSelectedIndex()</b>:
|
207
|
+
|
208
|
+
combo_box.setSelectedIndex(2) # For the third entry.
|
209
|
+
|
210
|
+
To query which index is the currently selected one on a
|
211
|
+
combo-box, use the method <b>.selected_index</b>, as in:
|
212
|
+
|
213
|
+
combo_box.selected_index
|
214
|
+
|
215
|
+
To obtain the selected entry, use <b>.selected_item</b>,
|
216
|
+
as in:
|
217
|
+
|
218
|
+
combo_box.selected_item
|
219
|
+
|
220
|
+
## Java::JavaAwtEvent::ActionEvent
|
221
|
+
|
222
|
+
Events in java can be found under <b>java.awt.events.*</b>.
|
223
|
+
|
224
|
+
<b>class Java::JavaAwtEvent::ActionEvent</b> is the base class for
|
225
|
+
when Java Swing fires an event, such as when the user changes the
|
226
|
+
content of a combo-box.
|
227
|
+
|
228
|
+
The syntax to use it, from <b>jruby</b>, goes like this:
|
229
|
+
|
230
|
+
widget.add_action_listener { |event|
|
231
|
+
}
|
232
|
+
|
233
|
+
So you designate a block variable; I recommend to consistently call
|
234
|
+
it <b>event</b>, as that should simplify things.
|
235
|
+
|
236
|
+
How can you find out the specific event?
|
237
|
+
|
238
|
+
One way goes via the method <b>.get_action_command()</b>,
|
239
|
+
such as in:
|
240
|
+
|
241
|
+
event.get_action_command
|
242
|
+
|
243
|
+
action_command = event.get_action_command
|
244
|
+
|
245
|
+
For the changed content of a combo-box, the result
|
246
|
+
would <b>comboBoxChanged</b>.
|
247
|
+
|
248
|
+
To respond to this, you can use the following snippet:
|
249
|
+
|
250
|
+
case event.get_action_command
|
251
|
+
when /comboBoxChanged/
|
252
|
+
end
|
253
|
+
|
254
|
+
I needed this functionality for a widget that, when the user changes
|
255
|
+
the combo-box content, another entry is also changed, reflecting the
|
256
|
+
currently selected entry there.
|
257
|
+
|
258
|
+
## Available colours
|
259
|
+
|
260
|
+
Just a simple listing of available colours in a java swing
|
261
|
+
application:
|
262
|
+
|
263
|
+
Color::RED
|
264
|
+
Color::BLUE
|
265
|
+
Color::GREEN
|
266
|
+
Color::BLACK
|
267
|
+
|
268
|
+
## Obtaining the height and width of a widget
|
269
|
+
|
270
|
+
Use .getBounds as in:
|
271
|
+
|
272
|
+
frame.getBounds()
|
273
|
+
height = r.height
|
274
|
+
width = r.width
|
275
|
+
|
276
|
+
## The GridLayout
|
277
|
+
|
278
|
+
A GridLayout in java-swing looks like this:
|
279
|
+
|
280
|
+
<img src="https://docs.oracle.com/javase/tutorial/figures/uiswing/layout/GridLayoutDemo.png" style="margin: 1em">
|
281
|
+
|
282
|
+
In other words: you arrange elements (widgets) in a 2D-like matrix. This
|
283
|
+
is also called <b>a grid of cells</b>. Each component in the grid
|
284
|
+
is <b>exactly</b> the same size.
|
285
|
+
|
286
|
+
To create a new GridLayout, in raw Java, use this:
|
287
|
+
|
288
|
+
/* API: GridLayout(int rows, int cols) */
|
289
|
+
GridLayout x = new GridLayout(3, 3); /* A 3x3 grid */
|
290
|
+
|
291
|
+
You can then add new elements to it via:
|
292
|
+
|
293
|
+
.add(new JButton("Button 1"));
|
294
|
+
.add(new JButton("Button 2"));
|
295
|
+
|
296
|
+
And so forth.
|
297
|
+
|
298
|
+
If you use SwingParadise::BaseModule then you can also make
|
299
|
+
use of the .create_grid() method.
|
300
|
+
|
301
|
+
grid = create_grid('2x2')
|
302
|
+
grid.add(button('Button 1'))
|
303
|
+
grid.add(button('Button 2'))
|
304
|
+
|
305
|
+
This should be equivalent to the above mentioned Java code.
|
306
|
+
|
307
|
+
## JCheckBox and checkboxes in Java swing
|
308
|
+
|
309
|
+
Let's first look at an image how checkboxes look in Java swing:
|
310
|
+
|
311
|
+
<img src="https://i.imgur.com/E5gugWY.png" style="margin: 1em">
|
312
|
+
|
313
|
+
Let's next have a look at how we <b>add checkboxes in raw Java swing</b>:
|
314
|
+
|
315
|
+
JPanel panel = new JPanel();
|
316
|
+
panel.add(label);
|
317
|
+
|
318
|
+
JCheckBox one = new JCheckBox("one");
|
319
|
+
JCheckBox two = new JCheckBox("two");
|
320
|
+
|
321
|
+
panel.add(one);
|
322
|
+
panel.add(two);
|
323
|
+
|
324
|
+
So, we make use of <b>JCheckBox</b>. A second argument can be passed,
|
325
|
+
to determine whether the check-box is checked or whether it is not:
|
326
|
+
|
327
|
+
JCheckBox.new("Foobar", true)
|
328
|
+
JCheckBox.new("Foobar", false)
|
329
|
+
|
330
|
+
To determine whether a JCheckBox is <b>checked</b> - aka selected, the
|
331
|
+
following method can be used:
|
332
|
+
|
333
|
+
checkbox.isSelected()
|
334
|
+
|
335
|
+
Or, if you use the swing_paradise gem, you can also use:
|
336
|
+
|
337
|
+
checkbox.is_selected?
|
338
|
+
|
339
|
+
To mark the checkbox as checked, use:
|
340
|
+
|
341
|
+
checkbox.setSelected(true)
|
342
|
+
|
343
|
+
## JFrame
|
344
|
+
|
345
|
+
To create a new frame, aka a new JFrame, from jruby, use:
|
346
|
+
|
347
|
+
frame = JFrame.new # This would be an untitled frame.
|
348
|
+
frame = JFrame.new("Frame Title") # And this would set the title to "Frame Title".
|
349
|
+
|
350
|
+
If you'd like to you could also use the full qualifier (full name),
|
351
|
+
which is:
|
352
|
+
|
353
|
+
frame = javax.swing.JFrame.new
|
354
|
+
# panel = Java::javax::swing::JFrame.new # This variant may also work, but is not as elegant as the one above.
|
355
|
+
|
356
|
+
However had, note that both variants shown above are more verbose, so
|
357
|
+
it may not be worth the extra time to type; nonetheless, should you
|
358
|
+
ever have a use case to scope specifically to a particular class,
|
359
|
+
you can preface it via <b>javax.swing</b> (or wherever else that
|
360
|
+
particular swing-class resides at).
|
361
|
+
|
362
|
+
To set a grid layout you can use the method called <b>.set_layout()</b>,
|
363
|
+
as seen in the following example:
|
364
|
+
|
365
|
+
frame.set_layout(
|
366
|
+
java.awt.GridLayout.new(2, 2, 2, 2)
|
367
|
+
)
|
368
|
+
|
369
|
+
This is especially useful for any 2D layouts.
|
370
|
+
|
371
|
+
To <b>exit a JFrame</b>, as the main pane, Java Swing usually
|
372
|
+
requires that you use something like this:
|
373
|
+
|
374
|
+
frame.setDefaultCloseOperation(JFrame::EXIT_ON_CLOSE)
|
375
|
+
|
376
|
+
I found this a bit cumbersome to type and difficult to
|
377
|
+
remember, so the SwingParadise::BaseModule allows you
|
378
|
+
to use this method instead:
|
379
|
+
|
380
|
+
default_close
|
381
|
+
|
382
|
+
This one is easier for me to remember, and less to type, too.
|
383
|
+
|
384
|
+
Note that you can not add a JFrame to another JFrame. I ran into
|
385
|
+
this issue in December 2023, so I had to note this down here.
|
386
|
+
|
387
|
+
The explanation I found stated this:
|
388
|
+
|
389
|
+
"JFrame is a <b>top level container</b> and as such it cannot
|
390
|
+
be <b>added</b> to any other container."
|
391
|
+
|
392
|
+
Typically a JFrame contains two parts: a space area on top for
|
393
|
+
the menu bar, and the content pane below the menu bar. Often
|
394
|
+
the menu bar is missing, though, so the content pane is
|
395
|
+
ultimately more important than the menu bar.
|
396
|
+
|
397
|
+
Further methods for the JFrame include these (as a sample):
|
398
|
+
|
399
|
+
.setVisible(boolean b)
|
400
|
+
.setTitle(String title)
|
401
|
+
.setSize(int width, int height)
|
402
|
+
.setLocation(int horizontal, int vertical)
|
403
|
+
.pack()
|
404
|
+
.setDefaultCloseOperation(int operation)
|
405
|
+
|
406
|
+
By default a JFrame is not visible, so we have to use:
|
407
|
+
|
408
|
+
frame.setVisible(true)
|
409
|
+
|
410
|
+
To make it visible.
|
411
|
+
|
412
|
+
You can designate the size of the main JFrame via .setSize():
|
413
|
+
|
414
|
+
.setSize(int width, int height)
|
415
|
+
.setSize(600, 420)
|
416
|
+
|
417
|
+
Note that calling the method .pack() will resize the frame so that
|
418
|
+
it tightly fits around components embedded into its content
|
419
|
+
pane.
|
420
|
+
|
421
|
+
To make the whole application quit when the close-action is
|
422
|
+
triggered, use:
|
423
|
+
|
424
|
+
frame.setDefaultCloseOperation(JFrame::EXIT_ON_CLOSE)
|
425
|
+
|
426
|
+
## JPanel
|
427
|
+
|
428
|
+
In raw jruby, you can create a new instance of JPanel by issuing
|
429
|
+
this:
|
430
|
+
|
431
|
+
panel = JPanel.new
|
432
|
+
|
433
|
+
You can then assign different layouts to be used. For instance,
|
434
|
+
to keep the panel left-aligned, meaning you will see new elements
|
435
|
+
all appear in a linear left-to-right fashion, you can use a
|
436
|
+
FlowLayout like this:
|
437
|
+
|
438
|
+
panel.layout = FlowLayout.new(FlowLayout::LEFT)
|
439
|
+
|
440
|
+
This would look similar to the following image:
|
441
|
+
|
442
|
+
<img src="https://i.imgur.com/Yr7t7hJ.png" style="margin: 1em">
|
443
|
+
|
444
|
+
This seems quite convenient and easy to use, so the swing_paradise
|
445
|
+
gem tries to make this even easier. Here is the proposed API
|
446
|
+
for the above two lines:
|
447
|
+
|
448
|
+
panel = create_panel { :left }
|
449
|
+
|
450
|
+
This is <b>exactly</b> the same as:
|
451
|
+
|
452
|
+
panel = JPanel.new
|
453
|
+
panel.layout = FlowLayout.new(FlowLayout::LEFT)
|
454
|
+
|
455
|
+
Note that FlowLayout is the default layout manager for
|
456
|
+
every JPanel. The components will be laid out in a single
|
457
|
+
row one after the other.
|
458
|
+
|
459
|
+
Here is another picture how this would look:
|
460
|
+
|
461
|
+
<img src="https://www.guru99.com/images/uploads/2012/06/java-flow-layout-manager.jpg" style="margin: 1em">
|
462
|
+
|
463
|
+
JPanel can also be used to draw onto, via the method called
|
464
|
+
<b>paintComponent</b>. Whenever the GUI is resized, this
|
465
|
+
method will be automatically called.
|
466
|
+
|
467
|
+
Take note that .paintComponent() should not be called directly;
|
468
|
+
instead, use the .repaint() method in the event you wish to
|
469
|
+
draw onto the panel.
|
470
|
+
|
471
|
+
The API for paintComponent in raw Java Swing goes as follows:
|
472
|
+
|
473
|
+
public void paintComponent(Graphics g)
|
474
|
+
|
475
|
+
Graphics here belongs to AWT.
|
476
|
+
|
477
|
+
## Working with colours in SWING and jruby
|
478
|
+
|
479
|
+
The generic way to handle colours in java-swing goes like this:
|
480
|
+
|
481
|
+
import java.awt.Color;
|
482
|
+
Color color = new Color(255,0,0); /* This is red. */
|
483
|
+
|
484
|
+
## Using no specific layout
|
485
|
+
|
486
|
+
Via:
|
487
|
+
|
488
|
+
frame.setLayout(nil)
|
489
|
+
|
490
|
+
You can avoid using any specific layout.
|
491
|
+
|
492
|
+
## GridBagLayout
|
493
|
+
|
494
|
+
GridBagLayout aligns components by placing them within a grid
|
495
|
+
of cells, allowing components to span more than one cell.
|
496
|
+
|
497
|
+
The following image shows how this may look like:
|
498
|
+
|
499
|
+
<img src="https://www.guru99.com/images/uploads/2012/06/java-grid-bag-layout.jpg" style="margin: 1em">
|
500
|
+
|
501
|
+
## JButton and buttons in swing
|
502
|
+
|
503
|
+
Java-Swing calls a button JButton. JButton is not the only button
|
504
|
+
available in Java-Swing: we can also use JCheckBox, JRadioButton,
|
505
|
+
JMenuItem, JCheckBoxMenuItem, JRadioButtonMenuItem or JToggleButton.
|
506
|
+
|
507
|
+
An example for a widget that uses three buttons will be shown
|
508
|
+
next (on Windows XP):
|
509
|
+
|
510
|
+
<img src="https://i.imgur.com/xBvl7Fq.png" style="margin: 1em">
|
511
|
+
|
512
|
+
You can add an icon to a button in swing.
|
513
|
+
|
514
|
+
First, let's show the Java version for this:
|
515
|
+
|
516
|
+
JButton button = new JButton(new ImageIcon("foobar.jpg"));
|
517
|
+
|
518
|
+
<b>ImageIcon</b> can be used for <b>pixel graphics</b>.
|
519
|
+
|
520
|
+
Next, the equivalent ruby code:
|
521
|
+
|
522
|
+
button = JButton.new(ImageIcon.new('foobar.jpg'))
|
523
|
+
|
524
|
+
If you use the swing_paradise gem, the above can be simplified a
|
525
|
+
little bit further:
|
526
|
+
|
527
|
+
button = button(ImageIcon.new('foobar.jpg'))
|
528
|
+
|
529
|
+
I may extend this API to simplify this further, such as
|
530
|
+
<b>button_with_image()</b> or something like that. In fact, in
|
531
|
+
February 2024 this was indeed extended: if you use SwingParadise::BaseModule
|
532
|
+
then you can use the method called <b>button_with_image()</b> to add
|
533
|
+
a button with an image. There are two ways to call this: one is by simply
|
534
|
+
passing the path to a local image. The second way is to also pass an
|
535
|
+
optional text that is displayed next to the image.
|
536
|
+
|
537
|
+
To change the background colour for a button, use the following API:
|
538
|
+
|
539
|
+
button.setBackground(Color.green) # This would make it green.
|
540
|
+
|
541
|
+
To let a JButton respond to on-click events, one has to
|
542
|
+
attach a listener, via the following API:
|
543
|
+
|
544
|
+
button.addActionListener(ActionListener listener)
|
545
|
+
|
546
|
+
In jruby this is implemented via a block form, that is via:
|
547
|
+
|
548
|
+
{
|
549
|
+
}
|
550
|
+
|
551
|
+
To <b>focus</b> on a button, use:
|
552
|
+
|
553
|
+
button.requestFocusInWindow();
|
554
|
+
|
555
|
+
To obtain the text (label) if a JButton, use the method
|
556
|
+
<b>.getText</b>.
|
557
|
+
|
558
|
+
If you make use of the swing-paradise gem then you can
|
559
|
+
simply call the .on_clicked {} method on a button,
|
560
|
+
such as via:
|
561
|
+
|
562
|
+
button = JButton.new('Please click me.')
|
563
|
+
button.on_clicked {
|
564
|
+
puts 'I was clicked.'
|
565
|
+
}
|
566
|
+
|
567
|
+
There is, interestingly enough, another way possible for
|
568
|
+
achieving the above, in that you specify a distinct
|
569
|
+
class that will be invoked when the button is called.
|
570
|
+
|
571
|
+
So, the code for the button at hand would then look like
|
572
|
+
this:
|
573
|
+
|
574
|
+
button = JButton.new('Please click me.')
|
575
|
+
button.addActionListener(ClickAction.new)
|
576
|
+
|
577
|
+
And you also need to define class ClickAction, like this:
|
578
|
+
|
579
|
+
class ClickAction
|
580
|
+
|
581
|
+
include ActionListener
|
582
|
+
|
583
|
+
def actionPerformed(event) # you can also use: "def action_performed" instead
|
584
|
+
puts 'This time the button was called from within clas ClickAction.'
|
585
|
+
end
|
586
|
+
|
587
|
+
end
|
588
|
+
|
589
|
+
This solution is not quite as convenient as the .on_clicked {} variant,
|
590
|
+
but perhaps there may be times when this is needed, so it is mentioned
|
591
|
+
here in the documentation. Personally I will continue to prefer
|
592
|
+
the <b>.on_clicked {} method variant</b> though - my brain has an
|
593
|
+
easier time remembering that variant.
|
594
|
+
|
595
|
+
You can also use tooltips for a button.
|
596
|
+
|
597
|
+
Examples:
|
598
|
+
|
599
|
+
button.setToolTipText('Press Alt+H to trigger this button.')
|
600
|
+
button.hint = 'Press Alt+H to trigger this button.'
|
601
|
+
|
602
|
+
If you need to obtain the tooltip-text, you can use:
|
603
|
+
|
604
|
+
puts button.getToolTipText
|
605
|
+
|
606
|
+
The location where the tooltip will be shown, can be obtained via:
|
607
|
+
|
608
|
+
puts button.getToolTipLocation(MouseEvent)
|
609
|
+
|
610
|
+
If you want to make the button have a flat-style look, use:
|
611
|
+
|
612
|
+
button.setBorderPainted(false)
|
613
|
+
button.setFocusPainted(false)
|
614
|
+
button.setContentAreaFilled(false)
|
615
|
+
|
616
|
+
The full <b>API documentation</b> for JButton can be found here:
|
617
|
+
|
618
|
+
https://docs.oracle.com/javase/8/docs/api/javax/swing/JButton.html
|
619
|
+
|
620
|
+
## JLabel and text
|
621
|
+
|
622
|
+
You can right-align a JLabel widget via:
|
623
|
+
|
624
|
+
JLabel(String text, int horizontalAlignment)
|
625
|
+
JLabel label = new JLabel("Telephone", SwingConstants.RIGHT);
|
626
|
+
|
627
|
+
In jruby-swing this would look like this:
|
628
|
+
|
629
|
+
label = JLabel.new('Telephone', SwingConstants::RIGHT)
|
630
|
+
|
631
|
+
After you created a label, you can call several methods on it.
|
632
|
+
|
633
|
+
For instance, to change the foreground colour, use:
|
634
|
+
|
635
|
+
label.setForeground(Color c)
|
636
|
+
|
637
|
+
For the background colour use:
|
638
|
+
|
639
|
+
label.setBackground(Color c)
|
640
|
+
|
641
|
+
You can also set the label to be opaque, via:
|
642
|
+
|
643
|
+
label.setOpaque(boolean b)
|
644
|
+
label.setOpaque(true)
|
645
|
+
label.setOpaque(false)
|
646
|
+
|
647
|
+
If true is passed to the latter method then the label
|
648
|
+
will be transparent; if it is false, then the label will be
|
649
|
+
non-transparent.
|
650
|
+
|
651
|
+
Interestingly you can also use HTML markup in a JLabel. The
|
652
|
+
following example shows how this can be done:
|
653
|
+
|
654
|
+
label = JLabel.new("<html><span>This is your text</span></html>");
|
655
|
+
|
656
|
+
## JColorChooser (javax.swing.colorchooser)
|
657
|
+
|
658
|
+
<b>JColorChooser</b> can be used to pick a certain colours.
|
659
|
+
|
660
|
+
Let's have a look at an image, to find out how this may actually look:
|
661
|
+
|
662
|
+
<img src="https://docs.oracle.com/javase/tutorial/figures/uiswing/components/ColorChooserDemoMetal.png" style="margin: 1em">
|
663
|
+
|
664
|
+
In raw Java, we would use the following to create a new JColorChooser instance:
|
665
|
+
|
666
|
+
banner = new JLabel("Some text.", JLabel.CENTER);
|
667
|
+
banner.setForeground(Color.yellow);
|
668
|
+
jcolorchooser = new JColorChooser(banner.getForeground());
|
669
|
+
add(jcolorchooser, BorderLayout.PAGE_END);
|
670
|
+
|
671
|
+
If you want to create a dialog, for the user to make a choice, you can
|
672
|
+
use the <b>.createDialog()</b> method:
|
673
|
+
|
674
|
+
jcolorchooser.createDialog()
|
675
|
+
jcolorchooser.createDialog # Remember, in ruby you can omit the ().
|
676
|
+
|
677
|
+
## JOptionPane
|
678
|
+
|
679
|
+
<b>JOptionPane</b> can be used to ask the user about confirmation about
|
680
|
+
certain actions, such as <b>Do you really want to delete this
|
681
|
+
file?</b>.
|
682
|
+
|
683
|
+
## BorderLayout
|
684
|
+
|
685
|
+
A BorderLayout places components in up to five areas:
|
686
|
+
|
687
|
+
<b>top</b>, <b>bottom</b>, <b>left</b>, <b>right</b>,
|
688
|
+
and <b>center</b>.
|
689
|
+
|
690
|
+
It is <b>the default layout manager</b> for every java JFrame.
|
691
|
+
|
692
|
+
It looks like this:
|
693
|
+
|
694
|
+
<img src="https://www.guru99.com/images/uploads/2012/06/java-border-layout-manager.jpg" style="margin: 1em">
|
695
|
+
|
696
|
+
## BorderFactory
|
697
|
+
|
698
|
+
BorderFactory can be used to create a frame with a label.
|
699
|
+
|
700
|
+
Usage example in jruby:
|
701
|
+
|
702
|
+
_ = BorderFactory.createTitledBorder(' Shell ')
|
703
|
+
_.setTitleFont(Font.new('Tahoma', Font::PLAIN, 50)) # This here can be used to set the font that is used.
|
704
|
+
|
705
|
+
Many variants exist for BorderFactory.
|
706
|
+
|
707
|
+
For instance, to set a matte-border, you can use:
|
708
|
+
|
709
|
+
ImageIcon icon = createImageIcon("images/wavy.gif", "wavy-line border icon"); # 20x22
|
710
|
+
BorderFactory.createMatteBorder(-1, -1, -1, -1, icon));
|
711
|
+
|
712
|
+
## ImageIcon
|
713
|
+
|
714
|
+
The name icon is a slight misnomer for this class, as it can also deal with
|
715
|
+
large images.
|
716
|
+
|
717
|
+
As argument to this class the path to a local filename should be supplied,
|
718
|
+
as a String.
|
719
|
+
|
720
|
+
Example:
|
721
|
+
|
722
|
+
image_icon = ImageIcon.new('/tmp/foobar.png')
|
723
|
+
|
724
|
+
You can also supply an URL instead of a String to a local path.
|
725
|
+
|
726
|
+
You can query the height and width of this image via:
|
727
|
+
|
728
|
+
image_icon.getImageHeight() # returns the image height, in n pixels.
|
729
|
+
image_icon.getImageWidth() # returns the image width, in n pixels.
|
730
|
+
|
731
|
+
Keep in mind that instances of class ImageIcon are non-graphical components.
|
732
|
+
This means that they have to be put into some container, such as
|
733
|
+
JLabel, e. g.:
|
734
|
+
|
735
|
+
JLabel.new(ImageIcon picture)
|
736
|
+
JLabel.new(image_icon) # re-using the variable defined above ^^^
|
737
|
+
|
738
|
+
You can also load images <b>asynchronously</b>. This can be done via
|
739
|
+
<b>Toolkit</b> from the AWT library.
|
740
|
+
|
741
|
+
Example in Java-Swing:
|
742
|
+
|
743
|
+
Image picture = Toolkit.getDefaultToolkit.getImage(String filename);
|
744
|
+
Image picture = Toolkit.getDefaultToolkit.getImage(String url);
|
745
|
+
|
746
|
+
In jruby-Swing:
|
747
|
+
|
748
|
+
picture = Toolkit.getDefaultToolkit.getImage(String filename)
|
749
|
+
picture = Toolkit.getDefaultToolkit.getImage('foobar.png')
|
750
|
+
|
751
|
+
If you need to load multiple images, possibly distributed on
|
752
|
+
various servers on the internet, you may want to make use
|
753
|
+
of class <b>MediaTracker</b>, which is part of the AWT
|
754
|
+
library. MediaTracker can monitor the loading process of many
|
755
|
+
images. Interestingly MediaTracker makes use of an id,
|
756
|
+
such as via the following method call:
|
757
|
+
|
758
|
+
.addImage(Image picture, int id)
|
759
|
+
|
760
|
+
## Java::JavaAwtEvent::ActionEvent and events in general
|
761
|
+
|
762
|
+
An event in a SWING application is typically of class
|
763
|
+
<b>Java::JavaAwtEvent::ActionEvent</b>, as far as Ruby is
|
764
|
+
concerned.
|
765
|
+
|
766
|
+
## JTextField
|
767
|
+
|
768
|
+
<b>JTextField</b> is a lightweight component that allows the
|
769
|
+
editing of a single line of text.
|
770
|
+
|
771
|
+
A <b>JTextField</b> - also known as an <b>entry</b> - is
|
772
|
+
a <b>subclass</b> of the <b>JTextComponent</b> class.
|
773
|
+
|
774
|
+
<b>Padding</b> can be added to a JTextField via the method
|
775
|
+
.setMargin() and passing proper insets to it.
|
776
|
+
|
777
|
+
Example:
|
778
|
+
|
779
|
+
setMargin(Insets m)
|
780
|
+
|
781
|
+
text_field = new JTextField("A text field example.");
|
782
|
+
text_field.setMargin(new Insets(10, 10, 10, 10));
|
783
|
+
|
784
|
+
JTextField can also be instantiated in this manner:
|
785
|
+
|
786
|
+
JTextField(String text, int columns)
|
787
|
+
|
788
|
+
So the second argument means how many columns this entry
|
789
|
+
should have.
|
790
|
+
|
791
|
+
Documentation for JTextField can be seen here:
|
792
|
+
|
793
|
+
https://docs.oracle.com/javase/8/docs/api/javax/swing/JTextField.html
|
794
|
+
|
795
|
+
## Textfields in Java-SWING via JFormattedTextField
|
796
|
+
|
797
|
+
If you have a need to hide certain input elements, such as
|
798
|
+
via a user-password, you could use the following code, in
|
799
|
+
Java-SWING:
|
800
|
+
|
801
|
+
import javax.swing.text.MaskFormatter;
|
802
|
+
MaskFormatter mask_formatter = new MaskFormatter("###-##-####");
|
803
|
+
|
804
|
+
JFormattedTextField has three preconfigured format types:
|
805
|
+
|
806
|
+
numbers
|
807
|
+
dates
|
808
|
+
strings
|
809
|
+
|
810
|
+
## JScrollBar
|
811
|
+
|
812
|
+
First, before this subsection explains some things about a <b>JScollBar</b>, let us state
|
813
|
+
that in many cases a developer may want to use <b>JScrollPane</b> instead.
|
814
|
+
|
815
|
+
<b>JScrollBar</b> is used to create a scrolling widget. This refers to
|
816
|
+
a widget that has a vertical and a horizontal bar - both of which
|
817
|
+
can be optional - allowing the mouse pointer to click and drag
|
818
|
+
the child-widget, to the right, left, up or down. This is especially
|
819
|
+
useful for a text-buffer widget, where regular text is displayed
|
820
|
+
that overflows to the right hand side (or somewhere else).
|
821
|
+
|
822
|
+
The following image shows how this looked on Windows XP:
|
823
|
+
|
824
|
+
<img src="https://i.imgur.com/6AEwGR7.png" style="margin: 1em">
|
825
|
+
|
826
|
+
So, to summarize: the scroll bar is used to determine the
|
827
|
+
viewing area of the component (the child-widget).
|
828
|
+
|
829
|
+
The scroll bar involves a knob that can be adjusted by the
|
830
|
+
user. This is meant for use with the mouse pointer.
|
831
|
+
|
832
|
+
How to create a new instance for a scroll bar in Java?
|
833
|
+
|
834
|
+
The following code example (<b>ScrollBarExample.java</b>) shows this:
|
835
|
+
|
836
|
+
import javax.swing.*;
|
837
|
+
import java.awt.*;
|
838
|
+
|
839
|
+
class ScrollBarExample {
|
840
|
+
|
841
|
+
public static void main(String[] args) {
|
842
|
+
final JFrame frame = new JFrame("ScrollBarExample");
|
843
|
+
|
844
|
+
JScrollBar scrollBarH = new JScrollBar(JScrollBar.HORIZONTAL, 30, 20, 0, 500);
|
845
|
+
JScrollBar scrollBarV = new JScrollBar(JScrollBar.VERTICAL, 30, 40, 0, 500);
|
846
|
+
|
847
|
+
frame.setSize(300,200);
|
848
|
+
frame.getContentPane().add(scrollBarH, BorderLayout.SOUTH);
|
849
|
+
frame.getContentPane().add(scrollBarV, BorderLayout.EAST);
|
850
|
+
frame.setVisible(true);
|
851
|
+
}
|
852
|
+
|
853
|
+
}
|
854
|
+
|
855
|
+
Which relevant properties does the scroll bar have?
|
856
|
+
|
857
|
+
orientation: This indicates a horizontal or a vertical Scrollbar.
|
858
|
+
value: This indicates the model's current value. The upper
|
859
|
+
limit on the model's value is maximum - extent and the
|
860
|
+
lower limit is minimum.
|
861
|
+
extent: This indicates the width of the knob of the scrollbar.
|
862
|
+
minimum: This indicates the minimum width of the track on which the scrollbar moves.
|
863
|
+
maximum: This indicates the maximum width of the track on which the scrollbar moves.
|
864
|
+
|
865
|
+
If you instantiate a new scrollbar in jruby, using this syntax:
|
866
|
+
|
867
|
+
JScrollBar.new
|
868
|
+
|
869
|
+
then the following initial values are used:
|
870
|
+
|
871
|
+
minimum = 0
|
872
|
+
maximum = 100
|
873
|
+
value = 0
|
874
|
+
extent = 10
|
875
|
+
|
876
|
+
The first argument is orientation (as Integer).
|
877
|
+
|
878
|
+
Example:
|
879
|
+
|
880
|
+
JScrollBar.new(int orientation)
|
881
|
+
JScrollBar.new(1)
|
882
|
+
|
883
|
+
In other words: you can use this to determine the orientation
|
884
|
+
of the scrollbar. The value <b>orientation=0</b> means we will
|
885
|
+
make use of a horizontal scroll bar, whereas the value
|
886
|
+
<b>orientation=1</b> means we will get a vertical scroll bar.
|
887
|
+
Most commonly a horizontal scroll bar is used.
|
888
|
+
|
889
|
+
The most commonly used methods of the JScrollBar class are
|
890
|
+
as follows:
|
891
|
+
|
892
|
+
- The addAdjustmentListener(AdjustmentListener l) method adds a
|
893
|
+
listener to the specified JScrollBar instance. The listener
|
894
|
+
will be notified every time a change to the model of the
|
895
|
+
scroll bar is detected.
|
896
|
+
- The getModel() method returns the model of the scroll bar.
|
897
|
+
- The getMaximum() method returns the maximum value (maximum -
|
898
|
+
extent) of the scrollbar.
|
899
|
+
- The getMinimum() method returns the minimum value of the scroll
|
900
|
+
bar.
|
901
|
+
- The getOrientation() method returns the orientation of the
|
902
|
+
scroll bar.
|
903
|
+
- The getValue() method returns the scrollbar’s value.
|
904
|
+
- The setMaximum() method is used to set the maximum value
|
905
|
+
of the scrollbar.
|
906
|
+
- The setMinimum() method is used to set the minimum value of the scroll bar.
|
907
|
+
- The setOrientation() method is used to set the orientation of the scroll bar.
|
908
|
+
- The setValue() method is used to set the scrollbar’s value.
|
909
|
+
|
910
|
+
If you want to set inner padding, you have to make use of
|
911
|
+
a border:
|
912
|
+
|
913
|
+
scroll_bar.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10))
|
914
|
+
|
915
|
+
## Checking for the escape-key being pressed
|
916
|
+
|
917
|
+
In raw Java SWING, we can use the following line of code to check whether
|
918
|
+
the user has pressed the escape-key:
|
919
|
+
|
920
|
+
if (event.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
921
|
+
}
|
922
|
+
|
923
|
+
In jruby SWING, this would be:
|
924
|
+
|
925
|
+
if (event.getKeyCode() == KeyEvent::VK_ESCAPE) {
|
926
|
+
}
|
927
|
+
|
928
|
+
Note that <b>KeyEvent::VK_ESCAPE</b> returns a number; in this case
|
929
|
+
that number is <b>27</b>.
|
930
|
+
|
931
|
+
## The Graphics class
|
932
|
+
|
933
|
+
Available methods include:
|
934
|
+
|
935
|
+
drawLine(int xstart, int ystart, int xend, int yend)
|
936
|
+
drawRect(int xleft, int ytop, int width, int height)
|
937
|
+
drawOval(int xleft, int ytop, int width, int height)
|
938
|
+
drawString(String text, int xleft, int ybottom)
|
939
|
+
fillRect(int xleft, int ytop, int width, int height)
|
940
|
+
fillOval(int xleft, int ytop, int width, int height)
|
941
|
+
setColor(Color col)
|
942
|
+
|
943
|
+
All these int-arguments refer to <b>pixels</b>.
|
944
|
+
|
945
|
+
<b>.drawLine(xstart,ystart,xend,yend)</b> draws a line segment
|
946
|
+
between the points with coordinates (xstart, ystart) and
|
947
|
+
(xend, yend).
|
948
|
+
|
949
|
+
Note that .setColor(col) sets the colour of the drawing to col.
|
950
|
+
This colour is used until the setColor command is used again.
|
951
|
+
|
952
|
+
## The mouse and mouse-events
|
953
|
+
|
954
|
+
A mouse event in jruby is of class <b>Java::JavaAwtEvent::MouseEvent</b>.
|
955
|
+
|
956
|
+
In Java-Swing two interfaces process mouse events:
|
957
|
+
|
958
|
+
1) MouseListener
|
959
|
+
2) MouseMotionListener
|
960
|
+
|
961
|
+
Note that key listeners react to key strokes (aka key press events).
|
962
|
+
|
963
|
+
## JScrollPane
|
964
|
+
|
965
|
+
First, let's have a look how a JScrollPane may look like:
|
966
|
+
|
967
|
+
<img src="https://i.imgur.com/sGd0NN6.png" style="margin: 1em">
|
968
|
+
|
969
|
+
JScrollPane is the primary widget to be used when scrolling
|
970
|
+
should be used (in Swing).
|
971
|
+
|
972
|
+
Next, let's look at a raw Java example for how to work with a <b>JScrollPane</b>:
|
973
|
+
|
974
|
+
import java.awt.FlowLayout;
|
975
|
+
import javax.swing.JFrame;
|
976
|
+
import javax.swing.JScrollPane; /* This is where it resides. */
|
977
|
+
import javax.swing.JtextArea;
|
978
|
+
|
979
|
+
public class JScrollPaneExample {
|
980
|
+
private static final long serialVersionUID = 1L;
|
981
|
+
|
982
|
+
private static void createAndShowGUI() {
|
983
|
+
|
984
|
+
// Create and set up the window.
|
985
|
+
final JFrame frame = new JFrame("Scroll Pane Example");
|
986
|
+
|
987
|
+
// Display the window.
|
988
|
+
frame.setSize(500, 500);
|
989
|
+
frame.setVisible(true);
|
990
|
+
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
991
|
+
|
992
|
+
// set flow layout for the frame
|
993
|
+
frame.getContentPane().setLayout(new FlowLayout());
|
994
|
+
|
995
|
+
JTextArea textArea = new JTextArea(20, 20);
|
996
|
+
JScrollPane scrollableTextArea = new JScrollPane(textArea);
|
997
|
+
|
998
|
+
scrollableTextArea.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
|
999
|
+
scrollableTextArea.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
|
1000
|
+
|
1001
|
+
frame.getContentPane().add(scrollableTextArea);
|
1002
|
+
}
|
1003
|
+
public static void main(String[] args) {
|
1004
|
+
|
1005
|
+
javax.swing.SwingUtilities.invokeLater(new Runnable() {
|
1006
|
+
public void run() {
|
1007
|
+
createAndShowGUI();
|
1008
|
+
}
|
1009
|
+
});
|
1010
|
+
}
|
1011
|
+
}
|
1012
|
+
|
1013
|
+
In jruby this may look like so:
|
1014
|
+
|
1015
|
+
text_area = JTextArea.new(20, 20)
|
1016
|
+
scrollable_text_area = JScrollPane.new(text_area) # Add the scroll-pane here.
|
1017
|
+
scrollable_text_area.setHorizontalScrollBarPolicy(JScrollPane::HORIZONTAL_SCROLLBAR_ALWAYS)
|
1018
|
+
scrollable_text_area.setVerticalScrollBarPolicy(JScrollPane::VERTICAL_SCROLLBAR_ALWAYS)
|
1019
|
+
|
1020
|
+
In other words: you pass the widget that you want to see scroll-bars for,
|
1021
|
+
into JScrollPane.new() - in that case, the variable text_area.
|
1022
|
+
|
1023
|
+
The viewport that you see will display the content of the JTextArea then.
|
1024
|
+
|
1025
|
+
If the whole component fits into the viewport then the default behaviour is
|
1026
|
+
that the scroll bars disappear. This behaviour can be changed, though, via
|
1027
|
+
the horizontal and vertical policy.
|
1028
|
+
|
1029
|
+
## Using mnemonics for JButton
|
1030
|
+
|
1031
|
+
You can use shortcut-keys, aka mnemonics, for buttons.
|
1032
|
+
|
1033
|
+
This is done in general via the method called <b>.setMnemonic()</b>.
|
1034
|
+
|
1035
|
+
Example for this:
|
1036
|
+
|
1037
|
+
button.setMnemonic(KeyEvent::VK_H)
|
1038
|
+
|
1039
|
+
VK_H means Alt+H. Alt here refers to the Alt-key. H is simply the letter
|
1040
|
+
H on the keyboard, so this means "press the alt-key as well as the h
|
1041
|
+
key".
|
1042
|
+
|
1043
|
+
If you instead want to enable Akt+H, use:
|
1044
|
+
|
1045
|
+
button.setMnemonic(KeyEvent::VK_A)
|
1046
|
+
|
1047
|
+
You can also use numbers instead. For instance:
|
1048
|
+
|
1049
|
+
button.setMnemonic(KeyEvent::VK_1)
|
1050
|
+
|
1051
|
+
This would allow you to respond to "Alt+1" key combinations. You can
|
1052
|
+
find examples related to this in the file at <b>examples/017_button_example.rb</b>.
|
1053
|
+
That file will, in the long run, contain all useful button-related
|
1054
|
+
activities that may be useful when designing applications via jruby-SWING.
|
1055
|
+
|
1056
|
+
As I find this a bit cumbersome to remember (I can't remember VK_1 or
|
1057
|
+
similar crypt names), I decided to add an API that simplifies this.
|
1058
|
+
|
1059
|
+
Usage example:
|
1060
|
+
|
1061
|
+
button.keycombo('Alt+1') # respond to alt+1
|
1062
|
+
button.keycombo('Alt+W') # respond to alt+W
|
1063
|
+
|
1064
|
+
Note that this currently (<b>January 2024</b>) only works for Alt-key
|
1065
|
+
combinations. At a later time I may extend this for more key-combinations.
|
1066
|
+
|
1067
|
+
## Working with JTable
|
1068
|
+
|
1069
|
+
A new table can be created via:
|
1070
|
+
|
1071
|
+
JTable(int rows, int cols): Creates a table of size rows * cols.
|
1072
|
+
|
1073
|
+
Like a table with (2, 3), 2 rows, and 3 columns.
|
1074
|
+
|
1075
|
+
You can also simplify it a bit, by using
|
1076
|
+
<b>javax.swing.table.DefaultTableModel</b> via:
|
1077
|
+
|
1078
|
+
m = javax.swing.table.DefaultTableModel.new
|
1079
|
+
m.add_column("id")
|
1080
|
+
m.add_column("name")
|
1081
|
+
m.add_row(['1', "jimmy"].to_java)
|
1082
|
+
m.add_row(['2', "robert"].to_java)
|
1083
|
+
|
1084
|
+
table = JTable.new(m)
|
1085
|
+
# The fulle qualifier for JTable is javax.swing.JTable, by the way.
|
1086
|
+
|
1087
|
+
You can add java-specific objects, such as a vector, via:
|
1088
|
+
|
1089
|
+
m.add_row java.util.Vector.new('"ト', 'あ', 'い'])
|
1090
|
+
|
1091
|
+
You can also pass the columns by calling DefaultTableModel.new,
|
1092
|
+
like this:
|
1093
|
+
|
1094
|
+
m = DefaultTableModel.new(nil, ["No.", "Name", "Path"].to_java)
|
1095
|
+
|
1096
|
+
The <b>API documentation</b> for JTable can be found here:
|
1097
|
+
|
1098
|
+
https://docs.oracle.com/javase/8/docs/api/javax/swing/JTable.html
|
1099
|
+
|
1100
|
+
## Converting an Array into Java::JavaLang:Object:
|
1101
|
+
|
1102
|
+
This can be done by calling .to_java.
|
1103
|
+
|
1104
|
+
Example for this:
|
1105
|
+
|
1106
|
+
pp ["1", "jimmy"].to_java # => #<Java::JavaLang::Object[2]: ["1", "jimmy"]>
|
1107
|
+
|
1108
|
+
## JEditorPane()
|
1109
|
+
|
1110
|
+
<b>JEditorPane()</b> can be used to <b>display text via java-swing</b>.
|
1111
|
+
|
1112
|
+
Let's have a look at an image, how this may look:
|
1113
|
+
|
1114
|
+
<img src="https://i.imgur.com/aVioB68.png" style="margin: 1em">
|
1115
|
+
|
1116
|
+
If you need to obtain the current text stored in a JEditorPane,
|
1117
|
+
you can use the method called <b>.getText()</b>.
|
1118
|
+
|
1119
|
+
## JComponent
|
1120
|
+
|
1121
|
+
Every <b>JComponent</b> can have one or more <b>borders</b>.
|
1122
|
+
|
1123
|
+
You can put a border around a JComponent. This is done via
|
1124
|
+
the <b>.setBorder()</b> method.
|
1125
|
+
|
1126
|
+
This method is usually combined with the <b>BorderFactory class</b>.
|
1127
|
+
|
1128
|
+
In raw Java swing, the code would look like this:
|
1129
|
+
|
1130
|
+
JPanel pane = new JPanel();
|
1131
|
+
pane.setBorder(BorderFactory.createLineBorder(Color.black));
|
1132
|
+
|
1133
|
+
## javax.swing.border
|
1134
|
+
|
1135
|
+
This subsection may eventually contain some information about
|
1136
|
+
borders in java-swing applications.
|
1137
|
+
|
1138
|
+
## JTextPane
|
1139
|
+
|
1140
|
+
<b>JTextPane</b> can be used to render HTML content.
|
1141
|
+
|
1142
|
+
The full scope of JTextPane is <b>javax.swing.JTextPane</b>.
|
1143
|
+
|
1144
|
+
## Creating a MenuBar via JMenu
|
1145
|
+
|
1146
|
+
First, let's look at how a Menu (JMenu) looks in Java-Swing:
|
1147
|
+
|
1148
|
+
<img src="https://i.imgur.com/PNlkIfK.png" style="margin: 1em">
|
1149
|
+
|
1150
|
+
The primary menu bar is called <b>JMenuBar</b> in Java-Swing.
|
1151
|
+
|
1152
|
+
To then create a menu, in raw Java-Swing, the following code
|
1153
|
+
could be used:
|
1154
|
+
|
1155
|
+
JMenuBar menu_bar = new JMenuBar(); # Create a new menubar here.
|
1156
|
+
JMenu m1 = new JMenu("FILE");
|
1157
|
+
menu_bar.add(m1);
|
1158
|
+
JMenu m2 = new JMenu("Help");
|
1159
|
+
menu_bar.add(m2);
|
1160
|
+
|
1161
|
+
Or in jruby code:
|
1162
|
+
|
1163
|
+
menu_bar = JMenuBar.new
|
1164
|
+
m1 = JMenu.new("FILE")
|
1165
|
+
menu_bar.add(m1)
|
1166
|
+
m2 = JMenu.new("Help")
|
1167
|
+
menu_bar.add(m2)
|
1168
|
+
|
1169
|
+
If you use the swing_paradise gem then you can also use <<
|
1170
|
+
rather than .add(). Example:
|
1171
|
+
|
1172
|
+
menu_bar << m1
|
1173
|
+
menu_bar << m2
|
1174
|
+
|
1175
|
+
This is a bit shorter to type.
|
1176
|
+
|
1177
|
+
Take note that the constructor for <b>JMenu</b> is this:
|
1178
|
+
|
1179
|
+
JMenu(String menuTitle);
|
1180
|
+
JMenu.new(menuTitle) # This for jruby.
|
1181
|
+
|
1182
|
+
So the name of the menu entry should be given, as a <b>String</b>.
|
1183
|
+
|
1184
|
+
You can also attach mnemonics to this, such as via:
|
1185
|
+
|
1186
|
+
menu = JMenu.new('A Menu')
|
1187
|
+
menu.setMnemonic(KeyEvent.VK_A)
|
1188
|
+
|
1189
|
+
As can be seen from the above code, we first need to create a new
|
1190
|
+
<b>JMenuBar</b> - this is the first step.
|
1191
|
+
|
1192
|
+
Then, now that we have a menu-bar, we can add new menus to
|
1193
|
+
it, of class JMenu. We use the method called .add() to
|
1194
|
+
add menu-entries there.
|
1195
|
+
|
1196
|
+
Once you are done with the menu, it is time to add it. The menu
|
1197
|
+
is typically added to a <b>JFrame</b>, via the following
|
1198
|
+
API:
|
1199
|
+
|
1200
|
+
setJMenuBar(JMenuBar menuBar)
|
1201
|
+
frame.setJMenuBar(menuBar)
|
1202
|
+
|
1203
|
+
Take note that there are two distinct methods that are rather
|
1204
|
+
similar: one is called <b>.setJMenuBar</b> and the other one is
|
1205
|
+
called <b>.setMenuBar</b>. JMenuBar() is for Swing and MenuBar()
|
1206
|
+
is for AWT.
|
1207
|
+
|
1208
|
+
Individual Menu items behave like buttons.
|
1209
|
+
|
1210
|
+
If you have a need to disable an individual menu item then you
|
1211
|
+
can do so via:
|
1212
|
+
|
1213
|
+
setEnabled(boolean b)
|
1214
|
+
|
1215
|
+
Example in jruby-Swing for disabling a menu item:
|
1216
|
+
|
1217
|
+
menu_item.setEnabled(false)
|
1218
|
+
|
1219
|
+
To then bind an event to a menu-item, use <b>.addActionListener</b>.
|
1220
|
+
|
1221
|
+
Example for this:
|
1222
|
+
|
1223
|
+
first = JMenuItem.new('Item 1')
|
1224
|
+
m1.add(first)
|
1225
|
+
first.addActionListener {|event|
|
1226
|
+
puts 'Hello world!'
|
1227
|
+
}
|
1228
|
+
# Or, to exit, use this:
|
1229
|
+
first.add_action_listener { |event|
|
1230
|
+
System.exit(0) # or just exit, should be fine too.
|
1231
|
+
}
|
1232
|
+
|
1233
|
+
If you have a need to repaint the menu bar, you can use .revalidate()
|
1234
|
+
as in:
|
1235
|
+
|
1236
|
+
menu_bar.revalidate()
|
1237
|
+
menu_bar.revalidate # or this one, as ruby allows you to omit ()
|
1238
|
+
|
1239
|
+
Once you created your menu, you have to fill the submenus with
|
1240
|
+
JMenuItem entries. The following shows such an example I was
|
1241
|
+
using in January 2024:
|
1242
|
+
|
1243
|
+
open_a_local_file_entrypoint = JMenuItem.new('Open a local file', KeyEvent::VK_T)
|
1244
|
+
open_a_local_file_entrypoint.use_this_font = :hack_26
|
1245
|
+
open_a_local_file_entrypoint.addActionListener {|event|
|
1246
|
+
do_choose_a_local_file_then_read_it_in
|
1247
|
+
}
|
1248
|
+
m1.add(open_a_local_file_entrypoint)
|
1249
|
+
|
1250
|
+
So, to respond to the on-selected event, make use of .addActionListenere.
|
1251
|
+
|
1252
|
+
## Working with JSplitPane
|
1253
|
+
|
1254
|
+
Via JSplitPane - to be found under <b>javax.swing.JSplitPane</b> - you can
|
1255
|
+
split a pane, such as splitting into a left and a right component.
|
1256
|
+
|
1257
|
+
Let's look at two images as to how <b>JSplitPane</b> looks like:
|
1258
|
+
|
1259
|
+
<img src="https://i.imgur.com/zDe6NHK.png" style="margin: 1em">
|
1260
|
+
<img src="https://i.imgur.com/ucVpEcj.png" style="margin: 1em">
|
1261
|
+
|
1262
|
+
To create a new <b>split-pane</b>, you would use the following code:
|
1263
|
+
|
1264
|
+
split_pane = JSplitPane.new(JSplitPane::VERTICAL_SPLIT)
|
1265
|
+
|
1266
|
+
You can then modify its layout, or whether it allows one-touch
|
1267
|
+
expendable behaviour:
|
1268
|
+
|
1269
|
+
split_pane.setContinuousLayout(true)
|
1270
|
+
split_pane.setOneTouchExpandable(true)
|
1271
|
+
|
1272
|
+
You can then put other widgets into it, such as a button on top:
|
1273
|
+
|
1274
|
+
button_on_top = JButton.new('A')
|
1275
|
+
split_pane.setTopComponent(button_on_top)
|
1276
|
+
|
1277
|
+
And a button on bottom:
|
1278
|
+
|
1279
|
+
button_on_bottom =JButton.new('B')
|
1280
|
+
split_pane.setBottomComponent(button_on_bottom)
|
1281
|
+
|
1282
|
+
## Assigning Enter as the trigger key for all JButtons in a Java-Swing application
|
1283
|
+
|
1284
|
+
UIManager.put("Button.defaultButtonFollowsFocus", Boolean::TRUE)
|
1285
|
+
|
1286
|
+
## Font, working with fonts and using fonts in a java-swing application
|
1287
|
+
|
1288
|
+
Working with fonts in a java-swing application (or jruby-swing application)
|
1289
|
+
can be a bit tricky. This paragraph here tries to gather useful information
|
1290
|
+
pertaining to this.
|
1291
|
+
|
1292
|
+
The raw Java code for creating a new font, goes like this:
|
1293
|
+
|
1294
|
+
Font use_this_font = new Font("SansSerif", Font.PLAIN, 20);
|
1295
|
+
|
1296
|
+
In jruby this would be equivalent to the following code:
|
1297
|
+
|
1298
|
+
use_this_font = Font.new('SansSerif', Font::Plain, 20)
|
1299
|
+
|
1300
|
+
Next follows a list, as example, how to handle different fonts - first
|
1301
|
+
in java-swing, then in jruby-swing:
|
1302
|
+
|
1303
|
+
widget.setFont(new Font("Times New Roman", Font.PLAIN, 12))
|
1304
|
+
widget.setFont(new Font("Hack", Font.PLAIN, 40))
|
1305
|
+
|
1306
|
+
# now in jruby:
|
1307
|
+
widget.setFont(Font.new("Times New Roman", Font::PLAIN, 12))
|
1308
|
+
widget.setFont(Font.new("Hack", Font::PLAIN, 40))
|
1309
|
+
|
1310
|
+
## Choosing files via a GUI, through JFileChooser - file-chooser functionality
|
1311
|
+
|
1312
|
+
Let's first have a look how JFileChooser may look on WinXP:
|
1313
|
+
|
1314
|
+
<img src="https://i.imgur.com/pkEoG6T.png" style="margin: 1em">
|
1315
|
+
|
1316
|
+
You can use something like the following to get a file-chooser
|
1317
|
+
in jruby-swing:
|
1318
|
+
|
1319
|
+
file_chooser = JFileChooser.new
|
1320
|
+
# file_chooser.setFileSelectionMode(JFileChooser::DIRECTORIES_ONLY)
|
1321
|
+
|
1322
|
+
result = file_chooser.showOpenDialog(nil) # or pass true here, to show the open dialog.
|
1323
|
+
case result
|
1324
|
+
when JFileChooser::APPROVE_OPTION
|
1325
|
+
this_file = file_chooser.getSelectedFile.getAbsoluteFile.to_s
|
1326
|
+
# this_file = File.absolute_path(this_file)
|
1327
|
+
main_entry?.set_text(this_file)
|
1328
|
+
end
|
1329
|
+
|
1330
|
+
Adjust accordingly to your use case. Keep in mind that on closing, a
|
1331
|
+
file selection dialogue returns an integer value which is one of
|
1332
|
+
the following integer constants:
|
1333
|
+
|
1334
|
+
APPROVE_OPTION: indicates that the ‘Open’ or ‘Save’, in case of a
|
1335
|
+
save dialogue button of the dialogue has been
|
1336
|
+
clicked.
|
1337
|
+
CANCEL_OPTION: indicates that the ‘Cancel’ button of the dialogue
|
1338
|
+
has been clicked.
|
1339
|
+
|
1340
|
+
Note that <b>JFileChooser::APPROVE_OPTION</b> returns <b>0</b>.
|
1341
|
+
|
1342
|
+
To obtain the file that was selected, the method <b>.getSelectedFile</b>
|
1343
|
+
can be used, as shown in the code example above.
|
1344
|
+
|
1345
|
+
Since as of January 2024 you can also use UniversalWidgets.main_file?
|
1346
|
+
and UniversalWidgets.set_main_file() to keep track of the chosen file.
|
1347
|
+
|
1348
|
+
## JDialog and dialogues in jruby-SWING
|
1349
|
+
|
1350
|
+
First, what is a dialogue?
|
1351
|
+
|
1352
|
+
A dialogue is basically a simple means, via a widget, to obtain
|
1353
|
+
information from the user. This can then be of help for user-program
|
1354
|
+
interaction.
|
1355
|
+
|
1356
|
+
Dialogues - that is, the widgets - are used when the application needs
|
1357
|
+
information from the user in order to proceed with a task or some
|
1358
|
+
other event.
|
1359
|
+
|
1360
|
+
In jruby-SWING, the primary use of dialogues happens via
|
1361
|
+
<b>JDialog</b>:
|
1362
|
+
|
1363
|
+
<b>JDialog</b> can be thought of to be <b>a pop-up window</b> that pops out
|
1364
|
+
when a message has to be displayed to the user.
|
1365
|
+
|
1366
|
+
The namespace for <b>JDialog</b> is <b>javax.swing.JDialog</b>.
|
1367
|
+
|
1368
|
+
Some dialoguses are pre-defined. For instance, a message dialogue
|
1369
|
+
can be invoked via:
|
1370
|
+
|
1371
|
+
JOptionPane.showMessageDialog(
|
1372
|
+
Component parent,
|
1373
|
+
String title,
|
1374
|
+
String message,
|
1375
|
+
int type
|
1376
|
+
);
|
1377
|
+
|
1378
|
+
More documentation pertaining to JDialog, in particular its API,
|
1379
|
+
can be seen here:
|
1380
|
+
|
1381
|
+
https://docs.oracle.com/javase/8/docs/api/javax/swing/JDialog.html
|
1382
|
+
|
1383
|
+
## Working with JRadioButton
|
1384
|
+
|
1385
|
+
First, let's look at <b>two images</b> to see how a JRadioButton
|
1386
|
+
may look like:
|
1387
|
+
|
1388
|
+
<img src="https://i.imgur.com/E4S1VWL.png" style="margin-right: 1em">
|
1389
|
+
<img src="https://i.imgur.com/hSrhzWz.jpg" style="margin: 1em">
|
1390
|
+
|
1391
|
+
<b>JRadioButton</b>'s fully qualified namespace is
|
1392
|
+
<b>javax.swing.JRadioButton</b>. Its superclass is
|
1393
|
+
a <b>JToggleButton</b>.
|
1394
|
+
|
1395
|
+
To create a new JRadioButton via java-swing, use:
|
1396
|
+
|
1397
|
+
JRadioButton x = new JRadioButton("Foobar");
|
1398
|
+
|
1399
|
+
<b>Radio buttons</b> can be pressed and they can be grouped. They
|
1400
|
+
will stay pressed until another radio button of the group is
|
1401
|
+
pressed. A black dot appears inside the circular area if
|
1402
|
+
the button is pressed, as can be seen on the above image.
|
1403
|
+
|
1404
|
+
The text that is displayed on a radio-button can be defined
|
1405
|
+
via passing a String as the first argument, as seen in the
|
1406
|
+
above example. For sake of completion we will show how this
|
1407
|
+
is done in jruby too:
|
1408
|
+
|
1409
|
+
radio_button = JRadioButton.new('Foobar')
|
1410
|
+
|
1411
|
+
If you have a need to programmatically set that radio button
|
1412
|
+
selected or de-selected, use this method:
|
1413
|
+
|
1414
|
+
radio_button.setSelected(true) # It is now selected.
|
1415
|
+
radio_button.setSelected(false) # It is now de-selected.
|
1416
|
+
|
1417
|
+
.setActionCommand(String command) assigns the string command
|
1418
|
+
as the action command to the button. Radio buttons are not
|
1419
|
+
automatically assigned an action command. This is because
|
1420
|
+
their label is often not a text but a picture. The action
|
1421
|
+
command can be set via this method.
|
1422
|
+
|
1423
|
+
<b>.getActionCommand()</b> returns the action command
|
1424
|
+
assigned to the button.
|
1425
|
+
|
1426
|
+
Normally radio buttons are put into a <b>ButtonGroup</b>. This
|
1427
|
+
has the effect that if the user selects one radio button,
|
1428
|
+
all other radio buttons are de-selected. In other words:
|
1429
|
+
this achieves that only one radio button is actively
|
1430
|
+
selected at any given moment in time.
|
1431
|
+
|
1432
|
+
In order to group radio-buttons into a button group, we should
|
1433
|
+
first create a new instance of ButtonGroup, such as via:
|
1434
|
+
|
1435
|
+
button_group = ButtonGroup.new
|
1436
|
+
|
1437
|
+
Next, use the method <b>.add()</b> to add radio_buttons into that
|
1438
|
+
button group:
|
1439
|
+
|
1440
|
+
button_group.add(radio_button1)
|
1441
|
+
button_group.add(radio_button2)
|
1442
|
+
|
1443
|
+
The <b>API documentation</b> for <b>JRadioButton</b> can be seen here:
|
1444
|
+
|
1445
|
+
https://docs.oracle.com/javase/8/docs/api/javax/swing/JRadioButton.html
|
1446
|
+
|
1447
|
+
## Java Swing Plaf
|
1448
|
+
|
1449
|
+
The javax.swing.plaf package contains several subpackages and related packages.
|
1450
|
+
|
1451
|
+
<b>Plaf</b> stands for <b>pluggable look and feel</b>.
|
1452
|
+
|
1453
|
+
## Swing versus AWT
|
1454
|
+
|
1455
|
+
<b>Swing component</b> class names begin with a J. AWT components do
|
1456
|
+
not.
|
1457
|
+
|
1458
|
+
For instance, JButton is a swing-component whereas Button is an
|
1459
|
+
AWT component.
|
1460
|
+
|
1461
|
+
This distinction holds true for most components, but one exception
|
1462
|
+
is the <b>JComboBox</b>, which replaces the AWT Choice component.
|
1463
|
+
|
1464
|
+
The following table shows the AWT component and the nearest
|
1465
|
+
swing replacement:
|
1466
|
+
|
1467
|
+
AWT Component | Nearest Swing Replacement
|
1468
|
+
-------------------------------------------------
|
1469
|
+
Button | JButton
|
1470
|
+
Canvas | JPanel
|
1471
|
+
Checkbox | JCheckBox
|
1472
|
+
Checkbox in CheckboxGroup | JRadioButton in ButtonGroup
|
1473
|
+
Choice | JComboBox
|
1474
|
+
Component | JComponent
|
1475
|
+
Container | JPanel
|
1476
|
+
Label | JLabel
|
1477
|
+
List | JList
|
1478
|
+
Menu | JMenu
|
1479
|
+
MenuBar | JMenuBar
|
1480
|
+
MenuItem | JMenuItem
|
1481
|
+
Panel | JPanel
|
1482
|
+
PopupMenu | JPopupMenu
|
1483
|
+
Scrollbar | JScrollBar
|
1484
|
+
ScrollPane | JScrollPane
|
1485
|
+
TextArea | JTextArea
|
1486
|
+
TextField | JTextField
|
1487
|
+
Applet | JApplet
|
1488
|
+
Dialog | JDialog
|
1489
|
+
FileDialog | JFileChooser
|
1490
|
+
Frame | JFrame
|
1491
|
+
Window | JWindow
|
1492
|
+
|
1493
|
+
## JPasswordField
|
1494
|
+
|
1495
|
+
JPasswordField is a specialized text field that can be used for inputting
|
1496
|
+
a password into a Swing-Application.
|
1497
|
+
|
1498
|
+
Cut and copy operations are not possible within this
|
1499
|
+
component, but text can be pasted into it.
|
1500
|
+
|
1501
|
+
On Windows it may look like this:
|
1502
|
+
|
1503
|
+
<img src="https://static.javatpoint.com/java/swing/images/java-jpasswardfield1.png" style="margin: 1em">
|
1504
|
+
|
1505
|
+
## Potentially useful links pertaining to Java-Swing
|
1506
|
+
|
1507
|
+
https://web.mit.edu/6.005/www/sp14/psets/ps4/java-6-tutorial/components.html
|
1508
|
+
https://www.javatpoint.com/java-swing
|
1509
|
+
|
1510
|
+
CONTACT_INFORMATION
|