Skip to content

Commit 34036f2

Browse files
committed
Update rule editor font size immediately
Add support for listening to preference changes. Use this to immediately update editor fonts when the user changes the preference. This makes the new shortcuts very handy.
1 parent 8378799 commit 34036f2

File tree

4 files changed

+108
-32
lines changed

4 files changed

+108
-32
lines changed

src/main/java/edu/umich/soar/visualsoar/dialogs/prefs/PreferencesDialog.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public PreferencesDialog(final Frame owner) {
8787
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
8888
editorFontPanel.add(Box.createHorizontalBox());
8989
editorFontPanel.add(new JLabel("Font Size: "));
90-
editorFontField.setText(String.valueOf(SoarDocument.getFontSize()));
90+
editorFontField.setText(Prefs.editorFontSize.get());
9191
editorFontPanel.add(editorFontField);
9292

9393
ruleEditorPanel.setLayout(new BoxLayout(ruleEditorPanel, BoxLayout.Y_AXIS));
@@ -155,8 +155,7 @@ public void actionPerformed(ActionEvent e) {
155155

156156
// Set a new font size
157157
int fontSize = getFontSize();
158-
if (fontSize != SoarDocument.getFontSize()) {
159-
SoarDocument.setFontSize(fontSize);
158+
if (fontSize != Prefs.editorFontSize.getInt()) {
160159
Prefs.editorFontSize.setInt(fontSize);
161160
}
162161
}
@@ -168,7 +167,7 @@ public void actionPerformed(ActionEvent e) {
168167
* enforce min/max rules.
169168
*/
170169
private int getFontSize() {
171-
int fontSize = SoarDocument.getFontSize();
170+
int fontSize = Prefs.editorFontSize.getInt();
172171
try {
173172
fontSize = Integer.parseInt(editorFontField.getText());
174173
} catch (NumberFormatException nfe) {

src/main/java/edu/umich/soar/visualsoar/misc/Prefs.java

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,17 @@
99
import java.io.IOException;
1010
import java.io.PrintWriter;
1111
import java.nio.file.FileSystems;
12+
import java.util.ArrayList;
13+
import java.util.List;
1214
import java.util.Vector;
1315
import java.util.prefs.BackingStoreException;
1416
import java.util.prefs.Preferences;
1517

18+
/**
19+
* Preference values are persisted on the user's computer. Clients can listen for changes by
20+
* creating a {@link PrefsChangeListener} and passing it to {@link
21+
* #addChangeListener(PrefsChangeListener)} for the particular preference of interest.
22+
*/
1623
public enum Prefs {
1724
openFolder(System.getProperty("user.dir")),
1825
autoTileEnabled(true),
@@ -347,6 +354,15 @@ public static void addRecentProject(File newbie, boolean readOnly) {
347354
private final boolean defBoolean;
348355
private final int defInt;
349356

357+
public interface PrefsChangeListener {
358+
/**
359+
* @param newValue new String, boolean, or integer value
360+
*/
361+
void onPreferenceChanged(Object newValue);
362+
}
363+
364+
private final List<PrefsChangeListener> listeners = new ArrayList<>();
365+
350366
Prefs(String def) {
351367
this.def = def;
352368
this.defBoolean = false;
@@ -365,36 +381,52 @@ public static void addRecentProject(File newbie, boolean readOnly) {
365381
this.defInt = def;
366382
}
367383

368-
public String get() {
369-
return preferences.get(this.toString(), def);
370-
}
384+
public void addChangeListener(PrefsChangeListener listener) {
385+
listeners.add(listener);
386+
}
371387

372-
public void set(String value) {
373-
preferences.put(this.toString(), value);
374-
}
388+
public void removeChangeListener(PrefsChangeListener listener) {
389+
listeners.remove(listener);
390+
}
375391

376-
public boolean getBoolean() {
377-
return preferences.getBoolean(this.toString(), defBoolean);
392+
private void notifyListeners(Object newValue) {
393+
for (PrefsChangeListener listener : listeners) {
394+
listener.onPreferenceChanged(newValue);
378395
}
396+
}
379397

380-
public void setBoolean(boolean value) {
381-
preferences.putBoolean(this.toString(), value);
382-
}
398+
public String get() {
399+
return preferences.get(this.toString(), def);
400+
}
401+
402+
public void set(String value) {
403+
preferences.put(this.toString(), value);
404+
notifyListeners(value);
405+
}
406+
407+
public boolean getBoolean() {
408+
return preferences.getBoolean(this.toString(), defBoolean);
409+
}
410+
411+
public void setBoolean(boolean value) {
412+
preferences.putBoolean(this.toString(), value);
413+
notifyListeners(value);
414+
}
383415

384416
public int getInt() {
385417
return preferences.getInt(this.toString(), defInt);
386418
}
387419

388420
public void setInt(int value) {
389421
preferences.putInt(this.toString(), value);
422+
notifyListeners(value);
390423
}
391424

392-
public static void flush() {
393-
try {
394-
preferences.flush();
395-
} catch (BackingStoreException e) {
396-
e.printStackTrace();
397-
}
425+
public static void flush() {
426+
try {
427+
preferences.flush();
428+
} catch (BackingStoreException e) {
429+
e.printStackTrace();
398430
}
399-
431+
}
400432
}

src/main/java/edu/umich/soar/visualsoar/ruleeditor/EditorPane.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,17 @@ public void read(Reader in) throws IOException {
258258
}
259259
}
260260

261+
@Override
262+
public void removeNotify() {
263+
super.removeNotify();
264+
265+
// perform document cleanup
266+
SoarDocument doc = getSoarDocument();
267+
if (doc != null) {
268+
doc.close();
269+
}
270+
}
271+
261272
/** Colors the syntax of the whole document */
262273
public void colorSyntax() {
263274
getSoarDocument().colorSyntax(new StringReader(getText()));

src/main/java/edu/umich/soar/visualsoar/ruleeditor/SoarDocument.java

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import edu.umich.soar.visualsoar.misc.SyntaxColor;
66
import edu.umich.soar.visualsoar.parser.*;
77

8+
import javax.swing.*;
9+
import javax.swing.event.DocumentEvent;
810
import javax.swing.text.*;
911
import java.awt.*;
1012
import java.io.IOException;
@@ -34,27 +36,51 @@ public class SoarDocument extends DefaultStyledDocument {
3436

3537
/** to support Read-Only mode */
3638
public boolean isReadOnly = false;
39+
private Prefs.PrefsChangeListener fontSizeListener;
3740

3841

39-
public SoarDocument() {
42+
public SoarDocument() {
4043
colorTable = Prefs.getSyntaxColors().clone();
4144

4245
//set font size and style
4346
Style defaultStyle = this.getStyle("default");
4447
MutableAttributeSet attributeSet = new SimpleAttributeSet();
45-
SoarDocument.fontSize = Integer.parseInt(Prefs.editorFontSize.get());
46-
StyleConstants.setFontSize(attributeSet, SoarDocument.fontSize);
48+
StyleConstants.setFontSize(attributeSet, Prefs.editorFontSize.getInt());
4749
defaultStyle.addAttributes(attributeSet);
48-
}
4950

50-
public static int getFontSize() {
51-
return SoarDocument.fontSize;
52-
}
51+
fontSizeListener = newVal -> {
52+
try {
53+
int newFontSize = (int) newVal;
54+
setFontSize(newFontSize);
55+
} catch (ClassCastException e) {
56+
e.printStackTrace();
57+
}
58+
};
5359

54-
public static void setFontSize(int size) {
55-
SoarDocument.fontSize = size;
60+
Prefs.editorFontSize.addChangeListener(fontSizeListener);
5661
}
5762

63+
public void setFontSize(int size) {
64+
SoarDocument.fontSize = size;
65+
66+
// Create or update a style for the font size
67+
StyleContext context = StyleContext.getDefaultStyleContext();
68+
Style fontStyle = context.getStyle(StyleContext.DEFAULT_STYLE);
69+
70+
// Update the font size in the style
71+
MutableAttributeSet attributeSet = new SimpleAttributeSet();
72+
StyleConstants.setFontSize(attributeSet, size);
73+
fontStyle.addAttributes(attributeSet);
74+
75+
// Apply the updated style to the entire document
76+
SwingUtilities.invokeLater(() -> {
77+
setCharacterAttributes(0, getLength(), attributeSet, false);
78+
79+
// Notify observers to repaint the editor
80+
fireChangedUpdate(new DefaultDocumentEvent(0, getLength(), DocumentEvent.EventType.CHANGE));
81+
});
82+
}
83+
5884
public String getLastInsertedText() {
5985
return this.lastInsertedText;
6086
}
@@ -1158,5 +1184,13 @@ public String cropComments(String prevLine) {
11581184
return prevLine;
11591185
}
11601186

1161-
1187+
/** Cleanup method to be called when the document is closed. */
1188+
public void close() {
1189+
// Remove the font size listener so that we don't accumulate them every time a new window
1190+
// is opened and closed
1191+
if (fontSizeListener != null) {
1192+
Prefs.editorFontSize.removeChangeListener(fontSizeListener);
1193+
fontSizeListener = null;
1194+
}
1195+
}
11621196
} // class SoarDocument

0 commit comments

Comments
 (0)