Skip to content

Commit 48b5a7d

Browse files
committed
copyedit gui coding section
1 parent 5ea52ee commit 48b5a7d

27 files changed

+230
-639
lines changed

doc/client/coding/Adding-a-Button-to-the-Perspective-Switcher.md

Lines changed: 38 additions & 337 deletions
Large diffs are not rendered by default.

doc/client/coding/Adding-a-Plugin-or-Feature-to-Maven-Build.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Adding a plugin or feature to Maven
1+
# Adding a plugin or feature
22

33
The steps for adding a plug-in (one small part of IBEX, such as the blocks view) or feature (a larger collection of plug-ins, such as CSS) to the maven build are below:
44

doc/client/coding/Connecting-a-View-to-a-PV.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# Connecting a view to a PV
22

3-
See [An Introduction to Databinding](Databinding) for a explanation of databinding.
3+
:::{seealso}
4+
[An Introduction to Databinding](Databinding) for an explanation of databinding.
5+
:::
46

5-
The basic arrangement for the mechanism for connecting a View to a PV is shown below:
7+
The basic arrangement for the mechanism for connecting a View to a PV is:
68

7-
![Basic principle](basic_principle.png)
9+
<img src="connect_view_to_pv_basic_principle.png" width=750>
810

911
## Adding an Observable
1012

doc/client/coding/Databinding---common-mistakes.md

Lines changed: 0 additions & 40 deletions
This file was deleted.

doc/client/coding/Databinding.md

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Databinding
22

3-
Note: there are some helpful tips to common errors/mistakes [here](Databinding---common-mistakes).
3+
:::{seealso}
4+
[How to connect a view to a PV](Connecting-a-View-to-a-PV)
5+
:::
46

5-
Note: an explanation of how to connect a view to a PV is [here](Connecting-a-View-to-a-PV)
6-
7-
## Create the example plug-ins ##
7+
## Create the example plug-ins
88

99
First create an Eclipse plug-in for the back-end:
1010

@@ -384,4 +384,47 @@ myViewer.setInput(BeanProperties.list("names").observe(myViewModel));
384384
List myList = myViewer.getList();
385385
```
386386

387-
`ListViewer` is a wrapper around the List control that provides extra functionality and `ObservableListContentProvider` make the databinding work.
387+
`ListViewer` is a wrapper around the List control that provides extra functionality and `ObservableListContentProvider` make the databinding work.
388+
389+
## Troubleshooting
390+
391+
### Missing getter or setter (or incorrectly named)
392+
393+
The getter and setters (if the value can be set from the UI) must exist and be named correctly. For example: `getName` and `setName` for `BeanProperties.value("name")`.
394+
395+
Behind the scenes the databinding library automatically changes the first character to upper-case and then prepends "get" and "set".
396+
397+
### Incorrectly cased string in binding
398+
399+
With something like the following it is import that the name of the property to bind to is cased correctly:
400+
```java
401+
ctx.bindValue(WidgetProperties.text(SWT.Modify)
402+
.observe(txtAge), BeanProperties.value("age").observe(person));
403+
```
404+
405+
This assumes there is a getter and setter called `getAge` and `setAge`.
406+
407+
For something like `getFedId` the binding code would look like:
408+
409+
```java
410+
ctx.bindValue(WidgetProperties.text(SWT.Modify)
411+
.observe(txtId), BeanProperties.value("fedId").observe(person));
412+
```
413+
414+
:::{important}
415+
The 'f' of `fedId` is lower-case. It will not work if it is upper-case.
416+
:::
417+
418+
### The getter or setter "silently" throws an exception
419+
420+
If any code in the getter throws an unhandled exception then the binding won't work because the value cannot be read.
421+
If a setter throws an unhandled exception before the firing the property change then the listeners will not receive the change signal. Both result in the binding being broken.
422+
423+
If a binding seems to work intermittently then there might be something in the getter or setter causing this, e.g. an object used in a getter that switches between being null and initialised based on something else.
424+
425+
The exceptions will appear in the console inside Eclipse and IBEX, but won't cause an error pop-up to appear.
426+
427+
### The binding works but the initial value is not put in the widget
428+
429+
When the binding first happens it will call the getter to set the widget properties to whatever is in the model.
430+
If this doesn't happen, the getter is probably non-existent or not implemented correctly.
Lines changed: 52 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
# Conventions
1+
# GUI Coding Conventions
22

3-
Contains the style and coding conventions for the IBEX GUI.
3+
:::{note}
4+
New conventions should not be added to this document without first being discussed at a
5+
[code chat](/processes/meetings/Code-Chats-and-Lightning-Talks) or a group code-review session.
6+
:::
47

5-
**New conventions should not be added to this document without first being discussed at a 'Code Chat'.**
8+
## Style Conventions
69

7-
## Style Conventions #
10+
Unless stated otherwise below, we should follow the standard Java conventions for style where possible.
811

9-
Unless stated otherwise below we should follow the standard Java conventions for style where possible.
10-
11-
## Code documentation ##
12+
## Documentation
1213

1314
Classes and public methods should be documented using the Javadoc syntax. For example:
1415

@@ -46,7 +47,7 @@ public class CustomPizza extends Pizza {
4647
}
4748
}
4849
```
49-
For Getters it is okay to skip the first sentence and do the following as it saves repetition:
50+
For getters, it is acceptable to skip the first sentence and do the following as it saves repetition:
5051
```java
5152
/**
5253
* @return true if the block is enabled
@@ -56,9 +57,16 @@ public boolean getEnabled() {
5657
}
5758
```
5859

