Skip to content

User Inputs

William Wood edited this page Apr 23, 2019 · 5 revisions

User Inputs

Obviously a large part of any GUI is the ability to accept user-input. In the context of an experiment, this will largely be in the form of experimental parameters to configure the experiment and file-select windows to specify where to save data to.

Contents

  1. Basic Input using Dialogues
  2. Fields Element
  3. Field Handles
  4. Choice Boxes
  5. Buttons
  6. Fields Methods Reference
  7. Field Handle Methods Reference

Basic Input using Dialogues

Top ↑

The most basic way of prompting the user for input is by use of the "input window" dialogue box. This can be called at any time (so long as the GUI thread is running) by use of:

Java

String[] responses = GUI.inputWindow(title, header, message, name1, name2, ...);

Kotlin

val responses = GUI.inputWindow(title, header, message, name1, name2, ...)

Python

responses = GUI.inputWindow(title, header, message, [name1, name2, ...])

This will show a pop-up dialogue window with the specified title, header and message with a text-box for each field, specified by providing names for each box.

For example:

String[] responses = GUI.inputWindow(
    "Hello", 
    "Greetings", 
    "Please enter your name, age and height",
    "Name",
    "Age",
    "Height"
);

will result in the following window showing:

After typing into the boxes and pressing "OK", the method will return the user's responses as an array of strings in the order that the boxes were specified (in our case into the variable responses).

System.out.printf("Your name is %s\n", responses[0]);
System.out.printf("Your age is %s\n", responses[1]);
System.out.printf("Your height is %s\n", responses[2]);

Fields Element

Top ↑

Whilst using the GUI.inputWindow(...) method is good if, for example, you are creating a simple "script-like" programme. However, when building a more cohesive GUI, having user-inputs that are persistent and/or configurable is a much better idea.

To do this, JISA provides the Fields class. This creates a window/element to which we can add fields such as text inputs, integer inputs, floating-point inputs, check-boxes, selection-boxes, file save inputs, file open inputs and buttons.

Java

Fields fields = new Fields("Title");
fields.show();

Kotlin

val fields = Fields("Title")
fields.show()

Python

fields = Fields("Title")
fields.show()

The above will create an empty window/element ready for inputs and buttons to be added.

Now, we can add some types of fields:

Java

// Text input
Field<String>  textField = fields.addTextField("Text Field");

// Whole-number input
Field<Integer> intField  = fields.addIntegerField("Integer Field");

// Double-precision floating-point (ie with a decimal point) input
Field<Double>  dblField  = fields.addDoubleField("Double Field");

// Check box: ticked = true, unticked = false
Field<Boolean> checkBox  = fields.addCheckBox("Check Box");

// Choice/drop-down box with two options
Field<Integer> choiceBox = fields.addChoice("Choice", "Option 1", "Option 2");

// Input to select an already existing file to open
Field<String>  openFile  = fields.addFileOpen("Open File");

// Input to select where to save a file to
Field<String>  saveFile  = fields.addFileSave("Save File");

Kotlin

// Text input
val textField = fields.addTextField("Text Field")

// Whole-number input
val intField  = fields.addIntegerField("Integer Field")

// Double-precision floating-point (ie with a decimal point) input
val dblField  = fields.addDoubleField("Double Field")

// Check box: ticked = true, unticked = false
val checkBox  = fields.addCheckBox("Check Box")

// Choice/drop-down box with two options
val choiceBox = fields.addChoice("Choice", "Option 1", "Option 2")

// Input to select an already existing file to open
val openFile  = fields.addFileOpen("Open File")

// Input to select where to save a file to
val saveFile  = fields.addFileSave("Save File")

Python

# Text input
textField = fields.addTextField("Text Field")

# Whole-number input
intField  = fields.addIntegerField("Integer Field")

# Double-precision floating-point (ie with a decimal point) input
dblField  = fields.addDoubleField("Double Field")

# Check box: ticked = true, unticked = false
checkBox  = fields.addCheckBox("Check Box")

# Choice/drop-down box with two options
choiceBox = fields.addChoice("Choice", "Option 1", "Option 2")

# Input to select an already existing file to open
openFile  = fields.addFileOpen("Open File")

# Input to select where to save a file to
saveFile  = fields.addFileSave("Save File")

If we look at our window now:

Field Handles

Top ↑

As you may have noticed, each time we created a field it returned a Field object. This is a "generic" object type, as denoted by the <...>, ie Field<String> or Field<Double>. This essentially means that they "contain" different variables types. For example, Field<String> means it "contains" a String whereas Field<Double> "contains" a double. Obviously, for Kotlin and Python this isn't a concern since you don't have to explicitly declare the type of your variables.

These Field objects act as our "handle" on each input-field, allowing us to retrieve, set and watch for changes in the contents of each field.

To retrieve what a field currently holds, you can use the get() method:

String text = textField.get();
double dbl  = dblField.get();

System.out.println(text);
System.out.println(dbl);

So, if the user has entered the following:

Then our above code will output:

Bamboozlin all day long
1.567E-7

You can also set the value by use of set(...):

