1
1
package qupath .ext .template ;
2
2
3
3
import javafx .beans .property .BooleanProperty ;
4
+ import javafx .beans .property .IntegerProperty ;
5
+ import javafx .beans .property .Property ;
6
+ import javafx .scene .Scene ;
4
7
import javafx .scene .control .MenuItem ;
8
+ import javafx .stage .Stage ;
5
9
import org .slf4j .Logger ;
6
10
import org .slf4j .LoggerFactory ;
11
+ import qupath .ext .template .ui .InterfaceController ;
12
+ import qupath .fx .dialogs .Dialogs ;
13
+ import qupath .fx .prefs .controlsfx .PropertyItemBuilder ;
7
14
import qupath .lib .common .Version ;
8
15
import qupath .lib .gui .QuPathGUI ;
9
- import qupath .lib .gui .dialogs .Dialogs ;
10
16
import qupath .lib .gui .extensions .GitHubProject ;
11
17
import qupath .lib .gui .extensions .QuPathExtension ;
12
18
import qupath .lib .gui .prefs .PathPrefs ;
13
19
20
+ import java .io .IOException ;
21
+
14
22
15
23
/**
16
24
* This is a demo to provide a template for creating a new QuPath extension.
@@ -63,11 +71,35 @@ public class DemoExtension implements QuPathExtension, GitHubProject {
63
71
private boolean isInstalled = false ;
64
72
65
73
/**
66
- * A 'persistent preference' - showing how to create a property that is stored whenever QuPath is closed
74
+ * A 'persistent preference' - showing how to create a property that is stored whenever QuPath is closed.
75
+ * This preference will be managed in the main QuPath GUI preferences window.
67
76
*/
68
- private BooleanProperty enableExtensionProperty = PathPrefs .createPersistentPreference (
77
+ private static BooleanProperty enableExtensionProperty = PathPrefs .createPersistentPreference (
69
78
"enableExtension" , true );
70
79
80
+
81
+ /**
82
+ * Another 'persistent preference'.
83
+ * This one will be managed using a GUI element created by the extension.
84
+ * We use {@link Property<Integer>} rather than {@link IntegerProperty}
85
+ * because of the type of GUI element we use to manage it.
86
+ */
87
+ private static Property <Integer > numThreadsProperty = PathPrefs .createPersistentPreference (
88
+ "demo.num.threads" , 1 ).asObject ();
89
+
90
+ /**
91
+ * An example of how to expose persistent preferences to other classes in your extension.
92
+ * @return The persistent preference, so that it can be read or set somewhere else.
93
+ */
94
+ public static Property <Integer > numThreadsProperty () {
95
+ return numThreadsProperty ;
96
+ }
97
+
98
+ /**
99
+ * Create a stage for the extension to display
100
+ */
101
+ private Stage stage ;
102
+
71
103
@ Override
72
104
public void installExtension (QuPathGUI qupath ) {
73
105
if (isInstalled ) {
@@ -76,12 +108,35 @@ public void installExtension(QuPathGUI qupath) {
76
108
}
77
109
isInstalled = true ;
78
110
addPreference (qupath );
111
+ addPreferenceToPane (qupath );
79
112
addMenuItem (qupath );
80
113
}
81
114
82
115
/**
83
116
* Demo showing how to add a persistent preference to the QuPath preferences pane.
84
- * @param qupath
117
+ * The preference will be in a section of the preference pane based on the
118
+ * category you set. The description is used as a tooltip.
119
+ * @param qupath The currently running QuPathGUI instance.
120
+ */
121
+ private void addPreferenceToPane (QuPathGUI qupath ) {
122
+ var propertyItem = new PropertyItemBuilder <>(enableExtensionProperty , Boolean .class )
123
+ .name ("Enable extension" )
124
+ .category ("Demo extension" )
125
+ .description ("Enable the demo extension" )
126
+ .build ();
127
+ qupath .getPreferencePane ()
128
+ .getPropertySheet ()
129
+ .getItems ()
130
+ .add (propertyItem );
131
+ }
132
+
133
+ /**
134
+ * Demo showing how to add a persistent preference.
135
+ * This will be loaded whenever QuPath launches, with the value retained unless
136
+ * the preferences are reset.
137
+ * However, users will not be able to edit it unless you create a GUI
138
+ * element that corresponds with it
139
+ * @param qupath The currently running QuPathGUI instance.
85
140
*/
86
141
private void addPreference (QuPathGUI qupath ) {
87
142
qupath .getPreferencePane ().addPropertyPreference (
@@ -99,15 +154,28 @@ private void addPreference(QuPathGUI qupath) {
99
154
private void addMenuItem (QuPathGUI qupath ) {
100
155
var menu = qupath .getMenu ("Extensions>" + EXTENSION_NAME , true );
101
156
MenuItem menuItem = new MenuItem ("My menu item" );
102
- menuItem .setOnAction (e -> {
103
- Dialogs .showMessageDialog (EXTENSION_NAME ,
104
- "Hello! This is my Java extension." );
105
- });
157
+ menuItem .setOnAction (e -> createStage ());
106
158
menuItem .disableProperty ().bind (enableExtensionProperty .not ());
107
159
menu .getItems ().add (menuItem );
108
160
}
109
-
110
-
161
+
162
+ /**
163
+ * Demo showing how to create a new stage with a JavaFX FXML interface.
164
+ */
165
+ private void createStage () {
166
+ if (stage == null ) {
167
+ try {
168
+ stage = new Stage ();
169
+ Scene scene = new Scene (InterfaceController .createInstance ());
170
+ stage .setScene (scene );
171
+ } catch (IOException e ) {
172
+ Dialogs .showErrorMessage ("Extension Error" , "GUI loading failed" );
173
+ logger .error ("Unable to load extension interface FXML" , e );
174
+ }
175
+ }
176
+ stage .show ();
177
+ }
178
+
111
179
@ Override
112
180
public String getName () {
113
181
return EXTENSION_NAME ;
0 commit comments