Skip to content

Commit 9bdd822

Browse files
Merge pull request #553 from JordanMartinez/easierCustomObjectSupport
Easier custom object support
2 parents 14776d2 + e6b8404 commit 9bdd822

3 files changed

Lines changed: 135 additions & 55 deletions

File tree

Lines changed: 8 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,21 @@
11
package org.fxmisc.richtext.demo.richtext;
22

3-
import java.util.Optional;
3+
import org.fxmisc.richtext.model.NodeSegmentOpsBase;
44

5-
import org.fxmisc.richtext.model.SegmentOps;
5+
public class LinkedImageOps<S> extends NodeSegmentOpsBase<LinkedImage<S>, S> {
66

7-
public class LinkedImageOps<S> implements SegmentOps<LinkedImage<S>, S> {
8-
9-
private final EmptyLinkedImage<S> emptySeg = new EmptyLinkedImage<>();
10-
11-
@Override
12-
public int length(LinkedImage<S> seg) {
13-
return seg == emptySeg ? 0 : 1;
14-
}
15-
16-
@Override
17-
public char charAt(LinkedImage<S> seg, int index) {
18-
return seg == emptySeg ? '\0' : '\ufffc';
19-
}
20-
21-
@Override
22-
public String getText(LinkedImage<S> seg) {
23-
return seg == emptySeg ? "" : "\ufffc";
24-
}
25-
26-
@Override
27-
public LinkedImage<S> subSequence(LinkedImage<S> seg, int start, int end) {
28-
if (start < 0) {
29-
throw new IllegalArgumentException("Start cannot be negative. Start = " + start);
30-
}
31-
if (end > length(seg)) {
32-
throw new IllegalArgumentException("End cannot be greater than segment's length");
33-
}
34-
return start == 0 && end == 1
35-
? seg
36-
: emptySeg;
37-
}
38-
39-
@Override
40-
public LinkedImage<S> subSequence(LinkedImage<S> seg, int start) {
41-
if (start < 0) {
42-
throw new IllegalArgumentException("Start cannot be negative. Start = " + start);
43-
}
44-
return start == 0
45-
? seg
46-
: emptySeg;
7+
public LinkedImageOps() {
8+
super(new EmptyLinkedImage<>());
479
}
4810

4911
@Override
50-
public S getStyle(LinkedImage<S> seg) {
51-
return seg.getStyle();
12+
public S realGetStyle(LinkedImage<S> linkedImage) {
13+
return linkedImage.getStyle();
5214
}
5315

5416
@Override
55-
public LinkedImage<S> setStyle(LinkedImage<S> seg, S style) {
56-
return seg == emptySeg ? emptySeg : seg.setStyle(style);
17+
public LinkedImage<S> realSetStyle(LinkedImage<S> linkedImage, S style) {
18+
return linkedImage.setStyle(style);
5719
}
5820

59-
@Override
60-
public Optional<LinkedImage<S>> join(LinkedImage<S> currentSeg, LinkedImage<S> nextSeg) {
61-
return Optional.empty();
62-
}
63-
64-
@Override
65-
public LinkedImage<S> createEmpty() {
66-
return emptySeg;
67-
}
6821
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package org.fxmisc.richtext.model;
2+
3+
/**
4+
* Properly implements {@link SegmentOps} when implementing a non-text custom object (e.g. shape, circle, image)
5+
* and reduces boilerplate. Developers only need to override {@link #realGetStyle(Object)} and
6+
* {@link #realSetStyle(Object, Object)}. Developers may also want to override {@link #join(Object, Object)}.
7+
*
8+
* @param <SEG> type of segment
9+
* @param <S> type of style
10+
*/
11+
public abstract class NodeSegmentOpsBase<SEG, S> extends SegmentOpsBase<SEG, S> {
12+
13+
public NodeSegmentOpsBase(SEG empty) {
14+
super(empty);
15+
}
16+
17+
@Override
18+
public int realLength(SEG seg) {
19+
return 1;
20+
}
21+
22+
@Override
23+
public char realCharAt(SEG seg, int index) {
24+
return '\ufffc';
25+
}
26+
27+
@Override
28+
public String realGetText(SEG seg) {
29+
return "\ufffc";
30+
}
31+
32+
@Override
33+
public SEG realSubsequence(SEG seg, int start, int end) {
34+
return seg;
35+
}
36+
37+
@Override
38+
public SEG realSubsequence(SEG seg, int start) {
39+
return seg;
40+
}
41+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package org.fxmisc.richtext.model;
2+
3+
import java.util.Optional;
4+
5+
/**
6+
* Properly implements the {@link SegmentOps} interface and reduces boilerplate, so that developer only needs to
7+
* implement methods for real segments, not empty ones. Optionally, {@link #join(Object, Object)} can be overridden
8+
* as well.
9+
*
10+
* @param <SEG> the type of segment
11+
* @param <S> the type of style
12+
*/
13+
public abstract class SegmentOpsBase<SEG, S> implements SegmentOps<SEG, S> {
14+
15+
private final SEG empty;
16+
17+
public SegmentOpsBase(SEG emptySEg) {
18+
this.empty = emptySEg;
19+
}
20+
21+
@Override
22+
public final int length(SEG seg) {
23+
return seg == empty ? 0 : realLength(seg);
24+
}
25+
public abstract int realLength(SEG seg);
26+
27+
@Override
28+
public final char charAt(SEG seg, int index) {
29+
return seg == empty ? '\0' : realCharAt(seg, index);
30+
}
31+
public abstract char realCharAt(SEG seg, int index);
32+
33+
@Override
34+
public final String getText(SEG seg) {
35+
return seg == empty ? "\0" : realGetText(seg);
36+
}
37+
public abstract String realGetText(SEG seg);
38+
39+
@Override
40+
public final SEG subSequence(SEG seg, int start, int end) {
41+
if (start < 0) {
42+
throw new IllegalArgumentException("Start cannot be negative. Start=" + start);
43+
}
44+
if (end > length(seg)) {
45+
throw new IllegalArgumentException(
46+
String.format("End cannot be greater than segment's length. End=%s Length=%s", end, length(seg))
47+
);
48+
}
49+
return seg == empty || start == end
50+
? empty
51+
: realSubsequence(seg, start, end);
52+
}
53+
public abstract SEG realSubsequence(SEG seg, int start, int end);
54+
55+
@Override
56+
public final SEG subSequence(SEG seg, int start) {
57+
return seg == empty || length(seg) == start
58+
? empty
59+
: realSubsequence(seg, start);
60+
}
61+
public SEG realSubsequence(SEG seg, int start) {
62+
return realSubsequence(seg, start, length(seg));
63+
}
64+
65+
@Override
66+
public final S getStyle(SEG seg) {
67+
return seg == empty ? null : realGetStyle(seg);
68+
}
69+
public abstract S realGetStyle(SEG seg);
70+
71+
@Override
72+
public final SEG setStyle(SEG seg, S style) {
73+
return seg == empty ? empty : realSetStyle(seg, style);
74+
}
75+
public abstract SEG realSetStyle(SEG seg, S style);
76+
77+
@Override
78+
public final Optional<SEG> join(SEG currentSeg, SEG nextSeg) {
79+
return Optional.empty();
80+
}
81+
82+
@Override
83+
public final SEG createEmpty() {
84+
return empty;
85+
}
86+
}

0 commit comments

Comments
 (0)