textField.set("New Value");
dblField.set(1.23e-6);

Resulting in:

As mentioned, we can make JISA "watch" a field and do something every time it is changed by use of the setOnChange(...) method like so:

Java

textField.setOnChange(() -> {
    System.out.printf("Field changed to: %s\n", textField.get());
});

Kotlin

textField.setOnChange {
    println("Field changed to: %s".format(textField.get()))
}

Python

def onTextChange():
    print("Field changed to: %s" % textField.get())


textField.setOnChange(onTextChange)

Now, every time the value in the text field is changed, the new value will be output to the terminal. So if we start with a blank field and type in the word "Bob" the following will be output:

Field changed to: B
Field changed to: Bo
Field changed to: Bob

Choice Boxes

Top ↑

Choice boxes are a slight exception in some ways. Firstly, the do not return the value of what is selected, but an integer representing which option is selected. For example, if we created the following choice box:

Java

Field<Integer> choice = fields.addChoice("Choice", "Alice", "Bob", "Charlie");

Kotlin

val choice = fields.addChoice("Choice", "Alice", "Bob", "Charlie")

Python

choice = fields.addChoice("Choice", ["Alice", "Bob", "Charlie"])

Then calling:

int value = choice.get();

will return into value:

  • 0 if the user has selected "Alice"
  • 1 if the user has selected "Bob"
  • 2 if the user has selected "Charlie"

The same applies to setting the value. If we were to run:

choice.set(1);

The result would be:

Similarly:

choice.set(0) // Alice
choice.set(1) // Bob
choice.set(2) // Charlie

We can also change which options are displayed in the choice box at any time by using editValues(...) like so:

Java and Kotlin

choice.editValues("Adam", "Beatrice", "Carmilla", "Dan");

Python

choice.editValues(["Adam", "Beatrice", "Carmilla", "Dan"])

which will result in the options becoming:

Notice that since the second option was selected before changing the values, the new second option is automatically chosen after changing.

You can disabled (grey-out) a field at any time by using:

field.setDisabled(true);  // Disabled
field.setDisabled(false); // Enabled

doing this on a text field:

Fields fields = new Fields("Title");  
  
Field<String> textField1 = fields.addTextField("Disabled");  
Field<String> textField2 = fields.addTextField("Enabled");  
  
textField1.setDisabled(true);  
textField2.setDisabled(false);  
  
fields.show();

results in:

Buttons

Top ↑

It is possible to add buttons to the bottom of a Field element by use of the addButton(...) method. If for our example Fields we now run:

Java

fields.addButton("Apply", () -> {
    GUI.infoAlert("Input", "What you wrote", textField.get());
});

Kotlin

fields.addButton("Apply") {
    GUI.infoAlert("Input", "What you wrote", textField.get())
}

Python

def onApply():
    GUI.infoAlert("Input", "What you wrote", textField.get())


fields.addButton("Apply", onApply)

Then we will get the following:

Clicking on this new "Apply" button will now cause a dialogue to appear saying whatever we wrote in the "Text Field" like so:

Fields Reference

Top ↑

Method Description
Field<String> f = fields.addTextField(String name);
Creates an input-field for accepting text. Deals with values as strings.
Field<Integer> f = fields.addIntegerField(String name);
Creates an input-field for accepting integer numbers. Deals with values as integers.
Field<Double> f = fields.addDoubleField(String name);
Creates an input-field for accepting floating-points numbers (ie non-integer). Deals with values as doubles.
Field<Boolean> f = fields.addCheckBox(String name);
Creates a check-box for yes/no, true/false input. Deals with values a booleans.
Field<Integer> f = fields.addChoice(
    String name, 
    String... choices
);
Creates a choice box with the specified choices. Deals with values as integer indices representing the selected choice.
Field<String> f = fields.addFileOpen(String name);
Creates a text-field with a browse button which will show a file-open dialogue to select an already existing file for opening. Deals with values (file-paths) as strings.
Field<String> f = fields.addFileSave(String name);
Creates a text-field with a browse button which will show a file-save dialogue to select a file-path for writing to. Deals with values (file-paths) as strings.
fields.addButton(
    String name,
    SRunnable onClick
);
Creates a clickable button that will perform the action specified by onClick when clicked.
fields.addSeparator();
Adds a separating line after the last field that was added.

Field Reference

Top ↑

Field<E> field = ...; // eg Field<String> or Field<Integer> etc
Method Description
E value = field.get();
Returns the value currently held by the field. The type, E, depends on what sort of field it is.
field.set(E value);
Sets the value (value type depends on type of field) held and displayed by the field.
field.setOnChange(SRunnable onChange);
Tells JISA to watch this field for changes and run the code inside onChange when it detects a change.
field.setDisabled(boolean disabled);
Sets whether the field should be disabled to prevent user-editing or not (ie should it be greyed-out or not?).
boolean flag = field.isDisabled();
Returns whether the field is disabled or not.
field.editValues(String... values);
Changes the available choices for a choice box. Has no effect for other types of field.
boolean flag = field.isDisabled();
Returns whether the field is disabled or not.
Clone this wiki locally