59-
## Code formatting ##
60+
Inline comments should have a space between the // and the text, and start with a capital letter:
61+
```java
62+
// This is a good comment
63+
64+
//this is a bad comment
65+
```
6066

61-
For Java use the standard conventions built in to the IBEX developer's version of Eclipse.
67+
## Code formatting
68+
69+
For Java use the standard conventions built in to Eclipse.
6270

6371
An example of what it looks like:
6472
```java
@@ -78,58 +86,18 @@ void foo2() {
7886
```
7987
In Eclipse, a quick way to auto-format the code correctly is to use Ctrl+Shift+F.
8088

81-
## Code comments ##
82-
83-
Comments should have a space between the // and the text, and start with a capital letter:
84-
```java
85-
// This is a good comment
86-
87-
//this is a bad comment
88-
```
89-
90-
## Checkstyle ##
91-
92-
Code should be run through Checkstyle via Eclipse and corrected (within reason) before being committed.
93-
The Checkstyle plug-in is installed as part of the IBEX developer's version of Eclipse.
94-
95-
The Checkstyle configuration file for Eclipse is more picky that the one used on Jenkins as it warns about 'magic numbers' and 'Java-docs'.
96-
97-
By right-clicking on a file one can tell Checkstyle to check that file.
89+
## Naming conventions
9890

99-
Warnings must be fixed where possible.
91+
### General
10092

