Skip to content

Commit cb8f2db

Browse files
committed
WIP: first working version of Swing TextWidget
1 parent 7dd2d5a commit cb8f2db

File tree

7 files changed

+334
-66
lines changed

7 files changed

+334
-66
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2017 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck
7+
* Institute of Molecular Cell Biology and Genetics, University of
8+
* Konstanz, and KNIME GmbH.
9+
* %%
10+
* Redistribution and use in source and binary forms, with or without
11+
* modification, are permitted provided that the following conditions are met:
12+
*
13+
* 1. Redistributions of source code must retain the above copyright notice,
14+
* this list of conditions and the following disclaimer.
15+
* 2. Redistributions in binary form must reproduce the above copyright notice,
16+
* this list of conditions and the following disclaimer in the documentation
17+
* and/or other materials provided with the distribution.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
23+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29+
* POSSIBILITY OF SUCH DAMAGE.
30+
* #L%
31+
*/
32+
33+
package org.scijava.nwidget;
34+
35+
/**
36+
* Widget interface for text fields and areas.
37+
*
38+
* @author Curtis Rueden
39+
*/
40+
public interface NTextWidget extends NWidget {
41+
42+
/**
43+
* Widget style for text fields.
44+
*
45+
* @see org.scijava.plugin.Parameter#style()
46+
*/
47+
String FIELD_STYLE = "text field";
48+
49+
/**
50+
* Widget style for text areas.
51+
*
52+
* @see org.scijava.plugin.Parameter#style()
53+
*/
54+
String AREA_STYLE = "text area";
55+
56+
/**
57+
* Widget style for password fields.
58+
*
59+
* @see org.scijava.plugin.Parameter#style()
60+
*/
61+
String PASSWORD_STYLE = "password";
62+
63+
String ROWS_PROPERTY = "rows";
64+
String COLUMNS_PROPERTY = "columns";
65+
}

src/main/java/org/scijava/nwidget/NWidget.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,4 @@
44

