Libraryless. Click here for Pure Java version (16387L/99K).
1 | srecord noeq JTextFileEditor(File file) is Swingable { |
2 | settable bool autoSave; |
3 | settable bool wordWrap = true; |
4 | gettable bool uneditable; |
5 | |
6 | gettable JTextArea textArea; |
7 | JButton btnReload, btnSave; |
8 | JLabel lblChanged; |
9 | volatile S fileContents, savedText; |
10 | FileWatchService fileWatcher; |
11 | Q q = startQ(); |
12 | RSTOverQ rstLoad = rstWithPreDelay(0.5, q, r _load); |
13 | RSTOverQ rstSave; |
14 | JPanel buttons; |
15 | SingleComponentPanel scpButtons = singleComponentPanel(); |
16 | |
17 | cachedVisualize { |
18 | assertNotNull(file); |
19 | rstSave = rstWithPreDelay(autoSave ? 0.5 : 0.0, q, r _save); |
20 | savedText = fileContents = loadTextFile(file); |
21 | textArea = makeTextArea(); |
22 | if (uneditable) makeUneditable(textArea); |
23 | if (wordWrap) enableWordWrapForTextArea(textArea); |
24 | setText(savedText); |
25 | onChange(textArea, -> { |
26 | updateButtons(); |
27 | if (autoSave) rstSave!; |
28 | }); |
29 | |
30 | // Ctrl+S to save text |
31 | addKeyListener(textArea(), ctrlLetterKeyListener('s', rstSave)); |
32 | |
33 | bindToComponent(textArea, -> { |
34 | fileWatcher = new FileWatchService; |
35 | fileWatcher.addNonRecursiveListener(dirOfFile(file), |
36 | f -> { if (sameFile(f, file)) rstLoad!; }); |
37 | rstLoad!; |
38 | }, -> { dispose fileWatcher; }); |
39 | |
40 | scpButtons.set(buttons = makeButtons()); |
41 | |
42 | ret northAndCenter( |
43 | withSideMargin(10, 20, centerAndEastWithMargin( |
44 | new JFilePathLabel(file).iconOnTheLeft(true).minWidth(true).visualize(), |
45 | scpButtons)), |
46 | withMargin(textAreaLayoutComponent()) |
47 | ); |
48 | } |
49 | |
50 | JPanel makeButtons() { |
51 | btnSave = btnReload = null; |
52 | ret jline( |
53 | uneditable ? null |
54 | : autoSave |
55 | ? (lblChanged = jlabel()) |
56 | : (btnSave = disableButton(jbutton("Save", rstSave))), |
57 | uneditable ? null : (btnReload = jbutton("Reload", r reload)) |
58 | ); |
59 | } |
60 | |
61 | swappable JComponent textAreaLayoutComponent() { ret jscroll(textArea()); } |
62 | |
63 | void updateButtons { |
64 | bool changed = !eq(savedText, getText(textArea)); |
65 | setEnabled(btnSave, changed); |
66 | setEnabled(btnReload, !eq(fileContents, savedText)); |
67 | main setText(lblChanged, changed ? "*" : ""); |
68 | } |
69 | |
70 | void _save { |
71 | if (!uneditable) |
72 | saveTextFileVerbose(file, savedText = getText(textArea)); |
73 | } |
74 | |
75 | void reload { |
76 | savedText = fileContents; |
77 | setText(savedText); |
78 | updateButtons(); |
79 | } |
80 | |
81 | void _load { |
82 | print("Loading " + file); |
83 | fileContents = loadTextFile(file); |
84 | updateButtons(); |
85 | if (uneditable) reload(); |
86 | } |
87 | |
88 | swappable JTextArea makeTextArea() { |
89 | ret jTypeWriterTextArea(); |
90 | } |
91 | |
92 | void setText(S text) { |
93 | main setText(textArea(), text); |
94 | } |
95 | |
96 | JPanel buttons() { |
97 | visualize(); |
98 | ret buttons; |
99 | } |
100 | |
101 | selfType uneditable(bool b) { |
102 | if (uneditable == b) this; |
103 | uneditable = b; |
104 | if (buttons != null) { |
105 | scpButtons.set(buttons = makeButtons()); |
106 | setEditable(textArea(), true); |
107 | } |
108 | this; |
109 | } |
110 | } |
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1034689 |
Snippet name: | JTextFileEditor |
Eternal ID of this version: | #1034689/46 |
Text MD5: | 7d72869325f23ca1fd2aa32903c12c16 |
Transpilation MD5: | 1e16a9634ca0390f12af803f6687e344 |
Author: | stefan |
Category: | javax / gui |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-07-30 00:51:32 |
Source code size: | 2998 bytes / 110 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 235 / 519 |
Version history: | 45 change(s) |
Referenced in: | [show references] |