101-
Checkstyle has a suppress warning flag that tells it to ignore certain warning; warnings that are allowed to be suppressed are:
93+
We use the [standard Java naming conventions](https://www.oracle.com/java/technologies/javase/codeconventions-namingconventions.html):
94+
- Class names are CamelCase and usually nouns, e.g. `FileReader` not `ReadsFile`
95+
- Method names are Mixed Case (also known as Lower CamelCase), e.g. `sayHello`
96+
- Package names are lowercase, e.g. `uk.ac.stfc.isis.dae`
97+
- Variable names are Mixed Case, e.g. `calculateMeanSpeed`
98+
- Constants are uppercase spaced by underscores, e.g. `SECONDS_PER_FORTNIGHT`
10299

103-
* Magic numbers - if it is related to a GUI layout then suppress them.
104-
105-
* Name must match pattern - ignore GUI names that don't match the recommended pattern (e.g. `gd_switchToCombo`)
106-
107-
Suppression example:
108-
109-
```java
110-
@SuppressWarnings({ "checkstyle:magicnumber", "checkstyle:localvariablename" })
111-
public void getSecondsInHours(int hours) {
112-
int seconds_per_hour = 60 * 60; // Magic numbers and a bad variable name
113-
return hours * seconds_per_hour;
114-
}
115-
```
116-
## Naming conventions ##
117-
118-
### General ###
119-
120-
In general we use the standard Java naming conventions, e.g.:
121-
122-
* Class names are CamelCase and usually nouns, e.g. `FileReader` not `ReadsFile`
123-
124-
* Method names are Mixed Case (also known as Lower CamelCase), e.g. `sayHello`
125-
126-
* Package names are lowercase, e.g. `uk.ac.stfc.isis.dae`
127-
128-
* Variable names are Mixed Case, e.g. `calculateMeanSpeed`
129-
130-
* Constants are uppercase spaced by underscores, e.g. `SECONDS_PER_FORTNIGHT`
131-
132-
### Getters and Setters ###
100+
### Getters and Setters
133101

134102
Getters and Setters should follow the JavaBeans convention, namely:
135103

@@ -163,45 +131,34 @@ class Point {
163131
}
164132
```
165133

166-
## Coding Conventions ##
134+
## Coding Conventions
167135

168-
A mix of IBEX specific and general Java coding conventions.
169-
170-
### GUI code must use a View Model ###
136+
### GUI code should use a model-view-viewmodel (MVVM) pattern
171137

172138
This maintains a separation between pure GUI code and the back-end. It also makes it easier for us to test our code.
173-
See the previous GUI Chat slides for more information.
174-
175-
Some legacy code does not have a View Model, this is on the list to fix.
139+
See the [previous GUI Chat slides](/processes/meetings/Code-Chats-and-Lightning-Talks) for more information.
176140

177-
### Use data-binding for GUI items ###
141+
### Use data-binding for GUI items
178142

179-
~~For connecting UI elements to data from the View Model use data-binding.
180-
It seems that if a mix of data-binding and more traditional SWT wiring up is used (e.g. AddPropertyChangeListener) then the data-binding will stop working*, so always using data-binding should avoid this problem.~~
143+
For connecting UI elements to data from the View Model, prefer to use [databinding](Databinding) where possible.
181144

182-
~~*This does need more investigation to find out why it occurs.~~
145+
### Don't mess with finalizers
183146

184-
This no longer seems to apply.
185-
186-
### Don't mess with finalizers ###
187-
From the Google Java Style Guide:
188-
189-
```
190-
It is extremely rare to override Object.finalize.
191-
192-
Tip: Don't do it. If you absolutely must, first read and understand Effective Java Item 7, "Avoid Finalizers," very carefully, and then don't do it.
193-
```
194-
195-
As of Java 9, `finalize` is officially deprecated in java. The IBEX checkstyle configuration is configured to disallow finalizers - this check should not be disabled or overridden.
147+
In Java versions >=9, `finalize` is deprecated and marked for removal from Java. The IBEX checkstyle configuration
148+
is configured to disallow finalizers - this check must not be disabled or overridden.
196149

197150
The remaining options for supported clean-up mechanisms (in preference order) are:
198-
- Implement `autocloseable` and use the class in a try-with-resources statement to ensure the relevant resource is closed
199-
- Use a `closeable` and manually call `close` to ensure the relevant resource is closed
151+
- Implement `AutoCloseable` and use the class in a try-with-resources statement to ensure the relevant resource is closed
152+
- Use a `Closeable` and manually call `close` to ensure the relevant resource is closed
200153
- Refactor to avoid needing to close the resource at all
201-
- Use a *supported* automatic clean-up mechanism such as `PhantomReference` or `Cleaner` only as a last resort. While these are *better* than finalizers, they still suffer from high complexity and are tricky to get right. In particular it is easy to accidentally create reference loops meaning that objects will never be cleaned.
154+
- Use a *supported* automatic clean-up mechanism such as `PhantomReference` or `Cleaner` only as a last resort.
155+
While these are *better* than finalizers, they still suffer from high complexity and are tricky to get right.
156+
In particular, it is easy to accidentally create reference loops meaning that objects will never be cleaned.
157+
158+
### Return a empty collection or stream, not null
202159

203-
### Return a empty collection or stream, not null ###
204-
For methods that return arrays/lists/maps/sets/streams etc. don't return null. It is cleaner to return an empty instance as the calling code does not need to check for null.
160+
For methods that return arrays/lists/maps/sets/streams etc. don't return null. It is cleaner to return an empty
161+
instance as the calling code does not need to check for null.
205162

206163
```java
207164
// Avoids this extra check in the caller
@@ -211,14 +168,18 @@ if (cars != null && cars.contains("mustang") {
211168
```
212169
See Effective Java Item 43 "Return empty arrays or collections, not nulls"
213170

214-
### Prefer StringBuilder for string concatenation ###
215-
Using `+` is fine for, say, joining two or three short strings but it is inefficient for larger numbers of strings and longer strings. Use StringBuilder instead.
171+
### Prefer StringBuilder for string concatenation
172+
173+
Using `+` is fine for, say, joining two or three short strings, but it is inefficient for larger numbers of strings and
174+
longer strings. Use `StringBuilder` instead.
216175

217176
See Effective Java Item 51 "Beware the performance of string concatenation"
218177

219178
### Prefer `Optional` over `null`
220179

221-
New APIs should not return null to indicate a missing value. Instead, return an Optional wrapping the value which may not exist. Where external code returns null to indicate a missing value, this should be wrapped in an optional as soon as reasonable.
180+
New APIs should not return null to indicate a missing value. Instead, return an `Optional` wrapping the value which may
181+
not exist. Where external code returns null to indicate a missing value, this should be wrapped in an optional as soon
182+
as reasonable.
222183

223184
To convert a maybe-null value to an optional, use:
224185
```java
@@ -236,7 +197,7 @@ String str = mightNotExist.orElse(null);
236197

237198
Streams should be used where they make an algorithm clearer.
238199

239-
When using streams, put each operation on it's own line.
200+
When using streams, put each operation on its own line.
240201

241202
Good:
242203
```java
@@ -254,5 +215,3 @@ public Stream<String> getNames() {
254215
return getThings().map(thing -> thing.getName()).filter(name -> name != "").sorted();
255216
}
256217
```
257-
258-
Binary file not shown.

doc/client/coding/Instrument-switching.md

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)