55
public interface NWidget {
66
MemberInstance<?> model();
7-
8-
/**
9-
* Gets the label to use next to the widget, or null if the widget should
10-
* occupy the entire panel row.
11-
*/
12-
default String getLabel() {
13-
return null;
14-
}
15-
16-
default String getDescription() {
17-
return null;
18-
}
197
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
2+
package org.scijava.nwidget;
3+
4+
import java.util.Arrays;
5+
6+
import org.scijava.param.ParameterMember;
7+
import org.scijava.struct.Member;
8+
import org.scijava.struct.MemberInstance;
9+
10+
/** Utility class for working with {@link NWidget}s. */
11+
public final class NWidgets {
12+
13+
private NWidgets() {
14+
// NB: Prevent instantiation of utility class.
15+
}
16+
17+
public static ParameterMember<?> param(final NWidget widget) {
18+
return param(widget.model());
19+
}
20+
21+
public static <T> ParameterMember<T> param(final MemberInstance<T> model) {
22+
final Member<T> member = model.member();
23+
return member instanceof ParameterMember ? //
24+
(ParameterMember<T>) member : null;
25+
}
26+
27+
public static String label(final NWidget widget) {
28+
if (param(widget) != null) {
29+
final String label = param(widget).getLabel();
30+
if (label != null && !label.isEmpty()) return label;
31+
}
32+
33+
final String name = widget.model().member().getKey();
34+
return name.substring(0, 1).toUpperCase() + name.substring(1);
35+
}
36+
37+
public static String description(final NWidget widget) {
38+
return (param(widget) == null) ? null : param(widget).getDescription();
39+
}
40+
41+
public static String style(final NWidget widget) {
42+
return param(widget) == null ? null : param(widget).getWidgetStyle();
43+
}
44+
45+
public static boolean isStyle(final NWidget widget, final String style) {
46+
final String widgetStyle = style(widget);
47+
if (widgetStyle == null) return false;
48+
return Arrays.asList(widgetStyle.split(",")).contains(style);
49+
}
50+
51+
public static int intProperty(final NWidget widget, final String propKey,
52+
final int defaultValue)
53+
{
54+
if (param(widget) == null) return defaultValue;
55+
final Integer value = s2i(param(widget).get(propKey));
56+
return value == null ? defaultValue : value;
57+
}
58+
59+
public static Object minimum(final NWidget widget) {
60+
return param(widget) == null ? null : param(widget).getMinimumValue();
61+
}
62+
63+
public static Object maximum(final NWidget widget) {
64+
return param(widget) == null ? null : param(widget).getMaximumValue();
65+
}
66+
67+
public static Object softMinimum(final NWidget widget) {
68+
return param(widget) == null ? null : param(widget).getSoftMinimum();
69+
}
70+
71+
public static Object softMaximum(final NWidget widget) {
72+
return param(widget) == null ? null : param(widget).getSoftMaximum();
73+
}
74+
75+
public static Object stepSize(final NWidget widget) {
76+
return param(widget) == null ? null : param(widget).getStepSize();
77+
}
78+
79+
// -- Helper methods --
80+
81+
private static Integer s2i(final String s) {
82+
if (s == null) return null;
83+
try {
84+
return Integer.parseInt(s);
85+
}
86+
catch (final NumberFormatException exc) {
87+
return null;
88+
}
89+
}
90+
}

src/main/java/org/scijava/nwidget/swing/NSwingNumberWidgetFactory.java

Lines changed: 20 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@
2626

2727
import org.scijava.convert.ConvertService;
2828
import org.scijava.nwidget.NAbstractWidget;
29+
import org.scijava.nwidget.NNumberWidget;
2930
import org.scijava.nwidget.NWidget;
3031
import org.scijava.nwidget.NWidgetFactory;
31-
import org.scijava.nwidget.NNumberWidget;
32+
import org.scijava.nwidget.NWidgets;
3233
import org.scijava.param.ParameterMember;
3334
import org.scijava.plugin.Parameter;
3435
import org.scijava.plugin.Plugin;
@@ -49,7 +50,7 @@ public class NSwingNumberWidgetFactory implements NSwingWidgetFactory {
4950

5051
@Override
5152
public boolean supports(final MemberInstance<?> model) {
52-
Member<?> member = model.member();
53+
final Member<?> member = model.member();
5354
return ClassUtils.isNumber(member.getRawType()) &&
5455
member instanceof ParameterMember;
5556
}
@@ -65,30 +66,13 @@ private class Widget extends NAbstractWidget implements NSwingWidget,
6566
NNumberWidget, AdjustmentListener, ChangeListener
6667
{
6768

68-
private final ParameterMember<?> pMember;
69-
7069
private JPanel panel;
7170
private JScrollBar scrollBar;
7271
private JSlider slider;
7372
private JSpinner spinner;
7473

7574
public Widget(final MemberInstance<?> model) {
7675
super(model);
77-
pMember = (ParameterMember<?>) model.member();
78-
}
79-
80-
// TODO - migrate these to some abstract base class w/ ParameterMember?
81-
@Override
82-
public String getLabel() {
83-
final String label = pMember.getLabel();
84-
if (label != null && !label.isEmpty()) return label;
85-
86-
final String name = pMember.getKey();
87-
return name.substring(0, 1).toUpperCase() + name.substring(1);
88-
}
89-
@Override
90-
public String getDescription() {
91-
return pMember.getDescription();
9276
}
9377

9478
@Override
@@ -100,50 +84,50 @@ public JPanel getComponent() {
10084
"[fill,grow|pref]");
10185
panel.setLayout(layout);
10286

103-
final Number min = number(pMember.getMinimumValue(), null);
104-
final Number max = number(pMember.getMaximumValue(), null);
105-
final Number softMin = number(pMember.getSoftMinimum(), min);
106-
final Number softMax = number(pMember.getSoftMaximum(), max);
107-
final Number stepSize = number(pMember.getStepSize(), 1);
87+
final Number min = number(NWidgets.minimum(this), null);
88+
final Number max = number(NWidgets.maximum(this), null);
89+
final Number softMin = number(NWidgets.softMinimum(this), min);
90+
final Number softMax = number(NWidgets.softMaximum(this), max);
91+
final Number stepSize = number(NWidgets.stepSize(this), 1);
10892

10993
// add optional widgets, if specified
110-
if (isStyle(SCROLL_BAR_STYLE)) {
94+
if (NWidgets.isStyle(this, SCROLL_BAR_STYLE)) {
11195
int smx = softMax.intValue();
11296
if (smx < Integer.MAX_VALUE) smx++;
11397
scrollBar =
11498
new JScrollBar(Adjustable.HORIZONTAL, softMin.intValue(), 1, softMin
11599
.intValue(), smx);
116100
scrollBar.setUnitIncrement(stepSize.intValue());
117-
setToolTip(scrollBar);
101+
NSwingWidgets.setToolTip(this, scrollBar);
118102
getComponent().add(scrollBar);
119103
scrollBar.addAdjustmentListener(this);
120104
}
121-
else if (isStyle(SLIDER_STYLE)) {
105+
else if (NWidgets.isStyle(this, SLIDER_STYLE)) {
122106
slider =
123107
new JSlider(softMin.intValue(), softMax.intValue(), softMin.intValue());
124108
slider.setMajorTickSpacing((softMax.intValue() - softMin.intValue()) / 4);
125109
slider.setMinorTickSpacing(stepSize.intValue());
126110
slider.setPaintLabels(true);
127111
slider.setPaintTicks(true);
128-
setToolTip(slider);
112+
NSwingWidgets.setToolTip(this, slider);
129113
getComponent().add(slider);
130114
slider.addChangeListener(this);
131115
}
132116

133117
// add spinner widget
134-
final Class<?> type = pMember.getRawType();
135-
final Number v = getValue();
118+
final Class<?> type = model().member().getRawType();
119+
final Number v = modelValue();
136120
final Number value = v == null ? 0 : v;
137121
final SpinnerNumberModel spinnerModel =
138122
new SpinnerNumberModelFactory().createModel(value, min, max, stepSize);
139123
spinner = new JSpinner(spinnerModel);
140124
fixSpinner(type);
141-
setToolTip(spinner);
125+
NSwingWidgets.setToolTip(this, spinner);
142126
panel.add(spinner);
143127
limitWidth(200);
144128
spinner.addChangeListener(this);
145129

146-
spinner.setValue(getValue());
130+
spinner.setValue(modelValue());
147131
syncSliders();
148132

149133
return panel;
@@ -266,7 +250,7 @@ public void run() {
266250
private void syncSliders() {
267251
if (slider != null) {
268252
// clamp value within slider bounds
269-
int value = getValue().intValue();
253+
int value = modelValue().intValue();
270254
if (value < slider.getMinimum()) value = slider.getMinimum();
271255
else if (value > slider.getMaximum()) value = slider.getMaximum();
272256
slider.removeChangeListener(this);
@@ -275,38 +259,22 @@ private void syncSliders() {
275259
}
276260
if (scrollBar != null) {
277261
// clamp value within scroll bar bounds
278-
int value = getValue().intValue();
262+
int value = modelValue().intValue();
279263
if (value < scrollBar.getMinimum()) value = scrollBar.getMinimum();
280264
else if (value > scrollBar.getMaximum()) value = scrollBar.getMaximum();
281265
scrollBar.removeAdjustmentListener(this);
282-
scrollBar.setValue(getValue().intValue());
266+
scrollBar.setValue(modelValue().intValue());
283267
scrollBar.addAdjustmentListener(this);
284268
}
285269
}
286270

287-
private boolean isStyle(final String style) {
288-
final String widgetStyle = pMember.getWidgetStyle();
289-
if (widgetStyle == null) return style == null;
290-
for (final String s : widgetStyle.split(",")) {
291-
if (s.equals(style)) return true;
292-
}
293-
return false;
294-
}
295-
296-
private Number getValue() {
271+
private Number modelValue() {
297272
final Number value = (Number) model().get();
298273

299274
// TODO: Decide whether to do this here.
300275
// if (isMultipleChoice()) return ensureValidChoice(value);
301276
// if (getObjectPool().size() > 0) return ensureValidObject(value);
302277
return value == null ? 0 : value;
303278
}
304-
305-
/** Assigns the model's description as the given component's tool tip. */
306-
private void setToolTip(final JComponent c) {
307-
final String desc = pMember.getDescription();
308-
if (desc == null || desc.isEmpty()) return;
309-
c.setToolTipText(desc);
310-
}
311279
}
312280
}

0 commit comments

Comments
 (0)