Skip to content

Commit 73f1287

Browse files
committed
copyedit gui coding section
1 parent 5ea52ee commit 73f1287

13 files changed

+232
-302
lines changed

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

+40-1
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,45 @@ by default this value is set to true and so perspectives are displayed.
347347

348348
To subsequently display the perspective run IBEX and go to the perspective window (CTRL + ALT + P) then enable the checkbox in ISIS Perspectives. On the next restart of the GUI your perspective should be displayed.
349349

350-
### Troubleshooting
350+
## Adding a button to the E4 Perspective switcher
351+
352+
### Migrating an E3 perspective to E4
353+
354+
1. Open the Application.e4xmi from `uk.ac.stfc.isis.ibex.e4.client`
355+
1. Go to `Snippets`
356+
1. Click `Add` to add a new perspective
357+
1. Set the perspective up using an existing migrated perspective as a template
358+
1. Set a sensible ID
359+
1. Give it a label
360+
1. If you want your perspective to be invisible toggle the visible checkbox
361+
1. Set the icon
362+
1. Add controls. This should be a hierarchy of part sash containers. You can see how it should be set up from the existing perspectives. Don't forget to set the container data where appropriate; it sets the relative size of sibling components.
363+
1. Add the perspective-specific parts
364+
1. In the alarms perspective, you'll see one part in the final part sash container called alarms. Do the same thing in your new perspective, but give it an appropriate name
365+
1. Change the ID of your new part to the ID of the view class you want the perspective to open
366+
1. Add the dependency of the view you've added to the `plugin.xml` in the `...e4.client` plugin
367+
1. Add the new dependency to `...feature.xml` (in `uk.ac.stfc.isis.ibex.feature.base`)
368+
1. Synchronize `ibex.product` (in `...e4.client.product`)
369+
1. Open IBEX
370+
1. Check the new perspective scales appropriately and change the layout accordingly if needed
371+
372+
### Creating a brand new E4 perspective
373+
374+
Making a brand new E4 perspective would probably look similar to the steps above, minus the E3 steps. However, a new E4 perspective has yet to been attempted.
375+
376+
### Hiding Perspectives
377+
378+
Perspectives can be hidden by adding perspective IDs to the Eclipse preference store at the preference key `uk.ac.stfc.isis.ibex.preferences/perspectives_not_shown` (at `/uk.ac.stfc.isis.ibex.e4.client/plugin_customization.ini`). e.g.
379+
380+
```
381+
uk.ac.stfc.isis.ibex.preferences/perspectives_not_shown=uk.ac.stfc.isis.ibex.client.e4.product.perspective.scriptGenerator
382+
```
383+
Note: Multiple perspectives can be hidden using a comma separated list of perspective IDs. e.g.
384+
385+
```
386+
uk.ac.stfc.isis.ibex.preferences/perspectives_not_shown=uk.ac.stfc.isis.ibex.client.e4.product.perspective.scriptGenerator,uk.ac.stfc.isis.ibex.client.e4.product.perspective.dae
387+
```
388+
389+
## Troubleshooting
351390

352391
If the perspective is not being shown in the switcher at the side it may be Eclipse being silly or you may not be running the right product. Be sure to re-run by going selecting the client product, rather than using the drop-down (which will run the same product as you used previously) Finally, try clearing the workspace and resetting the target platform etc.

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

+1-1
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

+5-3
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

-40
This file was deleted.

doc/client/coding/Databinding.md

+48-5
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.
+52-93
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-

0 commit comments

Comments
 (0)