mirror of
https://github.com/SuspiciousActivity/ByteEdit.git
synced 2026-08-13 17:56:17 +00:00
Updated to support Java 11, but only Java 8 features
This commit is contained in:
1 parent
58c8e90c81
commit
89f9753d8b
19 files changed
+1163
-1431
No files matched your search
@@ -79,9 +79,9 @@ public class Assembler {
|
|||||||
clazz.innerClasses = new ArrayList<>();
|
clazz.innerClasses = new ArrayList<>();
|
||||||
} else {
|
} else {
|
||||||
String split[] = s.split(" ");
|
String split[] = s.split(" ");
|
||||||
clazz.innerClasses.add(new InnerClassNode(UnicodeUtils.unescape(split[1]),
|
clazz.innerClasses
|
||||||
split[2].equals("null") ? null : UnicodeUtils.unescape(split[2]),
|
.add(new InnerClassNode(UnicodeUtils.unescape(split[1]), split[2].equals("null") ? null : UnicodeUtils.unescape(split[2]),
|
||||||
split[3].equals("null") ? null : UnicodeUtils.unescape(split[3]), Integer.parseInt(split[4].substring(2), 16)));
|
split[3].equals("null") ? null : UnicodeUtils.unescape(split[3]), Integer.parseInt(split[4].substring(2), 16)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -297,9 +297,8 @@ public class Assembler {
|
|||||||
_end = new LabelNode(entry.getKey());
|
_end = new LabelNode(entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.localVariables
|
node.localVariables.add(new LocalVariableNode(sp[0], UnicodeUtils.unescape(sp[1].substring(1, sp[1].length() - 2)),
|
||||||
.add(new LocalVariableNode(sp[0], UnicodeUtils.unescape(sp[1].substring(1, sp[1].length() - 2)), signat,
|
signat, _start, _end, Integer.parseInt(sp[2].substring(0, sp[2].length() - 2))));
|
||||||
_start, _end, Integer.parseInt(sp[2].substring(0, sp[2].length() - 2))));
|
|
||||||
}
|
}
|
||||||
for (String st : tryCatchBlocksToParse) {
|
for (String st : tryCatchBlocksToParse) {
|
||||||
String[] sp = st.split(" ");
|
String[] sp = st.split(" ");
|
||||||
@@ -320,8 +319,8 @@ public class Assembler {
|
|||||||
_handler = new LabelNode(entry.getKey());
|
_handler = new LabelNode(entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.tryCatchBlocks.add(new TryCatchBlockNode(_start, _end, _handler,
|
node.tryCatchBlocks
|
||||||
sp[0].equals("null") ? null : UnicodeUtils.unescape(sp[0])));
|
.add(new TryCatchBlockNode(_start, _end, _handler, sp[0].equals("null") ? null : UnicodeUtils.unescape(sp[0])));
|
||||||
}
|
}
|
||||||
clazz.methods.add(node);
|
clazz.methods.add(node);
|
||||||
// signature = null;
|
// signature = null;
|
||||||
@@ -643,8 +642,8 @@ public class Assembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new FrameNode(Integer.parseInt(str1.split(" ")[0]), local != null ? local.length : 0, local,
|
return new FrameNode(Integer.parseInt(str1.split(" ")[0]), local != null ? local.length : 0, local, stack != null ? stack.length : 0,
|
||||||
stack != null ? stack.length : 0, stack);
|
stack);
|
||||||
} else {
|
} else {
|
||||||
String[] split = s.split(" ");
|
String[] split = s.split(" ");
|
||||||
String command = split[0];
|
String command = split[0];
|
||||||
@@ -694,12 +693,12 @@ public class Assembler {
|
|||||||
if (str.startsWith("Type: ")) {
|
if (str.startsWith("Type: ")) {
|
||||||
str = str.substring(8, str.length() - 2);
|
str = str.substring(8, str.length() - 2);
|
||||||
String[] split2 = str.split("\n\t");
|
String[] split2 = str.split("\n\t");
|
||||||
Constructor<Type> constr = Type.class.getDeclaredConstructor(int.class, char[].class, int.class, int.class);
|
Constructor<Type> constr = Type.class.getDeclaredConstructor(int.class, String.class, int.class, int.class);
|
||||||
constr.setAccessible(true);
|
constr.setAccessible(true);
|
||||||
String type = split2[0].substring(7);
|
String type = split2[0].substring(7);
|
||||||
val = constr.newInstance(new Object[] { ClassUtil.getIDFromClassNameForType(type),
|
val = constr.newInstance(
|
||||||
split2[3].substring(6, split2[3].length() - 1).toCharArray(), Integer.parseInt(split2[1].substring(5)),
|
new Object[] { ClassUtil.getIDFromClassNameForType(type), split2[3].substring(6, split2[3].length() - 1),
|
||||||
Integer.parseInt(split2[2].substring(5)) });
|
Integer.parseInt(split2[1].substring(7)), Integer.parseInt(split2[2].substring(5)) });
|
||||||
} else if (str.startsWith("\"") && str.endsWith("\"")) {
|
} else if (str.startsWith("\"") && str.endsWith("\"")) {
|
||||||
val = UnicodeUtils.unescape(str.substring(1, str.length() - 1));
|
val = UnicodeUtils.unescape(str.substring(1, str.length() - 1));
|
||||||
} else if (str.endsWith("l")) {
|
} else if (str.endsWith("l")) {
|
||||||
@@ -1226,8 +1225,7 @@ public class Assembler {
|
|||||||
arr[counter] = ln;
|
arr[counter] = ln;
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
return new TableSwitchInsnNode(Integer.parseInt(split2[0].substring(5)), Integer.parseInt(split2[1].substring(5)), dflt,
|
return new TableSwitchInsnNode(Integer.parseInt(split2[0].substring(5)), Integer.parseInt(split2[1].substring(5)), dflt, arr);
|
||||||
arr);
|
|
||||||
}
|
}
|
||||||
case "lookupswitch": {
|
case "lookupswitch": {
|
||||||
String str = s.substring(15, s.length() - 2).replace("\t", "");
|
String str = s.substring(15, s.length() - 2).replace("\t", "");
|
||||||
@@ -1375,19 +1373,18 @@ public class Assembler {
|
|||||||
if (st.equals("]")) {
|
if (st.equals("]")) {
|
||||||
if (stage == 1) {
|
if (stage == 1) {
|
||||||
try {
|
try {
|
||||||
Constructor<Type> constr = Type.class.getDeclaredConstructor(int.class, char[].class, int.class,
|
Constructor<Type> constr = Type.class.getDeclaredConstructor(int.class, String.class, int.class, int.class);
|
||||||
int.class);
|
|
||||||
constr.setAccessible(true);
|
constr.setAccessible(true);
|
||||||
args.add(constr.newInstance(new Object[] { Integer.parseInt(vals.get(0).substring(6)),
|
args.add(constr.newInstance(new Object[] { Integer.parseInt(vals.get(0).substring(6)),
|
||||||
UnicodeUtils.unescape(vals.get(3).substring(6, vals.get(3).length() - 1)).toCharArray(),
|
UnicodeUtils.unescape(vals.get(3).substring(6, vals.get(3).length() - 1)),
|
||||||
Integer.parseInt(vals.get(1).substring(5)), Integer.parseInt(vals.get(2).substring(5)) }));
|
Integer.parseInt(vals.get(1).substring(7)), Integer.parseInt(vals.get(2).substring(5)) }));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
} else if (stage == 2) {
|
} else if (stage == 2) {
|
||||||
args.add(new Handle(Integer.parseInt(vals.get(4).substring(5)),
|
args.add(new Handle(Integer.parseInt(vals.get(4).substring(5)), UnicodeUtils.unescape(vals.get(1).substring(7)),
|
||||||
UnicodeUtils.unescape(vals.get(1).substring(7)), UnicodeUtils.unescape(vals.get(0).substring(6)),
|
UnicodeUtils.unescape(vals.get(0).substring(6)), UnicodeUtils.unescape(vals.get(2).substring(6)),
|
||||||
UnicodeUtils.unescape(vals.get(2).substring(6)), Boolean.parseBoolean(vals.get(3).substring(13))));
|
Boolean.parseBoolean(vals.get(3).substring(13))));
|
||||||
vals.clear();
|
vals.clear();
|
||||||
}
|
}
|
||||||
stage = 0;
|
stage = 0;
|
||||||
|
|||||||
@@ -139,8 +139,10 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
s += "// #Class v:" + classNode.version + "\n";
|
s += "// #Class v:" + classNode.version + "\n";
|
||||||
s += "// #Signature: " + UnicodeUtils.escapeWithSpaces(classNode.signature) + "\n";
|
s += "// #Signature: " + UnicodeUtils.escapeWithSpaces(classNode.signature) + "\n";
|
||||||
s += "// #OuterMethod: " + (classNode.outerMethod == null ? "null" : (UnicodeUtils.escapeWithSpaces(classNode.outerMethod) + " "
|
s += "// #OuterMethod: "
|
||||||
+ UnicodeUtils.escapeWithSpaces(classNode.outerMethodDesc))) + "\n";
|
+ (classNode.outerMethod == null ? "null"
|
||||||
|
: (UnicodeUtils.escapeWithSpaces(classNode.outerMethod) + " " + UnicodeUtils.escapeWithSpaces(classNode.outerMethodDesc)))
|
||||||
|
+ "\n";
|
||||||
s += "// #OuterClass: " + UnicodeUtils.escapeWithSpaces(classNode.outerClass) + "\n";
|
s += "// #OuterClass: " + UnicodeUtils.escapeWithSpaces(classNode.outerClass) + "\n";
|
||||||
s += "// #InnerClasses:\n";
|
s += "// #InnerClasses:\n";
|
||||||
if (classNode.innerClasses != null) {
|
if (classNode.innerClasses != null) {
|
||||||
@@ -163,8 +165,7 @@ public class Disassembler {
|
|||||||
if (!interfaceStr.isEmpty())
|
if (!interfaceStr.isEmpty())
|
||||||
s += "implements " + interfaceStr + " ";
|
s += "implements " + interfaceStr + " ";
|
||||||
}
|
}
|
||||||
s += "{\n// #SourceFile: " + (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(classNode.sourceFile))
|
s += "{\n// #SourceFile: " + (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(classNode.sourceFile)) + "\n\n// #Fields\n";
|
||||||
+ "\n\n// #Fields\n";
|
|
||||||
for (FieldNode fn : classNode.fields) {
|
for (FieldNode fn : classNode.fields) {
|
||||||
if (fn.signature != null)
|
if (fn.signature != null)
|
||||||
s += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(fn.signature) + "\n";
|
s += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(fn.signature) + "\n";
|
||||||
@@ -227,8 +228,8 @@ public class Disassembler {
|
|||||||
s += "\n";
|
s += "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient") + UnicodeUtils.escapeWithSpaces(fn.desc)
|
s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient") + UnicodeUtils.escapeWithSpaces(fn.desc) + " "
|
||||||
+ " " + UnicodeUtils.escapeWithSpaces(fn.name);
|
+ UnicodeUtils.escapeWithSpaces(fn.name);
|
||||||
if (fn.value != null) {
|
if (fn.value != null) {
|
||||||
s += " = " + ClassUtil.getDecompiledValue(fn.value, fn.desc, true);
|
s += " = " + ClassUtil.getDecompiledValue(fn.value, fn.desc, true);
|
||||||
}
|
}
|
||||||
@@ -323,8 +324,8 @@ public class Disassembler {
|
|||||||
s += dis[0];
|
s += dis[0];
|
||||||
s += "\t}\n\n";
|
s += "\t}\n\n";
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
s += "\t\t// Method couldn't be disassembled:\n\t\t// " + e.getClass().getName() + ": " + e.getMessage() + "\n" + Arrays
|
s += "\t\t// Method couldn't be disassembled:\n\t\t// " + e.getClass().getName() + ": " + e.getMessage() + "\n"
|
||||||
.toString(e.getStackTrace()).replace(", ", "\n\t\t// \tat ").replace("[", "\t\t// \tat ").replace("]", "")
|
+ Arrays.toString(e.getStackTrace()).replace(", ", "\n\t\t// \tat ").replace("[", "\t\t// \tat ").replace("]", "")
|
||||||
+ "\n\t}\n\n";
|
+ "\n\t}\n\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -427,38 +428,36 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
case "InvokeDynamicInsnNode": {
|
case "InvokeDynamicInsnNode": {
|
||||||
InvokeDynamicInsnNode node = (InvokeDynamicInsnNode) n;
|
InvokeDynamicInsnNode node = (InvokeDynamicInsnNode) n;
|
||||||
String s = "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " [\n\t\t\tname: "
|
String s = "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " [\n\t\t\tname: " + UnicodeUtils.escapeWithSpaces(node.name)
|
||||||
+ UnicodeUtils.escapeWithSpaces(node.name) + "\n\t\t\tdesc: " + UnicodeUtils.escapeWithSpaces(node.desc)
|
+ "\n\t\t\tdesc: " + UnicodeUtils.escapeWithSpaces(node.desc) + "\n\t\t\tHandle: [\n\t\t\t\tname: "
|
||||||
+ "\n\t\t\tHandle: [\n\t\t\t\tname: " + UnicodeUtils.escapeWithSpaces(node.bsm.getName()) + "\n\t\t\t\towner: "
|
+ UnicodeUtils.escapeWithSpaces(node.bsm.getName()) + "\n\t\t\t\towner: " + UnicodeUtils.escapeWithSpaces(node.bsm.getOwner())
|
||||||
+ UnicodeUtils.escapeWithSpaces(node.bsm.getOwner()) + "\n\t\t\t\tdesc: "
|
+ "\n\t\t\t\tdesc: " + UnicodeUtils.escapeWithSpaces(node.bsm.getDesc()) + "\n\t\t\t\tisInterface: " + node.bsm.isInterface()
|
||||||
+ UnicodeUtils.escapeWithSpaces(node.bsm.getDesc()) + "\n\t\t\t\tisInterface: " + node.bsm.isInterface()
|
|
||||||
+ "\n\t\t\t\ttag: " + node.bsm.getTag() + "\n\t\t\t]\n\t\t\targs: [\n";
|
+ "\n\t\t\t\ttag: " + node.bsm.getTag() + "\n\t\t\t]\n\t\t\targs: [\n";
|
||||||
for (Object l : node.bsmArgs) {
|
for (Object l : node.bsmArgs) {
|
||||||
if (l.getClass().getName().equals("org.objectweb.asm.Type")) {
|
if (l.getClass().getName().equals("org.objectweb.asm.Type")) {
|
||||||
Type type = (Type) l;
|
Type type = (Type) l;
|
||||||
int off = 0;
|
int valueBegin = 0;
|
||||||
int len = 0;
|
int valueEnd = 0;
|
||||||
char[] buf = null;
|
String buf = null;
|
||||||
try {
|
try {
|
||||||
Field f_off = Type.class.getDeclaredField("off");
|
Field f_off = Type.class.getDeclaredField("valueBegin");
|
||||||
f_off.setAccessible(true);
|
f_off.setAccessible(true);
|
||||||
off = f_off.getInt(type);
|
valueBegin = f_off.getInt(type);
|
||||||
Field f_len = Type.class.getDeclaredField("len");
|
Field f_len = Type.class.getDeclaredField("valueEnd");
|
||||||
f_len.setAccessible(true);
|
f_len.setAccessible(true);
|
||||||
len = f_len.getInt(type);
|
valueEnd = f_len.getInt(type);
|
||||||
Field f_buf = Type.class.getDeclaredField("buf");
|
Field f_buf = Type.class.getDeclaredField("valueBuffer");
|
||||||
f_buf.setAccessible(true);
|
f_buf.setAccessible(true);
|
||||||
buf = (char[]) f_buf.get(type);
|
buf = (String) f_buf.get(type);
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {}
|
||||||
s += "\t\t\t\tType: [\n\t\t\t\t\ttype: " + ClassUtil.getClassNameFromType(type) + "\n\t\t\t\t\toff: " + off
|
s += "\t\t\t\tType: [\n\t\t\t\t\ttype: " + ClassUtil.getClassNameFromType(type) + "\n\t\t\t\t\tstart: " + valueBegin
|
||||||
+ "\n\t\t\t\t\tlen: " + len + "\n\t\t\t\t\tbuf: " + ClassUtil.getDecompiledValue(new String(buf), "");
|
+ "\n\t\t\t\t\tend: " + valueEnd + "\n\t\t\t\t\tbuf: " + ClassUtil.getDecompiledValue(buf, "");
|
||||||
s += "\n\t\t\t\t]\n";
|
s += "\n\t\t\t\t]\n";
|
||||||
} else if (l.getClass().getName().equals("org.objectweb.asm.Handle")) {
|
} else if (l.getClass().getName().equals("org.objectweb.asm.Handle")) {
|
||||||
Handle h = (Handle) l;
|
Handle h = (Handle) l;
|
||||||
s += "\t\t\t\tHandle: [\n\t\t\t\t\tname: " + UnicodeUtils.escapeWithSpaces(h.getName()) + "\n\t\t\t\t\towner: "
|
s += "\t\t\t\tHandle: [\n\t\t\t\t\tname: " + UnicodeUtils.escapeWithSpaces(h.getName()) + "\n\t\t\t\t\towner: "
|
||||||
+ UnicodeUtils.escapeWithSpaces(h.getOwner()) + "\n\t\t\t\t\tdesc: "
|
+ UnicodeUtils.escapeWithSpaces(h.getOwner()) + "\n\t\t\t\t\tdesc: " + UnicodeUtils.escapeWithSpaces(h.getDesc())
|
||||||
+ UnicodeUtils.escapeWithSpaces(h.getDesc()) + "\n\t\t\t\t\tisInterface: " + h.isInterface()
|
+ "\n\t\t\t\t\tisInterface: " + h.isInterface() + "\n\t\t\t\t\ttag: " + h.getTag();
|
||||||
+ "\n\t\t\t\t\ttag: " + h.getTag();
|
|
||||||
s += "\n\t\t\t\t]\n";
|
s += "\n\t\t\t\t]\n";
|
||||||
} else {
|
} else {
|
||||||
s += "\t\t\t\t" + ClassUtil.getDecompiledValue(l, "") + "\n";
|
s += "\t\t\t\t" + ClassUtil.getDecompiledValue(l, "") + "\n";
|
||||||
@@ -478,8 +477,8 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
case "MultiANewArrayInsnNode": {
|
case "MultiANewArrayInsnNode": {
|
||||||
MultiANewArrayInsnNode node = (MultiANewArrayInsnNode) n;
|
MultiANewArrayInsnNode node = (MultiANewArrayInsnNode) n;
|
||||||
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + UnicodeUtils.escapeWithSpaces(node.desc) + " "
|
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + UnicodeUtils.escapeWithSpaces(node.desc) + " " + node.dims
|
||||||
+ node.dims + "\n";
|
+ "\n";
|
||||||
}
|
}
|
||||||
case "LdcInsnNode": {
|
case "LdcInsnNode": {
|
||||||
LdcInsnNode node = (LdcInsnNode) n;
|
LdcInsnNode node = (LdcInsnNode) n;
|
||||||
@@ -489,28 +488,27 @@ public class Disassembler {
|
|||||||
case "Integer":
|
case "Integer":
|
||||||
case "Float":
|
case "Float":
|
||||||
case "Long": {
|
case "Long": {
|
||||||
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + ClassUtil.getDecompiledValue(node.cst, "")
|
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + ClassUtil.getDecompiledValue(node.cst, "") + "\n";
|
||||||
+ "\n";
|
|
||||||
}
|
}
|
||||||
case "Type": {
|
case "Type": {
|
||||||
Type type = (Type) node.cst;
|
Type type = (Type) node.cst;
|
||||||
int off = 0;
|
int valueBegin = 0;
|
||||||
int len = 0;
|
int valueEnd = 0;
|
||||||
char[] buf = null;
|
String buf = null;
|
||||||
try {
|
try {
|
||||||
Field f_off = Type.class.getDeclaredField("off");
|
Field f_off = Type.class.getDeclaredField("valueBegin");
|
||||||
f_off.setAccessible(true);
|
f_off.setAccessible(true);
|
||||||
off = f_off.getInt(type);
|
valueBegin = f_off.getInt(type);
|
||||||
Field f_len = Type.class.getDeclaredField("len");
|
Field f_len = Type.class.getDeclaredField("valueEnd");
|
||||||
f_len.setAccessible(true);
|
f_len.setAccessible(true);
|
||||||
len = f_len.getInt(type);
|
valueEnd = f_len.getInt(type);
|
||||||
Field f_buf = Type.class.getDeclaredField("buf");
|
Field f_buf = Type.class.getDeclaredField("valueBuffer");
|
||||||
f_buf.setAccessible(true);
|
f_buf.setAccessible(true);
|
||||||
buf = (char[]) f_buf.get(type);
|
buf = (String) f_buf.get(type);
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {}
|
||||||
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " Type: [\n\t\t\ttype: "
|
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " Type: [\n\t\t\ttype: "
|
||||||
+ ClassUtil.getClassNameFromType(type) + "\n\t\t\toff: " + off + "\n\t\t\tlen: " + len + "\n\t\t\tbuf: "
|
+ ClassUtil.getClassNameFromType(type) + "\n\t\t\tstart: " + valueBegin + "\n\t\t\tend: " + valueEnd + "\n\t\t\tbuf: "
|
||||||
+ ClassUtil.getDecompiledValue(new String(buf), "");
|
+ ClassUtil.getDecompiledValue(buf, "");
|
||||||
s += "\n\t\t]\n";
|
s += "\n\t\t]\n";
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -604,11 +604,8 @@ public class Main extends JFrame {
|
|||||||
class ArchiveTreeModel extends DefaultTreeModel {
|
class ArchiveTreeModel extends DefaultTreeModel {
|
||||||
|
|
||||||
public ArchiveTreeModel(JarFile jar) {
|
public ArchiveTreeModel(JarFile jar) {
|
||||||
super(new DefaultMutableTreeNode(
|
super(new DefaultMutableTreeNode(jar.getName().split(File.separator.equals("\\") ? "\\\\"
|
||||||
jar.getName()
|
: File.separator)[jar.getName().split(File.separator.equals("\\") ? "\\\\" : File.separator).length - 1]));
|
||||||
.split(File.separator.equals("\\") ? "\\\\"
|
|
||||||
: File.separator)[jar.getName().split(File.separator.equals("\\") ? "\\\\" : File.separator).length
|
|
||||||
- 1]));
|
|
||||||
try {
|
try {
|
||||||
ArrayList<String> paths = new ArrayList<>();
|
ArrayList<String> paths = new ArrayList<>();
|
||||||
classNodes.clear();
|
classNodes.clear();
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ import java.io.Reader;
|
|||||||
* <li>UTF-32LE
|
* <li>UTF-32LE
|
||||||
* <li>UTF-32BE
|
* <li>UTF-32BE
|
||||||
* </ul>
|
* </ul>
|
||||||
* If the stream is not found to be any of the above, then a default encoding
|
* If the stream is not found to be any of the above, then a default encoding is
|
||||||
* is used for reading. The user can specify this default encoding, or a system
|
* used for reading. The user can specify this default encoding, or a system
|
||||||
* default will be used.
|
* default will be used.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
@@ -40,7 +40,6 @@ import java.io.Reader;
|
|||||||
* @author Robert Futrell
|
* @author Robert Futrell
|
||||||
* @version 0.9
|
* @version 0.9
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "checkstyle:magicnumber" })
|
|
||||||
public class UnicodeReader extends Reader {
|
public class UnicodeReader extends Reader {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,9 +47,9 @@ public class UnicodeReader extends Reader {
|
|||||||
*/
|
*/
|
||||||
private InputStreamReader internalIn = null;
|
private InputStreamReader internalIn = null;
|
||||||
/**
|
/**
|
||||||
* The encoding being used. We keep our own instead of using the string
|
* The encoding being used. We keep our own instead of using the string returned
|
||||||
* returned by <code>java.io.InputStreamReader</code> since that class
|
* by <code>java.io.InputStreamReader</code> since that class does not return
|
||||||
* does not return user-friendly names.
|
* user-friendly names.
|
||||||
*/
|
*/
|
||||||
private String encoding;
|
private String encoding;
|
||||||
/**
|
/**
|
||||||
@@ -62,17 +61,14 @@ public class UnicodeReader extends Reader {
|
|||||||
* This utility constructor is here because you will usually use a
|
* This utility constructor is here because you will usually use a
|
||||||
* <code>UnicodeReader</code> on files.
|
* <code>UnicodeReader</code> on files.
|
||||||
* <p>
|
* <p>
|
||||||
* Creates a reader using the encoding specified by the BOM in the file;
|
* Creates a reader using the encoding specified by the BOM in the file; if
|
||||||
* if there is no recognized BOM, then a system default encoding is used.
|
* there is no recognized BOM, then a system default encoding is used.
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file The file from which you want to read.
|
||||||
* The file from which you want to read.
|
* @throws IOException If an error occurs when checking for/reading the
|
||||||
* @throws IOException
|
* BOM.
|
||||||
* If an error occurs when checking for/reading the
|
* @throws SecurityException If a security manager exists and its checkRead
|
||||||
* BOM.
|
* method denies read access to the file.
|
||||||
* @throws SecurityException
|
|
||||||
* If a security manager exists and its
|
|
||||||
* checkRead method denies read access to the file.
|
|
||||||
*/
|
*/
|
||||||
public UnicodeReader(String file) throws IOException {
|
public UnicodeReader(String file) throws IOException {
|
||||||
this(new File(file));
|
this(new File(file));
|
||||||
@@ -82,17 +78,14 @@ public class UnicodeReader extends Reader {
|
|||||||
* This utility constructor is here because you will usually use a
|
* This utility constructor is here because you will usually use a
|
||||||
* <code>UnicodeReader</code> on files.
|
* <code>UnicodeReader</code> on files.
|
||||||
* <p>
|
* <p>
|
||||||
* Creates a reader using the encoding specified by the BOM in the file;
|
* Creates a reader using the encoding specified by the BOM in the file; if
|
||||||
* if there is no recognized BOM, then a system default encoding is used.
|
* there is no recognized BOM, then a system default encoding is used.
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file The file from which you want to read.
|
||||||
* The file from which you want to read.
|
* @throws IOException If an error occurs when checking for/reading the
|
||||||
* @throws IOException
|
* BOM.
|
||||||
* If an error occurs when checking for/reading the
|
* @throws SecurityException If a security manager exists and its checkRead
|
||||||
* BOM.
|
* method denies read access to the file.
|
||||||
* @throws SecurityException
|
|
||||||
* If a security manager exists and its
|
|
||||||
* checkRead method denies read access to the file.
|
|
||||||
*/
|
*/
|
||||||
public UnicodeReader(File file) throws IOException {
|
public UnicodeReader(File file) throws IOException {
|
||||||
this(new FileInputStream(file));
|
this(new FileInputStream(file));
|
||||||
@@ -102,54 +95,41 @@ public class UnicodeReader extends Reader {
|
|||||||
* This utility constructor is here because you will usually use a
|
* This utility constructor is here because you will usually use a
|
||||||
* <code>UnicodeReader</code> on files.
|
* <code>UnicodeReader</code> on files.
|
||||||
* <p>
|
* <p>
|
||||||
* Creates a reader using the encoding specified by the BOM in the file;
|
* Creates a reader using the encoding specified by the BOM in the file; if
|
||||||
* if there is no recognized BOM, then a specified default encoding is
|
* there is no recognized BOM, then a specified default encoding is used.
|
||||||
* used.
|
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file The file from which you want to read.
|
||||||
* The file from which you want to read.
|
* @param defaultEncoding The encoding to use if no BOM is found. If this value
|
||||||
* @param defaultEncoding
|
* is <code>null</code>, a system default is used.
|
||||||
* The encoding to use if no BOM is found. If
|
* @throws IOException If an error occurs when checking for/reading the
|
||||||
* this value is <code>null</code>, a system default is used.
|
* BOM.
|
||||||
* @throws IOException
|
* @throws SecurityException If a security manager exists and its checkRead
|
||||||
* If an error occurs when checking for/reading the
|
* method denies read access to the file.
|
||||||
* BOM.
|
|
||||||
* @throws SecurityException
|
|
||||||
* If a security manager exists and its
|
|
||||||
* checkRead method denies read access to the file.
|
|
||||||
*/
|
*/
|
||||||
public UnicodeReader(File file, String defaultEncoding) throws IOException {
|
public UnicodeReader(File file, String defaultEncoding) throws IOException {
|
||||||
this(new FileInputStream(file), defaultEncoding);
|
this(new FileInputStream(file), defaultEncoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a reader using the encoding specified by the BOM in the file;
|
* Creates a reader using the encoding specified by the BOM in the file; if
|
||||||
* if there is no recognized BOM, then a system default encoding is used.
|
* there is no recognized BOM, then a system default encoding is used.
|
||||||
*
|
*
|
||||||
* @param in
|
* @param in The input stream from which to read.
|
||||||
* The input stream from which to read.
|
* @throws IOException If an error occurs when checking for/reading the BOM.
|
||||||
* @throws IOException
|
|
||||||
* If an error occurs when checking for/reading the
|
|
||||||
* BOM.
|
|
||||||
*/
|
*/
|
||||||
public UnicodeReader(InputStream in) throws IOException {
|
public UnicodeReader(InputStream in) throws IOException {
|
||||||
this(in, null);
|
this(in, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a reader using the encoding specified by the BOM in the file;
|
* Creates a reader using the encoding specified by the BOM in the file; if
|
||||||
* if there is no recognized BOM, then <code>defaultEncoding</code> is
|
* there is no recognized BOM, then <code>defaultEncoding</code> is used.
|
||||||
* used.
|
|
||||||
*
|
*
|
||||||
* @param in
|
* @param in The input stream from which to read.
|
||||||
* The input stream from which to read.
|
* @param defaultEncoding The encoding to use if no recognized BOM is found. If
|
||||||
* @param defaultEncoding
|
* this value is <code>null</code>, a system default is
|
||||||
* The encoding to use if no recognized BOM is
|
* used.
|
||||||
* found. If this value is <code>null</code>, a system default
|
* @throws IOException If an error occurs when checking for/reading the BOM.
|
||||||
* is used.
|
|
||||||
* @throws IOException
|
|
||||||
* If an error occurs when checking for/reading the
|
|
||||||
* BOM.
|
|
||||||
*/
|
*/
|
||||||
public UnicodeReader(InputStream in, String defaultEncoding) throws IOException {
|
public UnicodeReader(InputStream in, String defaultEncoding) throws IOException {
|
||||||
init(in, defaultEncoding);
|
init(in, defaultEncoding);
|
||||||
@@ -164,10 +144,10 @@ public class UnicodeReader extends Reader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the encoding being used to read this input stream (i.e., the
|
* Returns the encoding being used to read this input stream (i.e., the encoding
|
||||||
* encoding of the file). If a BOM was recognized, then the specific
|
* of the file). If a BOM was recognized, then the specific Unicode type is
|
||||||
* Unicode type is returned; otherwise, either the default encoding passed
|
* returned; otherwise, either the default encoding passed into the constructor
|
||||||
* into the constructor or the system default is returned.
|
* or the system default is returned.
|
||||||
*
|
*
|
||||||
* @return The encoding of the stream.
|
* @return The encoding of the stream.
|
||||||
*/
|
*/
|
||||||
@@ -176,15 +156,13 @@ public class UnicodeReader extends Reader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read-ahead four bytes and check for BOM marks. Extra bytes are
|
* Read-ahead four bytes and check for BOM marks. Extra bytes are unread back to
|
||||||
* unread back to the stream, only BOM bytes are skipped.
|
* the stream, only BOM bytes are skipped.
|
||||||
*
|
*
|
||||||
* @param defaultEncoding
|
* @param defaultEncoding The encoding to use if no BOM was recognized. If this
|
||||||
* The encoding to use if no BOM was recognized. If
|
* value is <code>null</code>, then a system default is
|
||||||
* this value is <code>null</code>, then a system default is
|
* used.
|
||||||
* used.
|
* @throws IOException If an error occurs when trying to read a BOM.
|
||||||
* @throws IOException
|
|
||||||
* If an error occurs when trying to read a BOM.
|
|
||||||
*/
|
*/
|
||||||
protected void init(InputStream in, String defaultEncoding) throws IOException {
|
protected void init(InputStream in, String defaultEncoding) throws IOException {
|
||||||
PushbackInputStream tempIn = new PushbackInputStream(in, BOM_SIZE);
|
PushbackInputStream tempIn = new PushbackInputStream(in, BOM_SIZE);
|
||||||
@@ -196,7 +174,8 @@ public class UnicodeReader extends Reader {
|
|||||||
unread = n - 4;
|
unread = n - 4;
|
||||||
} else if (n == BOM_SIZE && // Last 2 bytes are 0; could be an empty
|
} else if (n == BOM_SIZE && // Last 2 bytes are 0; could be an empty
|
||||||
// UTF-16
|
// UTF-16
|
||||||
(bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
|
(bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00)
|
||||||
|
&& (bom[3] == (byte) 0x00)) {
|
||||||
encoding = "UTF-32LE";
|
encoding = "UTF-32LE";
|
||||||
unread = n - 4;
|
unread = n - 4;
|
||||||
} else if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
|
} else if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
|
||||||
@@ -228,19 +207,15 @@ public class UnicodeReader extends Reader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read characters into a portion of an array. This method will block until
|
* Read characters into a portion of an array. This method will block until some
|
||||||
* some input is available, an I/O error occurs, or the end of the stream
|
* input is available, an I/O error occurs, or the end of the stream is reached.
|
||||||
* is reached.
|
|
||||||
*
|
*
|
||||||
* @param cbuf
|
* @param cbuf The buffer into which to read.
|
||||||
* The buffer into which to read.
|
* @param off The offset at which to start storing characters.
|
||||||
* @param off
|
* @param len The maximum number of characters to read.
|
||||||
* The offset at which to start storing characters.
|
|
||||||
* @param len
|
|
||||||
* The maximum number of characters to read.
|
|
||||||
*
|
*
|
||||||
* @return The number of characters read, or <code>-1</code> if the end
|
* @return The number of characters read, or <code>-1</code> if the end of the
|
||||||
* of the stream has been reached.
|
* stream has been reached.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int read(char[] cbuf, int off, int len) throws IOException {
|
public int read(char[] cbuf, int off, int len) throws IOException {
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ import java.util.List;
|
|||||||
import javax.swing.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class for completion providers. {@link Completion}s are kept in
|
* A base class for completion providers. {@link Completion}s are kept in a
|
||||||
* a sorted list. To get the list of completions that match a given input,
|
* sorted list. To get the list of completions that match a given input, a
|
||||||
* a binary search is done to find the first matching completion, then all
|
* binary search is done to find the first matching completion, then all
|
||||||
* succeeding completions that also match are also returned.
|
* succeeding completions that also match are also returned.
|
||||||
*
|
*
|
||||||
* @author Robert Futrell
|
* @author Robert Futrell
|
||||||
@@ -26,8 +26,8 @@ import javax.swing.text.JTextComponent;
|
|||||||
public abstract class AbstractCompletionProvider extends CompletionProviderBase {
|
public abstract class AbstractCompletionProvider extends CompletionProviderBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The completions this provider is aware of. Subclasses should ensure
|
* The completions this provider is aware of. Subclasses should ensure that this
|
||||||
* that this list is sorted alphabetically (case-insensitively).
|
* list is sorted alphabetically (case-insensitively).
|
||||||
*/
|
*/
|
||||||
protected List<Completion> completions;
|
protected List<Completion> completions;
|
||||||
/**
|
/**
|
||||||
@@ -46,14 +46,12 @@ public abstract class AbstractCompletionProvider extends CompletionProviderBase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a single completion to this provider. If you are adding multiple
|
* Adds a single completion to this provider. If you are adding multiple
|
||||||
* completions to this provider, for efficiency reasons please consider
|
* completions to this provider, for efficiency reasons please consider using
|
||||||
* using {@link #addCompletions(List)} instead.
|
* {@link #addCompletions(List)} instead.
|
||||||
*
|
*
|
||||||
* @param c
|
* @param c The completion to add.
|
||||||
* The completion to add.
|
* @throws IllegalArgumentException If the completion's provider isn't this
|
||||||
* @throws IllegalArgumentException
|
* <tt>CompletionProvider</tt>.
|
||||||
* If the completion's provider isn't
|
|
||||||
* this <tt>CompletionProvider</tt>.
|
|
||||||
* @see #addCompletions(List)
|
* @see #addCompletions(List)
|
||||||
* @see #removeCompletion(Completion)
|
* @see #removeCompletion(Completion)
|
||||||
* @see #clear()
|
* @see #clear()
|
||||||
@@ -66,12 +64,9 @@ public abstract class AbstractCompletionProvider extends CompletionProviderBase
|
|||||||
/**
|
/**
|
||||||
* Adds {@link Completion}s to this provider.
|
* Adds {@link Completion}s to this provider.
|
||||||
*
|
*
|
||||||
* @param completions
|
* @param completions The completions to add. This cannot be <code>null</code>.
|
||||||
* The completions to add. This cannot be
|
* @throws IllegalArgumentException If a completion's provider isn't this
|
||||||
* <code>null</code>.
|
* <tt>CompletionProvider</tt>.
|
||||||
* @throws IllegalArgumentException
|
|
||||||
* If a completion's provider isn't
|
|
||||||
* this <tt>CompletionProvider</tt>.
|
|
||||||
* @see #addCompletion(Completion)
|
* @see #addCompletion(Completion)
|
||||||
* @see #removeCompletion(Completion)
|
* @see #removeCompletion(Completion)
|
||||||
* @see #clear()
|
* @see #clear()
|
||||||
@@ -87,8 +82,7 @@ public abstract class AbstractCompletionProvider extends CompletionProviderBase
|
|||||||
/**
|
/**
|
||||||
* Adds simple completions for a list of words.
|
* Adds simple completions for a list of words.
|
||||||
*
|
*
|
||||||
* @param words
|
* @param words The words.
|
||||||
* The words.
|
|
||||||
* @see BasicCompletion
|
* @see BasicCompletion
|
||||||
*/
|
*/
|
||||||
protected void addWordCompletions(String[] words) {
|
protected void addWordCompletions(String[] words) {
|
||||||
@@ -107,8 +101,8 @@ public abstract class AbstractCompletionProvider extends CompletionProviderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all completions from this provider. This does not affect
|
* Removes all completions from this provider. This does not affect the parent
|
||||||
* the parent <tt>CompletionProvider</tt>, if there is one.
|
* <tt>CompletionProvider</tt>, if there is one.
|
||||||
*
|
*
|
||||||
* @see #addCompletion(Completion)
|
* @see #addCompletion(Completion)
|
||||||
* @see #addCompletions(List)
|
* @see #addCompletions(List)
|
||||||
@@ -119,15 +113,13 @@ public abstract class AbstractCompletionProvider extends CompletionProviderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of <tt>Completion</tt>s in this provider with the
|
* Returns a list of <tt>Completion</tt>s in this provider with the specified
|
||||||
* specified input text.
|
* input text.
|
||||||
*
|
*
|
||||||
* @param inputText
|
* @param inputText The input text to search for.
|
||||||
* The input text to search for.
|
* @return A list of {@link Completion}s, or <code>null</code> if there are no
|
||||||
* @return A list of {@link Completion}s, or <code>null</code> if there
|
* matching <tt>Completion</tt>s.
|
||||||
* are no matching <tt>Completion</tt>s.
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public List<Completion> getCompletionByInputText(String inputText) {
|
public List<Completion> getCompletionByInputText(String inputText) {
|
||||||
// Find any entry that matches this input text (there may be > 1).
|
// Find any entry that matches this input text (there may be > 1).
|
||||||
int end = Collections.binarySearch(completions, inputText, comparator);
|
int end = Collections.binarySearch(completions, inputText, comparator);
|
||||||
@@ -140,7 +132,8 @@ public abstract class AbstractCompletionProvider extends CompletionProviderBase
|
|||||||
start--;
|
start--;
|
||||||
}
|
}
|
||||||
int count = completions.size();
|
int count = completions.size();
|
||||||
while (++end < count && comparator.compare(completions.get(end), inputText) == 0);
|
while (++end < count && comparator.compare(completions.get(end), inputText) == 0)
|
||||||
|
;
|
||||||
return completions.subList(start, end); // (inclusive, exclusive)
|
return completions.subList(start, end); // (inclusive, exclusive)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +141,6 @@ public abstract class AbstractCompletionProvider extends CompletionProviderBase
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected List<Completion> getCompletionsImpl(JTextComponent comp) {
|
protected List<Completion> getCompletionsImpl(JTextComponent comp) {
|
||||||
List<Completion> retVal = new ArrayList<Completion>();
|
List<Completion> retVal = new ArrayList<Completion>();
|
||||||
String text = getAlreadyEnteredText(comp);
|
String text = getAlreadyEnteredText(comp);
|
||||||
@@ -190,11 +182,10 @@ public abstract class AbstractCompletionProvider extends CompletionProviderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the specified completion from this provider. This method
|
* Removes the specified completion from this provider. This method will not
|
||||||
* will not remove completions from the parent provider, if there is one.
|
* remove completions from the parent provider, if there is one.
|
||||||
*
|
*
|
||||||
* @param c
|
* @param c The completion to remove.
|
||||||
* The completion to remove.
|
|
||||||
* @return <code>true</code> if this provider contained the specified
|
* @return <code>true</code> if this provider contained the specified
|
||||||
* completion.
|
* completion.
|
||||||
* @see #clear()
|
* @see #clear()
|
||||||
@@ -212,10 +203,9 @@ public abstract class AbstractCompletionProvider extends CompletionProviderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A comparator that compares the input text of a {@link Completion}
|
* A comparator that compares the input text of a {@link Completion} against a
|
||||||
* against a String lexicographically, ignoring case.
|
* String lexicographically, ignoring case.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
public static class CaseInsensitiveComparator implements Comparator, Serializable {
|
public static class CaseInsensitiveComparator implements Comparator, Serializable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -32,19 +32,18 @@ import org.fife.ui.rsyntaxtextarea.templates.CodeTemplate;
|
|||||||
* Manages "code templates."
|
* Manages "code templates."
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* All methods in this class are synchronized for thread safety, but as a
|
* All methods in this class are synchronized for thread safety, but as a best
|
||||||
* best practice, you should probably only modify the templates known to a
|
* practice, you should probably only modify the templates known to a
|
||||||
* <code>CodeTemplateManager</code> on the EDT. Modifying a
|
* <code>CodeTemplateManager</code> on the EDT. Modifying a
|
||||||
* <code>CodeTemplate</code> retrieved from a <code>CodeTemplateManager</code>
|
* <code>CodeTemplate</code> retrieved from a <code>CodeTemplateManager</code>
|
||||||
* while <em>not</em> on the EDT could cause problems.
|
* while <em>not</em> on the EDT could cause problems.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* For more flexible boilerplate code insertion, consider using the
|
* For more flexible boilerplate code insertion, consider using the <a href=
|
||||||
* <a href=
|
|
||||||
* "http://javadoc.fifesoft.com/autocomplete/org/fife/ui/autocomplete/TemplateCompletion.html">
|
* "http://javadoc.fifesoft.com/autocomplete/org/fife/ui/autocomplete/TemplateCompletion.html">
|
||||||
* TemplateCompletion class</a> in the
|
* TemplateCompletion class</a> in the
|
||||||
* <a href="https://github.com/bobbylight/AutoComplete">AutoComplete
|
* <a href="https://github.com/bobbylight/AutoComplete">AutoComplete add-on
|
||||||
* add-on library</a>.
|
* library</a>.
|
||||||
*
|
*
|
||||||
* @author Robert Futrell
|
* @author Robert Futrell
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
@@ -69,11 +68,9 @@ public class CodeTemplateManager {
|
|||||||
/**
|
/**
|
||||||
* Registers the specified template with this template manager.
|
* Registers the specified template with this template manager.
|
||||||
*
|
*
|
||||||
* @param template
|
* @param template The template to register.
|
||||||
* The template to register.
|
* @throws IllegalArgumentException If <code>template</code> is
|
||||||
* @throws IllegalArgumentException
|
* <code>null</code>.
|
||||||
* If <code>template</code> is
|
|
||||||
* <code>null</code>.
|
|
||||||
* @see #removeTemplate(CodeTemplate)
|
* @see #removeTemplate(CodeTemplate)
|
||||||
* @see #removeTemplate(String)
|
* @see #removeTemplate(String)
|
||||||
*/
|
*/
|
||||||
@@ -86,11 +83,10 @@ public class CodeTemplateManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the template that should be inserted at the current caret
|
* Returns the template that should be inserted at the current caret position,
|
||||||
* position, assuming the trigger character was pressed.
|
* assuming the trigger character was pressed.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area that's getting text inserted into it.
|
||||||
* The text area that's getting text inserted into it.
|
|
||||||
* @return A template that should be inserted, if appropriate, or
|
* @return A template that should be inserted, if appropriate, or
|
||||||
* <code>null</code> if no template should be inserted.
|
* <code>null</code> if no template should be inserted.
|
||||||
*/
|
*/
|
||||||
@@ -100,7 +96,6 @@ public class CodeTemplateManager {
|
|||||||
try {
|
try {
|
||||||
Document doc = textArea.getDocument();
|
Document doc = textArea.getDocument();
|
||||||
doc.getText(caretPos - charsToGet, charsToGet, s);
|
doc.getText(caretPos - charsToGet, charsToGet, s);
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
int index = Collections.binarySearch(templates, s, comparator);
|
int index = Collections.binarySearch(templates, s, comparator);
|
||||||
return index >= 0 ? (CodeTemplate) templates.get(index) : null;
|
return index >= 0 ? (CodeTemplate) templates.get(index) : null;
|
||||||
} catch (BadLocationException ble) {
|
} catch (BadLocationException ble) {
|
||||||
@@ -132,8 +127,7 @@ public class CodeTemplateManager {
|
|||||||
* Returns whether the specified character is a valid character for a
|
* Returns whether the specified character is a valid character for a
|
||||||
* <code>CodeTemplate</code> id.
|
* <code>CodeTemplate</code> id.
|
||||||
*
|
*
|
||||||
* @param ch
|
* @param ch The character to check.
|
||||||
* The character to check.
|
|
||||||
* @return Whether the character is a valid template character.
|
* @return Whether the character is a valid template character.
|
||||||
*/
|
*/
|
||||||
public static final boolean isValidChar(char ch) {
|
public static final boolean isValidChar(char ch) {
|
||||||
@@ -143,13 +137,11 @@ public class CodeTemplateManager {
|
|||||||
/**
|
/**
|
||||||
* Returns the specified code template.
|
* Returns the specified code template.
|
||||||
*
|
*
|
||||||
* @param template
|
* @param template The template to remove.
|
||||||
* The template to remove.
|
* @return <code>true</code> if the template was removed, <code>false</code> if
|
||||||
* @return <code>true</code> if the template was removed, <code>false</code>
|
* the template was not in this template manager.
|
||||||
* if the template was not in this template manager.
|
* @throws IllegalArgumentException If <code>template</code> is
|
||||||
* @throws IllegalArgumentException
|
* <code>null</code>.
|
||||||
* If <code>template</code> is
|
|
||||||
* <code>null</code>.
|
|
||||||
* @see #removeTemplate(String)
|
* @see #removeTemplate(String)
|
||||||
* @see #addTemplate(CodeTemplate)
|
* @see #addTemplate(CodeTemplate)
|
||||||
*/
|
*/
|
||||||
@@ -164,12 +156,10 @@ public class CodeTemplateManager {
|
|||||||
/**
|
/**
|
||||||
* Returns the code template with the specified id.
|
* Returns the code template with the specified id.
|
||||||
*
|
*
|
||||||
* @param id
|
* @param id The id to check for.
|
||||||
* The id to check for.
|
* @return The code template that was removed, or <code>null</code> if there was
|
||||||
* @return The code template that was removed, or <code>null</code> if
|
* no template with the specified ID.
|
||||||
* there was no template with the specified ID.
|
* @throws IllegalArgumentException If <code>id</code> is <code>null</code>.
|
||||||
* @throws IllegalArgumentException
|
|
||||||
* If <code>id</code> is <code>null</code>.
|
|
||||||
* @see #removeTemplate(CodeTemplate)
|
* @see #removeTemplate(CodeTemplate)
|
||||||
* @see #addTemplate(CodeTemplate)
|
* @see #addTemplate(CodeTemplate)
|
||||||
*/
|
*/
|
||||||
@@ -189,12 +179,10 @@ public class CodeTemplateManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces the current set of available templates with the ones
|
* Replaces the current set of available templates with the ones specified.
|
||||||
* specified.
|
|
||||||
*
|
*
|
||||||
* @param newTemplates
|
* @param newTemplates The new set of templates. Note that we will be taking a
|
||||||
* The new set of templates. Note that we will
|
* shallow copy of these and sorting them.
|
||||||
* be taking a shallow copy of these and sorting them.
|
|
||||||
*/
|
*/
|
||||||
public synchronized void replaceTemplates(CodeTemplate[] newTemplates) {
|
public synchronized void replaceTemplates(CodeTemplate[] newTemplates) {
|
||||||
templates.clear();
|
templates.clear();
|
||||||
@@ -245,12 +233,11 @@ public class CodeTemplateManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the directory in which to look for templates. Calling this
|
* Sets the directory in which to look for templates. Calling this method adds
|
||||||
* method adds any new templates found in the specified directory to
|
* any new templates found in the specified directory to the templates already
|
||||||
* the templates already registered.
|
* registered.
|
||||||
*
|
*
|
||||||
* @param dir
|
* @param dir The new directory in which to look for templates.
|
||||||
* The new directory in which to look for templates.
|
|
||||||
* @return The new number of templates in this template manager, or
|
* @return The new number of templates in this template manager, or
|
||||||
* <code>-1</code> if the specified directory does not exist.
|
* <code>-1</code> if the specified directory does not exist.
|
||||||
*/
|
*/
|
||||||
@@ -287,9 +274,8 @@ public class CodeTemplateManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes any null entries in the current set of templates (if
|
* Removes any null entries in the current set of templates (if any), sorts the
|
||||||
* any), sorts the remaining templates, and computes the new
|
* remaining templates, and computes the new maximum template ID length.
|
||||||
* maximum template ID length.
|
|
||||||
*/
|
*/
|
||||||
private synchronized void sortTemplates() {
|
private synchronized void sortTemplates() {
|
||||||
// Get the maximum length of a template ID.
|
// Get the maximum length of a template ID.
|
||||||
@@ -309,11 +295,10 @@ public class CodeTemplateManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A comparator that takes a <code>CodeTemplate</code> as its first
|
* A comparator that takes a <code>CodeTemplate</code> as its first parameter
|
||||||
* parameter and a <code>Segment</code> as its second, and knows
|
* and a <code>Segment</code> as its second, and knows to compare the template's
|
||||||
* to compare the template's ID to the segment's text.
|
* ID to the segment's text.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
private static class TemplateComparator implements Comparator, Serializable {
|
private static class TemplateComparator implements Comparator, Serializable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -15,17 +15,16 @@ import javax.swing.KeyStroke;
|
|||||||
import org.fife.ui.rtextarea.RTADefaultInputMap;
|
import org.fife.ui.rtextarea.RTADefaultInputMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default input map for an <code>RSyntaxTextArea</code>.
|
* The default input map for an <code>RSyntaxTextArea</code>. Currently, the new
|
||||||
* Currently, the new key bindings include:
|
* key bindings include:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Shift+Tab indents the current line or currently selected lines
|
* <li>Shift+Tab indents the current line or currently selected lines to the
|
||||||
* to the left.
|
* left.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author Robert Futrell
|
* @author Robert Futrell
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "checkstyle:linelength" })
|
|
||||||
public class RSyntaxTextAreaDefaultInputMap extends RTADefaultInputMap {
|
public class RSyntaxTextAreaDefaultInputMap extends RTADefaultInputMap {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,18 +59,23 @@ public class RSyntaxTextAreaDefaultInputMap extends RTADefaultInputMap {
|
|||||||
// (unfortunately) don't have a ToggleCommentAction for *nix
|
// (unfortunately) don't have a ToggleCommentAction for *nix
|
||||||
// out-of-the-box.
|
// out-of-the-box.
|
||||||
// Applications can add one easily enough if they want one.
|
// Applications can add one easily enough if they want one.
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_SLASH, defaultMod), RSyntaxTextAreaEditorKit.rstaToggleCommentAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_SLASH, defaultMod),
|
||||||
|
RSyntaxTextAreaEditorKit.rstaToggleCommentAction);
|
||||||
}
|
}
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_OPEN_BRACKET, defaultMod), RSyntaxTextAreaEditorKit.rstaGoToMatchingBracketAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_OPEN_BRACKET, defaultMod),
|
||||||
|
RSyntaxTextAreaEditorKit.rstaGoToMatchingBracketAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_SUBTRACT, defaultMod), RSyntaxTextAreaEditorKit.rstaCollapseFoldAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_SUBTRACT, defaultMod), RSyntaxTextAreaEditorKit.rstaCollapseFoldAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_ADD, defaultMod), RSyntaxTextAreaEditorKit.rstaExpandFoldAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_ADD, defaultMod), RSyntaxTextAreaEditorKit.rstaExpandFoldAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_DIVIDE, defaultMod), RSyntaxTextAreaEditorKit.rstaCollapseAllFoldsAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_DIVIDE, defaultMod),
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_MULTIPLY, defaultMod), RSyntaxTextAreaEditorKit.rstaExpandAllFoldsAction);
|
RSyntaxTextAreaEditorKit.rstaCollapseAllFoldsAction);
|
||||||
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_MULTIPLY, defaultMod),
|
||||||
|
RSyntaxTextAreaEditorKit.rstaExpandAllFoldsAction);
|
||||||
// NOTE: no modifiers => mapped to keyTyped. If we had "0" as a second
|
// NOTE: no modifiers => mapped to keyTyped. If we had "0" as a second
|
||||||
// second parameter, we'd get the template action (keyPressed) AND the
|
// second parameter, we'd get the template action (keyPressed) AND the
|
||||||
// default space action (keyTyped).
|
// default space action (keyTyped).
|
||||||
// put(KeyStroke.getKeyStroke(' '),
|
// put(KeyStroke.getKeyStroke(' '),
|
||||||
// RSyntaxTextAreaEditorKit.rstaPossiblyInsertTemplateAction);
|
// RSyntaxTextAreaEditorKit.rstaPossiblyInsertTemplateAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, defaultShift), RSyntaxTextAreaEditorKit.rstaPossiblyInsertTemplateAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, defaultShift),
|
||||||
|
RSyntaxTextAreaEditorKit.rstaPossiblyInsertTemplateAction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,6 @@ import org.fife.ui.rtextarea.RecordableTextAction;
|
|||||||
* @author Robert Futrell
|
* @author Robert Futrell
|
||||||
* @version 0.5
|
* @version 0.5
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "checkstyle:constantname" })
|
|
||||||
public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -88,21 +87,25 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
*/
|
*/
|
||||||
private static final Action[] defaultActions = { new CloseCurlyBraceAction(), new CloseMarkupTagAction(),
|
private static final Action[] defaultActions = { new CloseCurlyBraceAction(), new CloseMarkupTagAction(),
|
||||||
new BeginWordAction(beginWordAction, false), new BeginWordAction(selectionBeginWordAction, true),
|
new BeginWordAction(beginWordAction, false), new BeginWordAction(selectionBeginWordAction, true),
|
||||||
new ChangeFoldStateAction(rstaCollapseFoldAction, true), new ChangeFoldStateAction(rstaExpandFoldAction, false),
|
new ChangeFoldStateAction(rstaCollapseFoldAction, true),
|
||||||
new CollapseAllFoldsAction(), new CopyAsRtfAction(),
|
new ChangeFoldStateAction(rstaExpandFoldAction, false), new CollapseAllFoldsAction(), new CopyAsRtfAction(),
|
||||||
// new DecreaseFontSizeAction(),
|
// new DecreaseFontSizeAction(),
|
||||||
new DecreaseIndentAction(), new DeletePrevWordAction(), new DumbCompleteWordAction(), new EndAction(endAction, false),
|
new DecreaseIndentAction(), new DeletePrevWordAction(), new DumbCompleteWordAction(),
|
||||||
new EndAction(selectionEndAction, true), new EndWordAction(endWordAction, false), new EndWordAction(endWordAction, true),
|
new EndAction(endAction, false), new EndAction(selectionEndAction, true),
|
||||||
new ExpandAllFoldsAction(), new GoToMatchingBracketAction(), new InsertBreakAction(),
|
new EndWordAction(endWordAction, false), new EndWordAction(endWordAction, true), new ExpandAllFoldsAction(),
|
||||||
|
new GoToMatchingBracketAction(), new InsertBreakAction(),
|
||||||
// new IncreaseFontSizeAction(),
|
// new IncreaseFontSizeAction(),
|
||||||
new InsertTabAction(), new NextWordAction(nextWordAction, false), new NextWordAction(selectionNextWordAction, true),
|
new InsertTabAction(), new NextWordAction(nextWordAction, false),
|
||||||
new PossiblyInsertTemplateAction(), new PreviousWordAction(previousWordAction, false),
|
new NextWordAction(selectionNextWordAction, true), new PossiblyInsertTemplateAction(),
|
||||||
new PreviousWordAction(selectionPreviousWordAction, true), new SelectWordAction(), new ToggleCommentAction(), };
|
new PreviousWordAction(previousWordAction, false),
|
||||||
|
new PreviousWordAction(selectionPreviousWordAction, true), new SelectWordAction(),
|
||||||
|
new ToggleCommentAction(), };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
public RSyntaxTextAreaEditorKit() {}
|
public RSyntaxTextAreaEditorKit() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the default document used by <code>RSyntaxTextArea</code>s.
|
* Returns the default document used by <code>RSyntaxTextArea</code>s.
|
||||||
@@ -117,8 +120,7 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
/**
|
/**
|
||||||
* Overridden to return a row header that is aware of folding.
|
* Overridden to return a row header that is aware of folding.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area.
|
||||||
* The text area.
|
|
||||||
* @return The icon row header.
|
* @return The icon row header.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -127,9 +129,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the set of commands that can be used
|
* Fetches the set of commands that can be used on a text component that is
|
||||||
* on a text component that is using a model and
|
* using a model and view produced by this kit.
|
||||||
* view produced by this kit.
|
|
||||||
*
|
*
|
||||||
* @return the command list
|
* @return the command list
|
||||||
*/
|
*/
|
||||||
@@ -139,11 +140,10 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns localized text for an action. There's definitely a better place
|
* Returns localized text for an action. There's definitely a better place for
|
||||||
* for this functionality.
|
* this functionality.
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key The key into the action resource bundle.
|
||||||
* The key into the action resource bundle.
|
|
||||||
* @return The localized text.
|
* @return The localized text.
|
||||||
*/
|
*/
|
||||||
public static String getString(String key) {
|
public static String getString(String key) {
|
||||||
@@ -151,9 +151,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Positions the caret at the beginning of the word. This class is here
|
* Positions the caret at the beginning of the word. This class is here to
|
||||||
* to better handle finding the "beginning of the word" for programming
|
* better handle finding the "beginning of the word" for programming languages.
|
||||||
* languages.
|
|
||||||
*/
|
*/
|
||||||
protected static class BeginWordAction extends RTextAreaEditorKit.BeginWordAction {
|
protected static class BeginWordAction extends RTextAreaEditorKit.BeginWordAction {
|
||||||
|
|
||||||
@@ -358,7 +357,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
rsta.replaceSelection("/");
|
rsta.replaceSelection("/");
|
||||||
// Don't automatically complete a tag if there was a selection
|
// Don't automatically complete a tag if there was a selection
|
||||||
int dot = c.getDot();
|
int dot = c.getDot();
|
||||||
if (doc.getLanguageIsMarkup() && doc.getCompleteMarkupCloseTags() && !selection && rsta.getCloseMarkupTags() && dot > 1) {
|
if (doc.getLanguageIsMarkup() && doc.getCompleteMarkupCloseTags() && !selection && rsta.getCloseMarkupTags()
|
||||||
|
&& dot > 1) {
|
||||||
try {
|
try {
|
||||||
// Check actual char before token type, since it's quicker
|
// Check actual char before token type, since it's quicker
|
||||||
char ch = doc.charAt(dot - 2);
|
char ch = doc.charAt(dot - 2);
|
||||||
@@ -381,18 +381,15 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Discovers the name of the tag being closed. Assumes standard
|
* Discovers the name of the tag being closed. Assumes standard SGML-style
|
||||||
* SGML-style markup tags.
|
* markup tags.
|
||||||
*
|
*
|
||||||
* @param doc
|
* @param doc The document to parse.
|
||||||
* The document to parse.
|
* @param dot The location of the caret. This should be right after the start of
|
||||||
* @param dot
|
* a closing tag token (e.g. "<code></</code>" or "<code>[</code>"
|
||||||
* The location of the caret. This should be right after
|
* in the case of BBCode).
|
||||||
* the start of a closing tag token (e.g.
|
* @return The name of the tag to close, or <code>null</code> if it could not be
|
||||||
* "<code></</code>"
|
* determined.
|
||||||
* or "<code>[</code>" in the case of BBCode).
|
|
||||||
* @return The name of the tag to close, or <code>null</code> if it
|
|
||||||
* could not be determined.
|
|
||||||
*/
|
*/
|
||||||
private String discoverTagName(RSyntaxDocument doc, int dot) {
|
private String discoverTagName(RSyntaxDocument doc, int dot) {
|
||||||
Stack<String> stack = new Stack<String>();
|
Stack<String> stack = new Stack<String>();
|
||||||
@@ -416,11 +413,13 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
t = t.getNextToken();
|
t = t.getNextToken();
|
||||||
}
|
}
|
||||||
} else if (t.length() == 2 && t.charAt(0) == '/' && (t.charAt(1) == '>' || t.charAt(1) == ']')) {
|
} else if (t.length() == 2 && t.charAt(0) == '/'
|
||||||
|
&& (t.charAt(1) == '>' || t.charAt(1) == ']')) {
|
||||||
if (!stack.isEmpty()) { // Always true for valid XML
|
if (!stack.isEmpty()) { // Always true for valid XML
|
||||||
stack.pop();
|
stack.pop();
|
||||||
}
|
}
|
||||||
} else if (t.length() == 2 && (t.charAt(0) == '<' || t.charAt(0) == '[') && t.charAt(1) == '/') {
|
} else if (t.length() == 2 && (t.charAt(0) == '<' || t.charAt(0) == '[')
|
||||||
|
&& t.charAt(1) == '/') {
|
||||||
String tagName = null;
|
String tagName = null;
|
||||||
if (!stack.isEmpty()) { // Always true for valid XML
|
if (!stack.isEmpty()) { // Always true for valid XML
|
||||||
tagName = stack.pop();
|
tagName = stack.pop();
|
||||||
@@ -454,7 +453,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
setProperties(msg, "Action.CollapseCommentFolds");
|
setProperties(msg, "Action.CollapseCommentFolds");
|
||||||
}
|
}
|
||||||
|
|
||||||
public CollapseAllCommentFoldsAction(String name, Icon icon, String desc, Integer mnemonic, KeyStroke accelerator) {
|
public CollapseAllCommentFoldsAction(String name, Icon icon, String desc, Integer mnemonic,
|
||||||
|
KeyStroke accelerator) {
|
||||||
super(name, icon, desc, mnemonic, accelerator);
|
super(name, icon, desc, mnemonic, accelerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,21 +712,17 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actually does the "de-indentation." This method finds where the
|
* Actually does the "de-indentation." This method finds where the given
|
||||||
* given element's leading whitespace ends, then, if there is indeed
|
* element's leading whitespace ends, then, if there is indeed leading
|
||||||
* leading whitespace, removes either the last char in it (if it is a
|
* whitespace, removes either the last char in it (if it is a tab), or removes
|
||||||
* tab), or removes up to the number of spaces equal to a tab in the
|
* up to the number of spaces equal to a tab in the specified document (i.e., if
|
||||||
* specified document (i.e., if the tab size was 5 and there were 3
|
* the tab size was 5 and there were 3 spaces at the end of the leading
|
||||||
* spaces at the end of the leading whitespace, the three will be
|
* whitespace, the three will be removed; if there were 8 spaces, only the first
|
||||||
* removed; if there were 8 spaces, only the first 5 would be
|
* 5 would be removed).
|
||||||
* removed).
|
|
||||||
*
|
*
|
||||||
* @param elem
|
* @param elem The element to "de-indent."
|
||||||
* The element to "de-indent."
|
* @param doc The document containing the specified element.
|
||||||
* @param doc
|
* @param tabSize The size of a tab, in spaces.
|
||||||
* The document containing the specified element.
|
|
||||||
* @param tabSize
|
|
||||||
* The size of a tab, in spaces.
|
|
||||||
*/
|
*/
|
||||||
private void handleDecreaseIndent(Element elem, Document doc, int tabSize) throws BadLocationException {
|
private void handleDecreaseIndent(Element elem, Document doc, int tabSize) throws BadLocationException {
|
||||||
int start = elem.getStartOffset();
|
int start = elem.getStartOffset();
|
||||||
@@ -756,8 +752,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the previous word, but differentiates symbols from "words" to
|
* Deletes the previous word, but differentiates symbols from "words" to match
|
||||||
* match the behavior of code editors.
|
* the behavior of code editors.
|
||||||
*/
|
*/
|
||||||
public static class DeletePrevWordAction extends RTextAreaEditorKit.DeletePrevWordAction {
|
public static class DeletePrevWordAction extends RTextAreaEditorKit.DeletePrevWordAction {
|
||||||
|
|
||||||
@@ -814,8 +810,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overridden to use the programming language RSTA is displaying when
|
* Overridden to use the programming language RSTA is displaying when computing
|
||||||
* computing words to complete.
|
* words to complete.
|
||||||
*/
|
*/
|
||||||
public static class DumbCompleteWordAction extends RTextAreaEditorKit.DumbCompleteWordAction {
|
public static class DumbCompleteWordAction extends RTextAreaEditorKit.DumbCompleteWordAction {
|
||||||
|
|
||||||
@@ -849,7 +845,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
return prevWordStart;
|
return prevWordStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getPreviousWordStartInLine(RSyntaxDocument doc, Element elem, int offs) throws BadLocationException {
|
private int getPreviousWordStartInLine(RSyntaxDocument doc, Element elem, int offs)
|
||||||
|
throws BadLocationException {
|
||||||
int start = elem.getStartOffset();
|
int start = elem.getStartOffset();
|
||||||
int cur = offs;
|
int cur = offs;
|
||||||
// Skip any whitespace or non-word chars
|
// Skip any whitespace or non-word chars
|
||||||
@@ -908,13 +905,12 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overridden to not suggest word completions if the text right before
|
* Overridden to not suggest word completions if the text right before the caret
|
||||||
* the caret contains non-word characters, such as '/' or '%'.
|
* contains non-word characters, such as '/' or '%'.
|
||||||
*
|
*
|
||||||
* @param prefix
|
* @param prefix The prefix characters before the caret.
|
||||||
* The prefix characters before the caret.
|
* @return Whether the prefix could be part of a "word" in the context of the
|
||||||
* @return Whether the prefix could be part of a "word" in the context
|
* text area's current content.
|
||||||
* of the text area's current content.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected boolean isAcceptablePrefix(String prefix) {
|
protected boolean isAcceptablePrefix(String prefix) {
|
||||||
@@ -922,11 +918,10 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the specified character should be considered part
|
* Returns whether the specified character should be considered part of an
|
||||||
* of an identifier.
|
* identifier.
|
||||||
*
|
*
|
||||||
* @param ch
|
* @param ch The character.
|
||||||
* The character.
|
|
||||||
* @return Whether the character is part of an identifier.
|
* @return Whether the character is part of an identifier.
|
||||||
*/
|
*/
|
||||||
private static boolean isIdentifierChar(char ch) {
|
private static boolean isIdentifierChar(char ch) {
|
||||||
@@ -936,8 +931,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Positions the caret at the end of the word. This class is here to
|
* Positions the caret at the end of the word. This class is here to better
|
||||||
* better handle finding the "end of the word" in programming languages.
|
* handle finding the "end of the word" in programming languages.
|
||||||
*/
|
*/
|
||||||
protected static class EndWordAction extends RTextAreaEditorKit.EndWordAction {
|
protected static class EndWordAction extends RTextAreaEditorKit.EndWordAction {
|
||||||
|
|
||||||
@@ -1061,14 +1056,13 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action for moving the caret to the "matching bracket" of the bracket
|
* Action for moving the caret to the "matching bracket" of the bracket at the
|
||||||
* at the caret position (either before or after).
|
* caret position (either before or after).
|
||||||
*/
|
*/
|
||||||
public static class GoToMatchingBracketAction extends RecordableTextAction {
|
public static class GoToMatchingBracketAction extends RecordableTextAction {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the caret to the end of the document, taking into account code
|
* Moves the caret to the end of the document, taking into account code folding.
|
||||||
* folding.
|
|
||||||
*/
|
*/
|
||||||
public static class EndAction extends RTextAreaEditorKit.EndAction {
|
public static class EndAction extends RTextAreaEditorKit.EndAction {
|
||||||
|
|
||||||
@@ -1199,8 +1193,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action for when the user presses the Enter key. This is here so we can
|
* Action for when the user presses the Enter key. This is here so we can be
|
||||||
* be smart and "auto-indent" for programming languages.
|
* smart and "auto-indent" for programming languages.
|
||||||
*/
|
*/
|
||||||
public static class InsertBreakAction extends RTextAreaEditorKit.InsertBreakAction {
|
public static class InsertBreakAction extends RTextAreaEditorKit.InsertBreakAction {
|
||||||
|
|
||||||
@@ -1228,10 +1222,9 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The first location in the string past <code>pos</code> that
|
* @return The first location in the string past <code>pos</code> that is NOT a
|
||||||
* is NOT a whitespace char, or <code>-1</code> if only
|
* whitespace char, or <code>-1</code> if only whitespace chars follow
|
||||||
* whitespace chars follow <code>pos</code> (or it is the end
|
* <code>pos</code> (or it is the end position in the string).
|
||||||
* position in the string).
|
|
||||||
*/
|
*/
|
||||||
private static int atEndOfLine(int pos, String s, int sLen) {
|
private static int atEndOfLine(int pos, String s, int sLen) {
|
||||||
for (int i = pos; i < sLen; i++) {
|
for (int i = pos; i < sLen; i++) {
|
||||||
@@ -1258,13 +1251,12 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actually inserts the newline into the document, and auto-indents
|
* Actually inserts the newline into the document, and auto-indents if
|
||||||
* if appropriate. This method can be called by token makers who
|
* appropriate. This method can be called by token makers who implement a custom
|
||||||
* implement a custom action for inserting newlines.
|
* action for inserting newlines.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea
|
||||||
* @param noSelection
|
* @param noSelection Whether there is no selection.
|
||||||
* Whether there is no selection.
|
|
||||||
*/
|
*/
|
||||||
protected void handleInsertBreak(RSyntaxTextArea textArea, boolean noSelection) {
|
protected void handleInsertBreak(RSyntaxTextArea textArea, boolean noSelection) {
|
||||||
// If we're auto-indenting...
|
// If we're auto-indenting...
|
||||||
@@ -1337,7 +1329,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
t = t.getLastNonCommentNonWhitespaceToken();
|
t = t.getLastNonCommentNonWhitespaceToken();
|
||||||
if (t != null && t.isLeftCurly()) {
|
if (t != null && t.isLeftCurly()) {
|
||||||
int languageIndex = t.getLanguageIndex();
|
int languageIndex = t.getLanguageIndex();
|
||||||
if (doc.getCurlyBracesDenoteCodeBlocks(languageIndex) && getOpenBraceCount(doc, languageIndex) > 0) {
|
if (doc.getCurlyBracesDenoteCodeBlocks(languageIndex)
|
||||||
|
&& getOpenBraceCount(doc, languageIndex) > 0) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (line == textArea.getLineCount() - 1) {
|
if (line == textArea.getLineCount() - 1) {
|
||||||
sb.append('\n');
|
sb.append('\n');
|
||||||
@@ -1361,8 +1354,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action for inserting tabs. This is extended to "block indent" a
|
* Action for inserting tabs. This is extended to "block indent" a group of
|
||||||
* group of contiguous lines if they are selected.
|
* contiguous lines if they are selected.
|
||||||
*/
|
*/
|
||||||
public static class InsertTabAction extends RecordableTextAction {
|
public static class InsertTabAction extends RecordableTextAction {
|
||||||
|
|
||||||
@@ -1441,9 +1434,9 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action to move the selection and/or caret. Constructor indicates
|
* Action to move the selection and/or caret. Constructor indicates direction to
|
||||||
* direction to use. This class overrides the behavior defined in
|
* use. This class overrides the behavior defined in {@link RTextAreaEditorKit}
|
||||||
* {@link RTextAreaEditorKit} to better skip "words" in source code.
|
* to better skip "words" in source code.
|
||||||
*/
|
*/
|
||||||
public static class NextWordAction extends RTextAreaEditorKit.NextWordAction {
|
public static class NextWordAction extends RTextAreaEditorKit.NextWordAction {
|
||||||
|
|
||||||
@@ -1471,7 +1464,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
if (rsta.isCodeFoldingEnabled()) { // Start of next visible line
|
if (rsta.isCodeFoldingEnabled()) { // Start of next visible line
|
||||||
FoldManager fm = rsta.getFoldManager();
|
FoldManager fm = rsta.getFoldManager();
|
||||||
int lineCount = root.getElementCount();
|
int lineCount = root.getElementCount();
|
||||||
while (++line < lineCount && fm.isLineHidden(line));
|
while (++line < lineCount && fm.isLineHidden(line))
|
||||||
|
;
|
||||||
if (line < lineCount) { // Found a lower visible line
|
if (line < lineCount) { // Found a lower visible line
|
||||||
offs = root.getElement(line).getStartOffset();
|
offs = root.getElement(line).getStartOffset();
|
||||||
}
|
}
|
||||||
@@ -1497,7 +1491,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
else if (!Character.isWhitespace(ch)) {
|
else if (!Character.isWhitespace(ch)) {
|
||||||
do {
|
do {
|
||||||
ch = seg.next();
|
ch = seg.next();
|
||||||
} while (ch != Segment.DONE && !(doc.isIdentifierChar(languageIndex, ch) || Character.isWhitespace(ch)));
|
} while (ch != Segment.DONE
|
||||||
|
&& !(doc.isIdentifierChar(languageIndex, ch) || Character.isWhitespace(ch)));
|
||||||
}
|
}
|
||||||
// Skip any trailing whitespace
|
// Skip any trailing whitespace
|
||||||
while (Character.isWhitespace(ch)) {
|
while (Character.isWhitespace(ch)) {
|
||||||
@@ -1509,9 +1504,9 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action for when the user tries to insert a template (that is,
|
* Action for when the user tries to insert a template (that is, they've typed a
|
||||||
* they've typed a template ID and pressed the trigger character
|
* template ID and pressed the trigger character (a space) in an attempt to do
|
||||||
* (a space) in an attempt to do the substitution).
|
* the substitution).
|
||||||
*/
|
*/
|
||||||
public static class PossiblyInsertTemplateAction extends RecordableTextAction {
|
public static class PossiblyInsertTemplateAction extends RecordableTextAction {
|
||||||
|
|
||||||
@@ -1578,9 +1573,9 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action to move the selection and/or caret. Constructor indicates
|
* Action to move the selection and/or caret. Constructor indicates direction to
|
||||||
* direction to use. This class overrides the behavior defined in
|
* use. This class overrides the behavior defined in {@link RTextAreaEditorKit}
|
||||||
* {@link RTextAreaEditorKit} to better skip "words" in source code.
|
* to better skip "words" in source code.
|
||||||
*/
|
*/
|
||||||
public static class PreviousWordAction extends RTextAreaEditorKit.PreviousWordAction {
|
public static class PreviousWordAction extends RTextAreaEditorKit.PreviousWordAction {
|
||||||
|
|
||||||
@@ -1607,7 +1602,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
RSyntaxTextArea rsta = (RSyntaxTextArea) textArea;
|
RSyntaxTextArea rsta = (RSyntaxTextArea) textArea;
|
||||||
if (rsta.isCodeFoldingEnabled()) { // End of next visible line
|
if (rsta.isCodeFoldingEnabled()) { // End of next visible line
|
||||||
FoldManager fm = rsta.getFoldManager();
|
FoldManager fm = rsta.getFoldManager();
|
||||||
while (--line >= 0 && fm.isLineHidden(line));
|
while (--line >= 0 && fm.isLineHidden(line))
|
||||||
|
;
|
||||||
if (line >= 0) { // Found an earlier visible line
|
if (line >= 0) { // Found an earlier visible line
|
||||||
offs = root.getElement(line).getEndOffset() - 1;
|
offs = root.getElement(line).getEndOffset() - 1;
|
||||||
}
|
}
|
||||||
@@ -1636,7 +1632,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
else if (!Character.isWhitespace(ch)) {
|
else if (!Character.isWhitespace(ch)) {
|
||||||
do {
|
do {
|
||||||
ch = seg.previous();
|
ch = seg.previous();
|
||||||
} while (ch != Segment.DONE && !(doc.isIdentifierChar(languageIndex, ch) || Character.isWhitespace(ch)));
|
} while (ch != Segment.DONE
|
||||||
|
&& !(doc.isIdentifierChar(languageIndex, ch) || Character.isWhitespace(ch)));
|
||||||
}
|
}
|
||||||
offs -= seg.getEndIndex() - seg.getIndex();
|
offs -= seg.getEndIndex() - seg.getIndex();
|
||||||
if (ch != Segment.DONE) {
|
if (ch != Segment.DONE) {
|
||||||
@@ -1647,8 +1644,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects the word around the caret. This class is here to better
|
* Selects the word around the caret. This class is here to better handle
|
||||||
* handle selecting "words" in programming languages.
|
* selecting "words" in programming languages.
|
||||||
*/
|
*/
|
||||||
public static class SelectWordAction extends RTextAreaEditorKit.SelectWordAction {
|
public static class SelectWordAction extends RTextAreaEditorKit.SelectWordAction {
|
||||||
|
|
||||||
@@ -1660,8 +1657,7 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action that toggles whether the currently selected lines are
|
* Action that toggles whether the currently selected lines are commented.
|
||||||
* commented.
|
|
||||||
*/
|
*/
|
||||||
public static class ToggleCommentAction extends RecordableTextAction {
|
public static class ToggleCommentAction extends RecordableTextAction {
|
||||||
|
|
||||||
@@ -1714,7 +1710,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean getDoAdd(Document doc, Element map, int startLine, int endLine, String[] startEnd) throws BadLocationException {
|
private boolean getDoAdd(Document doc, Element map, int startLine, int endLine, String[] startEnd)
|
||||||
|
throws BadLocationException {
|
||||||
boolean doAdd = false;
|
boolean doAdd = false;
|
||||||
for (int i = startLine; i <= endLine; i++) {
|
for (int i = startLine; i <= endLine; i++) {
|
||||||
Element elem = map.getElement(i);
|
Element elem = map.getElement(i);
|
||||||
@@ -1728,7 +1725,8 @@ public class RSyntaxTextAreaEditorKit extends RTextAreaEditorKit {
|
|||||||
return doAdd;
|
return doAdd;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleToggleComment(Element elem, Document doc, String[] startEnd, boolean add) throws BadLocationException {
|
private void handleToggleComment(Element elem, Document doc, String[] startEnd, boolean add)
|
||||||
|
throws BadLocationException {
|
||||||
int start = elem.getStartOffset();
|
int start = elem.getStartOffset();
|
||||||
int end = elem.getEndOffset() - 1;
|
int end = elem.getEndOffset() - 1;
|
||||||
if (add) {
|
if (add) {
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import javax.swing.JPanel;
|
|||||||
* @author Robert Futrell
|
* @author Robert Futrell
|
||||||
* @version 0.6
|
* @version 0.6
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "checkstyle:visibilitymodifier" })
|
|
||||||
public class Style implements Cloneable {
|
public class Style implements Cloneable {
|
||||||
|
|
||||||
public static final Color DEFAULT_FOREGROUND = Color.BLACK;
|
public static final Color DEFAULT_FOREGROUND = Color.BLACK;
|
||||||
@@ -41,8 +40,8 @@ public class Style implements Cloneable {
|
|||||||
public FontMetrics fontMetrics;
|
public FontMetrics fontMetrics;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new style defaulting to black foreground, no
|
* Creates a new style defaulting to black foreground, no background, and no
|
||||||
* background, and no styling.
|
* styling.
|
||||||
*/
|
*/
|
||||||
public Style() {
|
public Style() {
|
||||||
this(DEFAULT_FOREGROUND);
|
this(DEFAULT_FOREGROUND);
|
||||||
@@ -51,8 +50,7 @@ public class Style implements Cloneable {
|
|||||||
/**
|
/**
|
||||||
* Creates a new style with the specified foreground and no styling.
|
* Creates a new style with the specified foreground and no styling.
|
||||||
*
|
*
|
||||||
* @param fg
|
* @param fg The foreground color to use.
|
||||||
* The foreground color to use.
|
|
||||||
*/
|
*/
|
||||||
public Style(Color fg) {
|
public Style(Color fg) {
|
||||||
this(fg, DEFAULT_BACKGROUND);
|
this(fg, DEFAULT_BACKGROUND);
|
||||||
@@ -61,10 +59,8 @@ public class Style implements Cloneable {
|
|||||||
/**
|
/**
|
||||||
* Creates a new style with the specified colors and no styling.
|
* Creates a new style with the specified colors and no styling.
|
||||||
*
|
*
|
||||||
* @param fg
|
* @param fg The foreground color to use.
|
||||||
* The foreground color to use.
|
* @param bg The background color to use.
|
||||||
* @param bg
|
|
||||||
* The background color to use.
|
|
||||||
*/
|
*/
|
||||||
public Style(Color fg, Color bg) {
|
public Style(Color fg, Color bg) {
|
||||||
this(fg, bg, DEFAULT_FONT);
|
this(fg, bg, DEFAULT_FONT);
|
||||||
@@ -73,12 +69,9 @@ public class Style implements Cloneable {
|
|||||||
/**
|
/**
|
||||||
* Creates a new style.
|
* Creates a new style.
|
||||||
*
|
*
|
||||||
* @param fg
|
* @param fg The foreground color to use.
|
||||||
* The foreground color to use.
|
* @param bg The background color to use.
|
||||||
* @param bg
|
* @param font The font for this syntax scheme.
|
||||||
* The background color to use.
|
|
||||||
* @param font
|
|
||||||
* The font for this syntax scheme.
|
|
||||||
*/
|
*/
|
||||||
public Style(Color fg, Color bg, Font font) {
|
public Style(Color fg, Color bg, Font font) {
|
||||||
this(fg, bg, font, false);
|
this(fg, bg, font, false);
|
||||||
@@ -87,14 +80,10 @@ public class Style implements Cloneable {
|
|||||||
/**
|
/**
|
||||||
* Creates a new style.
|
* Creates a new style.
|
||||||
*
|
*
|
||||||
* @param fg
|
* @param fg The foreground color to use.
|
||||||
* The foreground color to use.
|
* @param bg The background color to use.
|
||||||
* @param bg
|
* @param font The font for this syntax scheme.
|
||||||
* The background color to use.
|
* @param underline Whether or not to underline tokens with this style.
|
||||||
* @param font
|
|
||||||
* The font for this syntax scheme.
|
|
||||||
* @param underline
|
|
||||||
* Whether or not to underline tokens with this style.
|
|
||||||
*/
|
*/
|
||||||
public Style(Color fg, Color bg, Font font, boolean underline) {
|
public Style(Color fg, Color bg, Font font, boolean underline) {
|
||||||
foreground = fg;
|
foreground = fg;
|
||||||
@@ -108,8 +97,7 @@ public class Style implements Cloneable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not two (possibly <code>null</code>) objects are
|
* Returns whether or not two (possibly <code>null</code>) objects are equal.
|
||||||
* equal.
|
|
||||||
*/
|
*/
|
||||||
private boolean areEqual(Object o1, Object o2) {
|
private boolean areEqual(Object o1, Object o2) {
|
||||||
return (o1 == null && o2 == null) || (o1 != null && o1.equals(o2));
|
return (o1 == null && o2 == null) || (o1 != null && o1.equals(o2));
|
||||||
@@ -140,17 +128,16 @@ public class Style implements Cloneable {
|
|||||||
/**
|
/**
|
||||||
* Returns whether or not two syntax schemes are equal.
|
* Returns whether or not two syntax schemes are equal.
|
||||||
*
|
*
|
||||||
* @param o2
|
* @param o2 The object with which to compare this syntax scheme.
|
||||||
* The object with which to compare this syntax scheme.
|
* @return Whether or not these two syntax schemes represent the same scheme.
|
||||||
* @return Whether or not these two syntax schemes represent the same
|
|
||||||
* scheme.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o2) {
|
public boolean equals(Object o2) {
|
||||||
if (o2 instanceof Style) {
|
if (o2 instanceof Style) {
|
||||||
Style ss2 = (Style) o2;
|
Style ss2 = (Style) o2;
|
||||||
if (this.underline == ss2.underline && areEqual(foreground, ss2.foreground) && areEqual(background, ss2.background)
|
if (this.underline == ss2.underline && areEqual(foreground, ss2.foreground)
|
||||||
&& areEqual(font, ss2.font) && areEqual(fontMetrics, ss2.fontMetrics)) {
|
&& areEqual(background, ss2.background) && areEqual(font, ss2.font)
|
||||||
|
&& areEqual(fontMetrics, ss2.fontMetrics)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,12 +145,11 @@ public class Style implements Cloneable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the hash code to use when adding this syntax scheme to
|
* Computes the hash code to use when adding this syntax scheme to hash tables.
|
||||||
* hash tables.
|
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* This method is implemented, since {@link #equals(Object)} is implemented,
|
* This method is implemented, since {@link #equals(Object)} is implemented, to
|
||||||
* to keep FindBugs happy.
|
* keep FindBugs happy.
|
||||||
*
|
*
|
||||||
* @return The hash code.
|
* @return The hash code.
|
||||||
*/
|
*/
|
||||||
@@ -186,6 +172,7 @@ public class Style implements Cloneable {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[Style: foreground: " + foreground + ", background: " + background + ", underline: " + underline + ", font: " + font + "]";
|
return "[Style: foreground: " + foreground + ", background: " + background + ", underline: " + underline
|
||||||
|
+ ", font: " + font + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,8 +24,8 @@ import org.xml.sax.helpers.DefaultHandler;
|
|||||||
import org.xml.sax.helpers.XMLReaderFactory;
|
import org.xml.sax.helpers.XMLReaderFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The set of colors and styles used by an <code>RSyntaxTextArea</code> to
|
* The set of colors and styles used by an <code>RSyntaxTextArea</code> to color
|
||||||
* color tokens.
|
* tokens.
|
||||||
* <p>
|
* <p>
|
||||||
* You can use this class to programmatically set the fonts and colors used in
|
* You can use this class to programmatically set the fonts and colors used in
|
||||||
* an RSyntaxTextArea, but for more powerful, externalized control, consider
|
* an RSyntaxTextArea, but for more powerful, externalized control, consider
|
||||||
@@ -35,20 +35,18 @@ import org.xml.sax.helpers.XMLReaderFactory;
|
|||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @see Theme
|
* @see Theme
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "checkstyle:magicnumber" })
|
|
||||||
public class SyntaxScheme implements Cloneable, TokenTypes {
|
public class SyntaxScheme implements Cloneable, TokenTypes {
|
||||||
|
|
||||||
private Style[] styles;
|
private Style[] styles;
|
||||||
private static final String VERSION = "*ver1";
|
private static final String VERSION = "*ver1";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a color scheme that either has all color values set to
|
* Creates a color scheme that either has all color values set to a default
|
||||||
* a default value or set to <code>null</code>.
|
* value or set to <code>null</code>.
|
||||||
*
|
*
|
||||||
* @param useDefaults
|
* @param useDefaults If <code>true</code>, all color values will be set to
|
||||||
* If <code>true</code>, all color values will
|
* default colors; if <code>false</code>, all colors will be
|
||||||
* be set to default colors; if <code>false</code>, all colors
|
* initially <code>null</code>.
|
||||||
* will be initially <code>null</code>.
|
|
||||||
*/
|
*/
|
||||||
public SyntaxScheme(boolean useDefaults) {
|
public SyntaxScheme(boolean useDefaults) {
|
||||||
styles = new Style[DEFAULT_NUM_TOKEN_TYPES];
|
styles = new Style[DEFAULT_NUM_TOKEN_TYPES];
|
||||||
@@ -60,11 +58,9 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
/**
|
/**
|
||||||
* Creates a default color scheme.
|
* Creates a default color scheme.
|
||||||
*
|
*
|
||||||
* @param baseFont
|
* @param baseFont The base font to use. Keywords will be a bold version of this
|
||||||
* The base font to use. Keywords will be a bold version
|
* font, and comments will be an italicized version of this
|
||||||
* of this font, and comments will be an italicized version of
|
* font.
|
||||||
* this
|
|
||||||
* font.
|
|
||||||
*/
|
*/
|
||||||
public SyntaxScheme(Font baseFont) {
|
public SyntaxScheme(Font baseFont) {
|
||||||
this(baseFont, true);
|
this(baseFont, true);
|
||||||
@@ -73,14 +69,11 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
/**
|
/**
|
||||||
* Creates a default color scheme.
|
* Creates a default color scheme.
|
||||||
*
|
*
|
||||||
* @param baseFont
|
* @param baseFont The base font to use. Keywords will be a bold version of
|
||||||
* The base font to use. Keywords will be a bold version
|
* this font, and comments will be an italicized version of
|
||||||
* of this font, and comments will be an italicized version of
|
* this font.
|
||||||
* this
|
* @param fontStyles Whether bold and italic should be used in the scheme (vs.
|
||||||
* font.
|
* all tokens using a plain font).
|
||||||
* @param fontStyles
|
|
||||||
* Whether bold and italic should be used in the scheme
|
|
||||||
* (vs. all tokens using a plain font).
|
|
||||||
*/
|
*/
|
||||||
public SyntaxScheme(Font baseFont, boolean fontStyles) {
|
public SyntaxScheme(Font baseFont, boolean fontStyles) {
|
||||||
styles = new Style[DEFAULT_NUM_TOKEN_TYPES];
|
styles = new Style[DEFAULT_NUM_TOKEN_TYPES];
|
||||||
@@ -90,16 +83,14 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
/**
|
/**
|
||||||
* Changes the "base font" for this syntax scheme. This is called by
|
* Changes the "base font" for this syntax scheme. This is called by
|
||||||
* <code>RSyntaxTextArea</code> when its font changes via
|
* <code>RSyntaxTextArea</code> when its font changes via
|
||||||
* <code>setFont()</code>. This looks for tokens that use a derivative of
|
* <code>setFont()</code>. This looks for tokens that use a derivative of the
|
||||||
* the text area's old font (but bolded and/or italicized) and make them
|
* text area's old font (but bolded and/or italicized) and make them use the new
|
||||||
* use the new font with those stylings instead. This is desirable because
|
* font with those stylings instead. This is desirable because most programmers
|
||||||
* most programmers prefer a single font to be used in their text editor,
|
* prefer a single font to be used in their text editor, but might want bold
|
||||||
* but might want bold (say for keywords) or italics.
|
* (say for keywords) or italics.
|
||||||
*
|
*
|
||||||
* @param old
|
* @param old The old font of the text area.
|
||||||
* The old font of the text area.
|
* @param font The new font of the text area.
|
||||||
* @param font
|
|
||||||
* The new font of the text area.
|
|
||||||
*/
|
*/
|
||||||
void changeBaseFont(Font old, Font font) {
|
void changeBaseFont(Font old, Font font) {
|
||||||
for (int i = 0; i < styles.length; i++) {
|
for (int i = 0; i < styles.length; i++) {
|
||||||
@@ -141,11 +132,9 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
/**
|
/**
|
||||||
* Tests whether this color scheme is the same as another color scheme.
|
* Tests whether this color scheme is the same as another color scheme.
|
||||||
*
|
*
|
||||||
* @param otherScheme
|
* @param otherScheme The color scheme to compare to.
|
||||||
* The color scheme to compare to.
|
* @return <code>true</code> if this color scheme and <code>otherScheme</code>
|
||||||
* @return <code>true</code> if this color scheme and
|
* are the same scheme; <code>false</code> otherwise.
|
||||||
* <code>otherScheme</code> are the same scheme;
|
|
||||||
* <code>false</code> otherwise.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object otherScheme) {
|
public boolean equals(Object otherScheme) {
|
||||||
@@ -172,8 +161,7 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
* Returns a hex string representing an RGB color, of the form
|
* Returns a hex string representing an RGB color, of the form
|
||||||
* <code>"$rrggbb"</code>.
|
* <code>"$rrggbb"</code>.
|
||||||
*
|
*
|
||||||
* @param c
|
* @param c The color.
|
||||||
* The color.
|
|
||||||
* @return The string representation of the color.
|
* @return The string representation of the color.
|
||||||
*/
|
*/
|
||||||
private static String getHexString(Color c) {
|
private static String getHexString(Color c) {
|
||||||
@@ -183,8 +171,7 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
/**
|
/**
|
||||||
* Returns the specified style.
|
* Returns the specified style.
|
||||||
*
|
*
|
||||||
* @param index
|
* @param index The index of the style.
|
||||||
* The index of the style.
|
|
||||||
* @return The style.
|
* @return The style.
|
||||||
* @see #setStyle(int, Style)
|
* @see #setStyle(int, Style)
|
||||||
* @see #getStyleCount()
|
* @see #getStyleCount()
|
||||||
@@ -204,12 +191,12 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by third party implementors e.g. SquirreL SQL. Most applications do
|
* Used by third party implementors e.g. SquirreL SQL. Most applications do not
|
||||||
* not need to call this method.
|
* need to call this method.
|
||||||
* <p>
|
* <p>
|
||||||
* Note that the returned array is not a copy of the style data; editing the
|
* Note that the returned array is not a copy of the style data; editing the
|
||||||
* array will modify the styles used by any <code>RSyntaxTextArea</code>
|
* array will modify the styles used by any <code>RSyntaxTextArea</code> using
|
||||||
* using this scheme.
|
* this scheme.
|
||||||
*
|
*
|
||||||
* @return The style array.
|
* @return The style array.
|
||||||
* @see #setStyles(Style[])
|
* @see #setStyles(Style[])
|
||||||
@@ -219,8 +206,8 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is implemented to be consistent with {@link #equals(Object)}.
|
* This is implemented to be consistent with {@link #equals(Object)}. This is a
|
||||||
* This is a requirement to keep FindBugs happy.
|
* requirement to keep FindBugs happy.
|
||||||
*
|
*
|
||||||
* @return The hash code for this object.
|
* @return The hash code for this object.
|
||||||
*/
|
*/
|
||||||
@@ -243,19 +230,15 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
* Loads a syntax scheme from an input stream.
|
* Loads a syntax scheme from an input stream.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* Consider using the {@link Theme} class for saving and loading RSTA
|
* Consider using the {@link Theme} class for saving and loading RSTA styles
|
||||||
* styles rather than using this API.
|
* rather than using this API.
|
||||||
*
|
*
|
||||||
* @param baseFont
|
* @param baseFont The font to use as the "base" for the syntax scheme. If this
|
||||||
* The font to use as the "base" for the syntax scheme.
|
* is <code>null</code>, a default monospaced font is used.
|
||||||
* If this is <code>null</code>, a default monospaced font is
|
* @param in The stream to load from. It is up to the caller to close this
|
||||||
* used.
|
* stream when they are done.
|
||||||
* @param in
|
|
||||||
* The stream to load from. It is up to the caller to close this
|
|
||||||
* stream when they are done.
|
|
||||||
* @return The syntax scheme.
|
* @return The syntax scheme.
|
||||||
* @throws IOException
|
* @throws IOException If an IO error occurs.
|
||||||
* If an IO error occurs.
|
|
||||||
*/
|
*/
|
||||||
public static SyntaxScheme load(Font baseFont, InputStream in) throws IOException {
|
public static SyntaxScheme load(Font baseFont, InputStream in) throws IOException {
|
||||||
if (baseFont == null) {
|
if (baseFont == null) {
|
||||||
@@ -266,15 +249,14 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a syntax highlighting color scheme from a string created from
|
* Loads a syntax highlighting color scheme from a string created from
|
||||||
* <code>toCommaSeparatedString</code>. This method is useful for saving
|
* <code>toCommaSeparatedString</code>. This method is useful for saving and
|
||||||
* and restoring color schemes.
|
* restoring color schemes.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* Consider using the {@link Theme} class for saving and loading RSTA
|
* Consider using the {@link Theme} class for saving and loading RSTA styles
|
||||||
* styles rather than using this API.
|
* rather than using this API.
|
||||||
*
|
*
|
||||||
* @param string
|
* @param string A string generated from {@link #toCommaSeparatedString()}.
|
||||||
* A string generated from {@link #toCommaSeparatedString()}.
|
|
||||||
* @return A color scheme.
|
* @return A color scheme.
|
||||||
* @see #toCommaSeparatedString()
|
* @see #toCommaSeparatedString()
|
||||||
*/
|
*/
|
||||||
@@ -284,21 +266,20 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a syntax highlighting color scheme from a string created from
|
* Loads a syntax highlighting color scheme from a string created from
|
||||||
* <code>toCommaSeparatedString</code>. This method is useful for saving
|
* <code>toCommaSeparatedString</code>. This method is useful for saving and
|
||||||
* and restoring color schemes.
|
* restoring color schemes.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* Consider using the {@link Theme} class for saving and loading RSTA
|
* Consider using the {@link Theme} class for saving and loading RSTA styles
|
||||||
* styles rather than using this API.
|
* rather than using this API.
|
||||||
*
|
*
|
||||||
* @param string
|
* @param string A string generated from
|
||||||
* A string generated from {@link #toCommaSeparatedString()}.
|
* {@link #toCommaSeparatedString()}.
|
||||||
* @param tokenTypeCount
|
* @param tokenTypeCount The number of token types saved in this string. This
|
||||||
* The number of token types saved in this string.
|
* should be the number of token types saved by your
|
||||||
* This should be the number of token types saved by your custom
|
* custom SyntaxScheme subclass, or
|
||||||
* SyntaxScheme subclass,
|
* {@link TokenTypes#DEFAULT_NUM_TOKEN_TYPES} if you used
|
||||||
* or {@link TokenTypes#DEFAULT_NUM_TOKEN_TYPES} if you used the
|
* the standard implementation (which most people will).
|
||||||
* standard implementation (which most people will).
|
|
||||||
* @return A color scheme.
|
* @return A color scheme.
|
||||||
* @see #loadFromString(String)
|
* @see #loadFromString(String)
|
||||||
* @see #toCommaSeparatedString()
|
* @see #toCommaSeparatedString()
|
||||||
@@ -314,7 +295,8 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
}
|
}
|
||||||
int tokenCount = tokenTypeCount * 7 + 1; // Version string
|
int tokenCount = tokenTypeCount * 7 + 1; // Version string
|
||||||
if (tokens.length != tokenCount) {
|
if (tokens.length != tokenCount) {
|
||||||
throw new Exception("Not enough tokens in packed color scheme: expected " + tokenCount + ", found " + tokens.length);
|
throw new Exception("Not enough tokens in packed color scheme: expected " + tokenCount + ", found "
|
||||||
|
+ tokens.length);
|
||||||
}
|
}
|
||||||
// Use StyleContext to create fonts to get composite fonts for
|
// Use StyleContext to create fonts to get composite fonts for
|
||||||
// Asian glyphs.
|
// Asian glyphs.
|
||||||
@@ -373,10 +355,8 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
/**
|
/**
|
||||||
* Restores all colors and fonts to their default values.
|
* Restores all colors and fonts to their default values.
|
||||||
*
|
*
|
||||||
* @param baseFont
|
* @param baseFont The base font to use when creating this scheme. If this is
|
||||||
* The base font to use when creating this scheme. If
|
* <code>null</code>, then a default monospaced font is used.
|
||||||
* this is <code>null</code>, then a default monospaced font is
|
|
||||||
* used.
|
|
||||||
*/
|
*/
|
||||||
public void restoreDefaults(Font baseFont) {
|
public void restoreDefaults(Font baseFont) {
|
||||||
restoreDefaults(baseFont, true);
|
restoreDefaults(baseFont, true);
|
||||||
@@ -385,13 +365,10 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
/**
|
/**
|
||||||
* Restores all colors and fonts to their default values.
|
* Restores all colors and fonts to their default values.
|
||||||
*
|
*
|
||||||
* @param baseFont
|
* @param baseFont The base font to use when creating this scheme. If this is
|
||||||
* The base font to use when creating this scheme. If
|
* <code>null</code>, then a default monospaced font is used.
|
||||||
* this is <code>null</code>, then a default monospaced font is
|
* @param fontStyles Whether bold and italic should be used in the scheme (vs.
|
||||||
* used.
|
* all tokens using a plain font).
|
||||||
* @param fontStyles
|
|
||||||
* Whether bold and italic should be used in the scheme
|
|
||||||
* (vs. all tokens using a plain font).
|
|
||||||
*/
|
*/
|
||||||
public void restoreDefaults(Font baseFont, boolean fontStyles) {
|
public void restoreDefaults(Font baseFont, boolean fontStyles) {
|
||||||
// Colors used by tokens.
|
// Colors used by tokens.
|
||||||
@@ -473,10 +450,8 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
/**
|
/**
|
||||||
* Sets a style to use when rendering a token type.
|
* Sets a style to use when rendering a token type.
|
||||||
*
|
*
|
||||||
* @param type
|
* @param type The token type.
|
||||||
* The token type.
|
* @param style The style for the token type.
|
||||||
* @param style
|
|
||||||
* The style for the token type.
|
|
||||||
* @see #getStyle(int)
|
* @see #getStyle(int)
|
||||||
*/
|
*/
|
||||||
public void setStyle(int type, Style style) {
|
public void setStyle(int type, Style style) {
|
||||||
@@ -484,14 +459,12 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by third party implementors e.g. SquirreL SQL. Most applications do
|
* Used by third party implementors e.g. SquirreL SQL. Most applications do not
|
||||||
* not need to call this method; individual styles can be set via
|
* need to call this method; individual styles can be set via
|
||||||
* {@link #setStyle(int, Style)}.
|
* {@link #setStyle(int, Style)}.
|
||||||
*
|
*
|
||||||
* @param styles
|
* @param styles The new array of styles to use. Note that this should have
|
||||||
* The new array of styles to use. Note that this should
|
* length of at least {@link TokenTypes#DEFAULT_NUM_TOKEN_TYPES}.
|
||||||
* have length of at least
|
|
||||||
* {@link TokenTypes#DEFAULT_NUM_TOKEN_TYPES}.
|
|
||||||
* @see #setStyle(int, Style)
|
* @see #setStyle(int, Style)
|
||||||
* @see #getStyles()
|
* @see #getStyles()
|
||||||
*/
|
*/
|
||||||
@@ -500,9 +473,9 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the color represented by a string. If the first char in the
|
* Returns the color represented by a string. If the first char in the string is
|
||||||
* string is '<code>$</code>', it is assumed to be in hex, otherwise it is
|
* '<code>$</code>', it is assumed to be in hex, otherwise it is assumed to be
|
||||||
* assumed to be decimal. So, for example, both of these:
|
* decimal. So, for example, both of these:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* "$00ff00"
|
* "$00ff00"
|
||||||
@@ -511,8 +484,7 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
*
|
*
|
||||||
* will return <code>new Color(0, 255, 0)</code>.
|
* will return <code>new Color(0, 255, 0)</code>.
|
||||||
*
|
*
|
||||||
* @param s
|
* @param s The string to evaluate.
|
||||||
* The string to evaluate.
|
|
||||||
* @return The color.
|
* @return The color.
|
||||||
*/
|
*/
|
||||||
private static Color stringToColor(String s) {
|
private static Color stringToColor(String s) {
|
||||||
@@ -523,26 +495,24 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns this syntax highlighting scheme as a comma-separated list of
|
* Returns this syntax highlighting scheme as a comma-separated list of values
|
||||||
* values as follows:
|
* as follows:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>If a color is non-null, it is added as a 24-bit integer
|
* <li>If a color is non-null, it is added as a 24-bit integer of the form
|
||||||
* of the form <code>((r<*lt;16) | (g<*lt;8) | (b))</code>; if
|
* <code>((r<*lt;16) | (g<*lt;8) | (b))</code>; if it is
|
||||||
* it is <code>null</code>, it is added as "<i>-,</i>".
|
* <code>null</code>, it is added as "<i>-,</i>".
|
||||||
* <li>The font and style (bold/italic) is added as an integer like so:
|
* <li>The font and style (bold/italic) is added as an integer like so:
|
||||||
* "<i>family,</i> <i>style,</i> <i>size</i>".
|
* "<i>family,</i> <i>style,</i> <i>size</i>".
|
||||||
* <li>The entire syntax highlighting scheme is thus one long string of
|
* <li>The entire syntax highlighting scheme is thus one long string of color
|
||||||
* color schemes of the format "<i>i,[fg],[bg],uline,[style]</i>,
|
* schemes of the format "<i>i,[fg],[bg],uline,[style]</i>, where:
|
||||||
* where:
|
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><code>i</code> is the index of the syntax scheme.
|
* <li><code>i</code> is the index of the syntax scheme.
|
||||||
* <li><i>fg</i> and <i>bg</i> are the foreground and background
|
* <li><i>fg</i> and <i>bg</i> are the foreground and background colors for the
|
||||||
* colors for the scheme, and may be null (represented by
|
* scheme, and may be null (represented by <code>-</code>).
|
||||||
* <code>-</code>).
|
* <li><code>uline</code> is whether or not the font should be underlined, and
|
||||||
* <li><code>uline</code> is whether or not the font should be
|
* is either <code>t</code> or <code>f</code>.
|
||||||
* underlined, and is either <code>t</code> or <code>f</code>.
|
* <li><code>style</code> is the <code>family,style,size</code> triplet
|
||||||
* <li><code>style</code> is the <code>family,style,size</code>
|
* described above.
|
||||||
* triplet described above.
|
|
||||||
* </ul>
|
* </ul>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
@@ -566,7 +536,8 @@ public class SyntaxScheme implements Cloneable, TokenTypes {
|
|||||||
sb.append(ss.underline ? "t," : "f,");
|
sb.append(ss.underline ? "t," : "f,");
|
||||||
Font font = ss.font;
|
Font font = ss.font;
|
||||||
if (font != null) {
|
if (font != null) {
|
||||||
sb.append(font.getFamily()).append(',').append(font.getStyle()).append(',').append(font.getSize()).append(',');
|
sb.append(font.getFamily()).append(',').append(font.getStyle()).append(',').append(font.getSize())
|
||||||
|
.append(',');
|
||||||
} else {
|
} else {
|
||||||
sb.append("-,,,");
|
sb.append("-,,,");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,15 +62,14 @@ import org.xml.sax.helpers.DefaultHandler;
|
|||||||
* for various tasks.
|
* for various tasks.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* Note that to save a <code>Theme</code> via {@link #save(OutputStream)},
|
* Note that to save a <code>Theme</code> via {@link #save(OutputStream)}, you
|
||||||
* you must currently create a <code>Theme</code> from a text area wrapped in
|
* must currently create a <code>Theme</code> from a text area wrapped in an
|
||||||
* an <code>RTextScrollPane</code>, so that the color information for the
|
* <code>RTextScrollPane</code>, so that the color information for the gutter
|
||||||
* gutter can be retrieved.
|
* can be retrieved.
|
||||||
*
|
*
|
||||||
* @author Robert Futrell
|
* @author Robert Futrell
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "checkstyle:visibilitymodifier" })
|
|
||||||
public class Theme {
|
public class Theme {
|
||||||
|
|
||||||
public Font baseFont;
|
public Font baseFont;
|
||||||
@@ -107,10 +106,9 @@ public class Theme {
|
|||||||
/**
|
/**
|
||||||
* Private constructor, used when loading from a stream.
|
* Private constructor, used when loading from a stream.
|
||||||
*
|
*
|
||||||
* @param baseFont
|
* @param baseFont The default font to use for any "base font" properties not
|
||||||
* The default font to use for any "base font" properties
|
* specified in the theme XML. If this is <code>null</code>, a
|
||||||
* not specified in the theme XML. If this is <code>null</code>,
|
* default monospaced font will be used.
|
||||||
* a default monospaced font will be used.
|
|
||||||
*/
|
*/
|
||||||
private Theme(Font baseFont) {
|
private Theme(Font baseFont) {
|
||||||
// Optional fields that require a default value.
|
// Optional fields that require a default value.
|
||||||
@@ -120,11 +118,10 @@ public class Theme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a theme from an RSyntaxTextArea. It should be contained in
|
* Creates a theme from an RSyntaxTextArea. It should be contained in an
|
||||||
* an <code>RTextScrollPane</code> to get all gutter color information.
|
* <code>RTextScrollPane</code> to get all gutter color information.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area.
|
||||||
* The text area.
|
|
||||||
*/
|
*/
|
||||||
public Theme(RSyntaxTextArea textArea) {
|
public Theme(RSyntaxTextArea textArea) {
|
||||||
baseFont = textArea.getFont();
|
baseFont = textArea.getFont();
|
||||||
@@ -169,8 +166,7 @@ public class Theme {
|
|||||||
/**
|
/**
|
||||||
* Applies this theme to a text area.
|
* Applies this theme to a text area.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area to apply this theme to.
|
||||||
* The text area to apply this theme to.
|
|
||||||
*/
|
*/
|
||||||
public void apply(RSyntaxTextArea textArea) {
|
public void apply(RSyntaxTextArea textArea) {
|
||||||
textArea.setFont(baseFont);
|
textArea.setFont(baseFont);
|
||||||
@@ -266,8 +262,8 @@ public class Theme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the default "selected text" color to use if "default" is
|
* Returns the default "selected text" color to use if "default" is specified in
|
||||||
* specified in a theme.
|
* a theme.
|
||||||
*
|
*
|
||||||
* @return The default selection foreground color to use.
|
* @return The default selection foreground color to use.
|
||||||
* @see #getDefaultSelectionBG()
|
* @see #getDefaultSelectionBG()
|
||||||
@@ -289,12 +285,9 @@ public class Theme {
|
|||||||
/**
|
/**
|
||||||
* Returns the specified font.
|
* Returns the specified font.
|
||||||
*
|
*
|
||||||
* @param family
|
* @param family The font family.
|
||||||
* The font family.
|
* @param style The style of font.
|
||||||
* @param style
|
* @param size The size of the font.
|
||||||
* The style of font.
|
|
||||||
* @param size
|
|
||||||
* The size of the font.
|
|
||||||
* @return The font.
|
* @return The font.
|
||||||
*/
|
*/
|
||||||
private static Font getFont(String family, int style, int size) {
|
private static Font getFont(String family, int style, int size) {
|
||||||
@@ -306,12 +299,10 @@ public class Theme {
|
|||||||
/**
|
/**
|
||||||
* Loads a theme.
|
* Loads a theme.
|
||||||
*
|
*
|
||||||
* @param in
|
* @param in The input stream to read from. This will be closed when this method
|
||||||
* The input stream to read from. This will be closed when this
|
* returns.
|
||||||
* method returns.
|
|
||||||
* @return The theme.
|
* @return The theme.
|
||||||
* @throws IOException
|
* @throws IOException If an IO error occurs.
|
||||||
* If an IO error occurs.
|
|
||||||
* @see #save(OutputStream)
|
* @see #save(OutputStream)
|
||||||
*/
|
*/
|
||||||
public static Theme load(InputStream in) throws IOException {
|
public static Theme load(InputStream in) throws IOException {
|
||||||
@@ -321,16 +312,13 @@ public class Theme {
|
|||||||
/**
|
/**
|
||||||
* Loads a theme.
|
* Loads a theme.
|
||||||
*
|
*
|
||||||
* @param in
|
* @param in The input stream to read from. This will be closed when this
|
||||||
* The input stream to read from. This will be closed when this
|
* method returns.
|
||||||
* method returns.
|
* @param baseFont The default font to use for any "base font" properties not
|
||||||
* @param baseFont
|
* specified in the theme XML. If this is <code>null</code>, a
|
||||||
* The default font to use for any "base font" properties
|
* default monospaced font will be used.
|
||||||
* not specified in the theme XML. If this is <code>null</code>,
|
|
||||||
* a default monospaced font will be used.
|
|
||||||
* @return The theme.
|
* @return The theme.
|
||||||
* @throws IOException
|
* @throws IOException If an IO error occurs.
|
||||||
* If an IO error occurs.
|
|
||||||
* @see #save(OutputStream)
|
* @see #save(OutputStream)
|
||||||
*/
|
*/
|
||||||
public static Theme load(InputStream in, Font baseFont) throws IOException {
|
public static Theme load(InputStream in, Font baseFont) throws IOException {
|
||||||
@@ -347,10 +335,8 @@ public class Theme {
|
|||||||
/**
|
/**
|
||||||
* Saves this theme to an output stream.
|
* Saves this theme to an output stream.
|
||||||
*
|
*
|
||||||
* @param out
|
* @param out The output stream to write to.
|
||||||
* The output stream to write to.
|
* @throws IOException If an IO error occurs.
|
||||||
* @throws IOException
|
|
||||||
* If an IO error occurs.
|
|
||||||
* @see #load(InputStream)
|
* @see #load(InputStream)
|
||||||
*/
|
*/
|
||||||
public void save(OutputStream out) throws IOException {
|
public void save(OutputStream out) throws IOException {
|
||||||
@@ -497,9 +483,9 @@ public class Theme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the color represented by a string. The input is expected to
|
* Returns the color represented by a string. The input is expected to be a
|
||||||
* be a 6-digit hex string, optionally prefixed by a '$'. For example,
|
* 6-digit hex string, optionally prefixed by a '$'. For example, either of the
|
||||||
* either of the following:
|
* following:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* "$00ff00"
|
* "$00ff00"
|
||||||
@@ -508,8 +494,7 @@ public class Theme {
|
|||||||
*
|
*
|
||||||
* will return <code>new Color(0, 255, 0)</code>.
|
* will return <code>new Color(0, 255, 0)</code>.
|
||||||
*
|
*
|
||||||
* @param s
|
* @param s The string to evaluate.
|
||||||
* The string to evaluate.
|
|
||||||
* @return The color.
|
* @return The color.
|
||||||
*/
|
*/
|
||||||
private static Color stringToColor(String s) {
|
private static Color stringToColor(String s) {
|
||||||
@@ -517,9 +502,9 @@ public class Theme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the color represented by a string. The input is expected to
|
* Returns the color represented by a string. The input is expected to be a
|
||||||
* be a 6-digit hex string, optionally prefixed by a '$'. For example,
|
* 6-digit hex string, optionally prefixed by a '$'. For example, either of the
|
||||||
* either of the following:
|
* following:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* "$00ff00"
|
* "$00ff00"
|
||||||
@@ -528,11 +513,9 @@ public class Theme {
|
|||||||
*
|
*
|
||||||
* will return <code>new Color(0, 255, 0)</code>.
|
* will return <code>new Color(0, 255, 0)</code>.
|
||||||
*
|
*
|
||||||
* @param s
|
* @param s The string to evaluate.
|
||||||
* The string to evaluate.
|
* @param defaultVal The color to use if <code>s</code> is
|
||||||
* @param defaultVal
|
* "<code>default</code>".
|
||||||
* The color to use if <code>s</code> is
|
|
||||||
* "<code>default</code>".
|
|
||||||
* @return The color.
|
* @return The color.
|
||||||
*/
|
*/
|
||||||
private static Color stringToColor(String s, Color defaultVal) {
|
private static Color stringToColor(String s, Color defaultVal) {
|
||||||
|
|||||||
@@ -22,19 +22,18 @@ import javax.swing.text.Utilities;
|
|||||||
* <b>Note:</b> The instances of <code>Token</code> returned by
|
* <b>Note:</b> The instances of <code>Token</code> returned by
|
||||||
* {@link RSyntaxDocument}s are pooled and should always be treated as
|
* {@link RSyntaxDocument}s are pooled and should always be treated as
|
||||||
* immutable. They should not be cast to <code>TokenImpl</code> and modified.
|
* immutable. They should not be cast to <code>TokenImpl</code> and modified.
|
||||||
* Modifying tokens you did not create yourself can and will result in
|
* Modifying tokens you did not create yourself can and will result in rendering
|
||||||
* rendering issues and/or runtime exceptions. You have been warned!
|
* issues and/or runtime exceptions. You have been warned!
|
||||||
*
|
*
|
||||||
* @author Robert Futrell
|
* @author Robert Futrell
|
||||||
* @version 0.3
|
* @version 0.3
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "checkstyle:visibilitymodifier" })
|
|
||||||
public class TokenImpl implements Token {
|
public class TokenImpl implements Token {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text this token represents. This is implemented as a segment so we
|
* The text this token represents. This is implemented as a segment so we can
|
||||||
* can point directly to the text in the document without having to make a
|
* point directly to the text in the document without having to make a copy of
|
||||||
* copy of it.
|
* it.
|
||||||
*/
|
*/
|
||||||
public char[] text;
|
public char[] text;
|
||||||
public int textOffset;
|
public int textOffset;
|
||||||
@@ -61,9 +60,9 @@ public class TokenImpl implements Token {
|
|||||||
private int languageIndex;
|
private int languageIndex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a "null" token. The token itself is not null; rather, it
|
* Creates a "null" token. The token itself is not null; rather, it signifies
|
||||||
* signifies that it is the last token in a linked list of tokens and
|
* that it is the last token in a linked list of tokens and that it is not part
|
||||||
* that it is not part of a "multi-line token."
|
* of a "multi-line token."
|
||||||
*/
|
*/
|
||||||
public TokenImpl() {
|
public TokenImpl() {
|
||||||
this.text = null;
|
this.text = null;
|
||||||
@@ -78,19 +77,12 @@ public class TokenImpl implements Token {
|
|||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param line
|
* @param line The segment from which to get the token.
|
||||||
* The segment from which to get the token.
|
* @param beg The first character's position in <code>line</code>.
|
||||||
* @param beg
|
* @param end The last character's position in <code>line</code>.
|
||||||
* The first character's position in <code>line</code>.
|
* @param startOffset The offset into the document at which this token begins.
|
||||||
* @param end
|
* @param type A token type listed as "generic" above.
|
||||||
* The last character's position in <code>line</code>.
|
* @param languageIndex The language index for this token.
|
||||||
* @param startOffset
|
|
||||||
* The offset into the document at which this
|
|
||||||
* token begins.
|
|
||||||
* @param type
|
|
||||||
* A token type listed as "generic" above.
|
|
||||||
* @param languageIndex
|
|
||||||
* The language index for this token.
|
|
||||||
*/
|
*/
|
||||||
public TokenImpl(Segment line, int beg, int end, int startOffset, int type, int languageIndex) {
|
public TokenImpl(Segment line, int beg, int end, int startOffset, int type, int languageIndex) {
|
||||||
this(line.array, beg, end, startOffset, type, languageIndex);
|
this(line.array, beg, end, startOffset, type, languageIndex);
|
||||||
@@ -99,19 +91,12 @@ public class TokenImpl implements Token {
|
|||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param line
|
* @param line The segment from which to get the token.
|
||||||
* The segment from which to get the token.
|
* @param beg The first character's position in <code>line</code>.
|
||||||
* @param beg
|
* @param end The last character's position in <code>line</code>.
|
||||||
* The first character's position in <code>line</code>.
|
* @param startOffset The offset into the document at which this token begins.
|
||||||
* @param end
|
* @param type A token type listed as "generic" above.
|
||||||
* The last character's position in <code>line</code>.
|
* @param languageIndex The language index for this token.
|
||||||
* @param startOffset
|
|
||||||
* The offset into the document at which this
|
|
||||||
* token begins.
|
|
||||||
* @param type
|
|
||||||
* A token type listed as "generic" above.
|
|
||||||
* @param languageIndex
|
|
||||||
* The language index for this token.
|
|
||||||
*/
|
*/
|
||||||
public TokenImpl(char[] line, int beg, int end, int startOffset, int type, int languageIndex) {
|
public TokenImpl(char[] line, int beg, int end, int startOffset, int type, int languageIndex) {
|
||||||
this();
|
this();
|
||||||
@@ -122,8 +107,7 @@ public class TokenImpl implements Token {
|
|||||||
/**
|
/**
|
||||||
* Creates this token as a copy of the passed-in token.
|
* Creates this token as a copy of the passed-in token.
|
||||||
*
|
*
|
||||||
* @param t2
|
* @param t2 The token from which to make a copy.
|
||||||
* The token from which to make a copy.
|
|
||||||
*/
|
*/
|
||||||
public TokenImpl(Token t2) {
|
public TokenImpl(Token t2) {
|
||||||
this();
|
this();
|
||||||
@@ -136,7 +120,8 @@ public class TokenImpl implements Token {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StringBuilder appendHTMLRepresentation(StringBuilder sb, RSyntaxTextArea textArea, boolean fontFamily, boolean tabsToSpaces) {
|
public StringBuilder appendHTMLRepresentation(StringBuilder sb, RSyntaxTextArea textArea, boolean fontFamily,
|
||||||
|
boolean tabsToSpaces) {
|
||||||
SyntaxScheme colorScheme = textArea.getSyntaxScheme();
|
SyntaxScheme colorScheme = textArea.getSyntaxScheme();
|
||||||
Style scheme = colorScheme.getStyle(getType());
|
Style scheme = colorScheme.getStyle(getType());
|
||||||
Font font = textArea.getFontForTokenType(getType());// scheme.font;
|
Font font = textArea.getFontForTokenType(getType());// scheme.font;
|
||||||
@@ -179,16 +164,13 @@ public class TokenImpl implements Token {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends an HTML version of the lexeme of this token (i.e. no style
|
* Appends an HTML version of the lexeme of this token (i.e. no style HTML, but
|
||||||
* HTML, but replacing chars such as <code>\t</code>, <code><</code>
|
* replacing chars such as <code>\t</code>, <code><</code> and
|
||||||
* and <code>></code> with their escapes).
|
* <code>></code> with their escapes).
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area.
|
||||||
* The text area.
|
* @param sb The buffer to append to.
|
||||||
* @param sb
|
* @param tabsToSpaces Whether to convert tabs into spaces.
|
||||||
* The buffer to append to.
|
|
||||||
* @param tabsToSpaces
|
|
||||||
* Whether to convert tabs into spaces.
|
|
||||||
* @return The same buffer.
|
* @return The same buffer.
|
||||||
*/
|
*/
|
||||||
private StringBuilder appendHtmlLexeme(RSyntaxTextArea textArea, StringBuilder sb, boolean tabsToSpaces) {
|
private StringBuilder appendHtmlLexeme(RSyntaxTextArea textArea, StringBuilder sb, boolean tabsToSpaces) {
|
||||||
@@ -199,64 +181,64 @@ public class TokenImpl implements Token {
|
|||||||
while (i < textOffset + textCount) {
|
while (i < textOffset + textCount) {
|
||||||
char ch = text[i];
|
char ch = text[i];
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ' ':
|
case ' ':
|
||||||
sb.append(text, lastI, i - lastI);
|
sb.append(text, lastI, i - lastI);
|
||||||
lastI = i + 1;
|
lastI = i + 1;
|
||||||
sb.append(lastWasSpace ? " " : " ");
|
sb.append(lastWasSpace ? " " : " ");
|
||||||
lastWasSpace = true;
|
lastWasSpace = true;
|
||||||
break;
|
break;
|
||||||
case '\t':
|
case '\t':
|
||||||
sb.append(text, lastI, i - lastI);
|
sb.append(text, lastI, i - lastI);
|
||||||
lastI = i + 1;
|
lastI = i + 1;
|
||||||
if (tabsToSpaces && tabStr == null) {
|
if (tabsToSpaces && tabStr == null) {
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
for (int j = 0; j < textArea.getTabSize(); j++) {
|
for (int j = 0; j < textArea.getTabSize(); j++) {
|
||||||
stringBuilder.append(" ");
|
stringBuilder.append(" ");
|
||||||
}
|
|
||||||
tabStr = stringBuilder.toString();
|
|
||||||
}
|
}
|
||||||
sb.append(tabsToSpaces ? tabStr : "	");
|
tabStr = stringBuilder.toString();
|
||||||
lastWasSpace = false;
|
}
|
||||||
break;
|
sb.append(tabsToSpaces ? tabStr : "	");
|
||||||
case '&':
|
lastWasSpace = false;
|
||||||
sb.append(text, lastI, i - lastI);
|
break;
|
||||||
lastI = i + 1;
|
case '&':
|
||||||
sb.append("&");
|
sb.append(text, lastI, i - lastI);
|
||||||
lastWasSpace = false;
|
lastI = i + 1;
|
||||||
break;
|
sb.append("&");
|
||||||
case '<':
|
lastWasSpace = false;
|
||||||
sb.append(text, lastI, i - lastI);
|
break;
|
||||||
lastI = i + 1;
|
case '<':
|
||||||
sb.append("<");
|
sb.append(text, lastI, i - lastI);
|
||||||
lastWasSpace = false;
|
lastI = i + 1;
|
||||||
break;
|
sb.append("<");
|
||||||
case '>':
|
lastWasSpace = false;
|
||||||
sb.append(text, lastI, i - lastI);
|
break;
|
||||||
lastI = i + 1;
|
case '>':
|
||||||
sb.append(">");
|
sb.append(text, lastI, i - lastI);
|
||||||
lastWasSpace = false;
|
lastI = i + 1;
|
||||||
break;
|
sb.append(">");
|
||||||
case '\'':
|
lastWasSpace = false;
|
||||||
sb.append(text, lastI, i - lastI);
|
break;
|
||||||
lastI = i + 1;
|
case '\'':
|
||||||
sb.append("'");
|
sb.append(text, lastI, i - lastI);
|
||||||
lastWasSpace = false;
|
lastI = i + 1;
|
||||||
break;
|
sb.append("'");
|
||||||
case '"':
|
lastWasSpace = false;
|
||||||
sb.append(text, lastI, i - lastI);
|
break;
|
||||||
lastI = i + 1;
|
case '"':
|
||||||
sb.append(""");
|
sb.append(text, lastI, i - lastI);
|
||||||
lastWasSpace = false;
|
lastI = i + 1;
|
||||||
break;
|
sb.append(""");
|
||||||
case '/': // OWASP-recommended to escape even though unnecessary
|
lastWasSpace = false;
|
||||||
sb.append(text, lastI, i - lastI);
|
break;
|
||||||
lastI = i + 1;
|
case '/': // OWASP-recommended to escape even though unnecessary
|
||||||
sb.append("/");
|
sb.append(text, lastI, i - lastI);
|
||||||
lastWasSpace = false;
|
lastI = i + 1;
|
||||||
break;
|
sb.append("/");
|
||||||
default:
|
lastWasSpace = false;
|
||||||
lastWasSpace = false;
|
break;
|
||||||
break;
|
default:
|
||||||
|
lastWasSpace = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -277,11 +259,10 @@ public class TokenImpl implements Token {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes one token point to the same text segment, and have the same value
|
* Makes one token point to the same text segment, and have the same value as
|
||||||
* as another token.
|
* another token.
|
||||||
*
|
*
|
||||||
* @param t2
|
* @param t2 The token from which to copy.
|
||||||
* The token from which to copy.
|
|
||||||
*/
|
*/
|
||||||
public void copyFrom(Token t2) {
|
public void copyFrom(Token t2) {
|
||||||
text = t2.getTextArray();
|
text = t2.getTextArray();
|
||||||
@@ -322,8 +303,9 @@ public class TokenImpl implements Token {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Token t2 = (Token) obj;
|
Token t2 = (Token) obj;
|
||||||
return offset == t2.getOffset() && type == t2.getType() && languageIndex == t2.getLanguageIndex() && hyperlink == t2.isHyperlink()
|
return offset == t2.getOffset() && type == t2.getType() && languageIndex == t2.getLanguageIndex()
|
||||||
&& ((getLexeme() == null && t2.getLexeme() == null) || (getLexeme() != null && getLexeme().equals(t2.getLexeme())));
|
&& hyperlink == t2.isHyperlink() && ((getLexeme() == null && t2.getLexeme() == null)
|
||||||
|
|| (getLexeme() != null && getLexeme().equals(t2.getLexeme())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -332,11 +314,10 @@ public class TokenImpl implements Token {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a <code>String</code> of the form "#xxxxxx" good for use
|
* Returns a <code>String</code> of the form "#xxxxxx" good for use in HTML,
|
||||||
* in HTML, representing the given color.
|
* representing the given color.
|
||||||
*
|
*
|
||||||
* @param color
|
* @param color The color to get a string for.
|
||||||
* The color to get a string for.
|
|
||||||
* @return The HTML form of the color. If <code>color</code> is
|
* @return The HTML form of the color. If <code>color</code> is
|
||||||
* <code>null</code>, <code>#000000</code> is returned.
|
* <code>null</code>, <code>#000000</code> is returned.
|
||||||
*/
|
*/
|
||||||
@@ -376,16 +357,16 @@ public class TokenImpl implements Token {
|
|||||||
Token last = null;
|
Token last = null;
|
||||||
for (Token t = this; t != null && t.isPaintable(); t = t.getNextToken()) {
|
for (Token t = this; t != null && t.isPaintable(); t = t.getNextToken()) {
|
||||||
switch (t.getType()) {
|
switch (t.getType()) {
|
||||||
case COMMENT_DOCUMENTATION:
|
case COMMENT_DOCUMENTATION:
|
||||||
case COMMENT_EOL:
|
case COMMENT_EOL:
|
||||||
case COMMENT_MULTILINE:
|
case COMMENT_MULTILINE:
|
||||||
case COMMENT_KEYWORD:
|
case COMMENT_KEYWORD:
|
||||||
case COMMENT_MARKUP:
|
case COMMENT_MARKUP:
|
||||||
case WHITESPACE:
|
case WHITESPACE:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
last = t;
|
last = t;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return last;
|
return last;
|
||||||
@@ -683,23 +664,22 @@ public class TokenImpl implements Token {
|
|||||||
* Makes this token start at the specified offset into the document.
|
* Makes this token start at the specified offset into the document.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* <b>Note:</b> You should not modify <code>Token</code> instances you
|
* <b>Note:</b> You should not modify <code>Token</code> instances you did not
|
||||||
* did not create yourself (e.g., came from an
|
* create yourself (e.g., came from an <code>RSyntaxDocument</code>). If you do,
|
||||||
* <code>RSyntaxDocument</code>). If you do, rendering issues and/or
|
* rendering issues and/or runtime exceptions will likely occur. You have been
|
||||||
* runtime exceptions will likely occur. You have been warned!
|
* warned!
|
||||||
*
|
*
|
||||||
* @param pos
|
* @param pos The offset into the document this token should start at. Note that
|
||||||
* The offset into the document this token should start at.
|
* this token must already contain this position; if it doesn't, an
|
||||||
* Note that this token must already contain this position; if
|
* exception is thrown.
|
||||||
* it doesn't, an exception is thrown.
|
* @throws IllegalArgumentException If pos is not already contained by this
|
||||||
* @throws IllegalArgumentException
|
* token.
|
||||||
* If pos is not already contained by
|
|
||||||
* this token.
|
|
||||||
* @see #moveOffset(int)
|
* @see #moveOffset(int)
|
||||||
*/
|
*/
|
||||||
public void makeStartAt(int pos) {
|
public void makeStartAt(int pos) {
|
||||||
if (pos < getOffset() || pos >= (getOffset() + textCount)) {
|
if (pos < getOffset() || pos >= (getOffset() + textCount)) {
|
||||||
throw new IllegalArgumentException("pos " + pos + " is not in range " + getOffset() + "-" + (getOffset() + textCount - 1));
|
throw new IllegalArgumentException(
|
||||||
|
"pos " + pos + " is not in range " + getOffset() + "-" + (getOffset() + textCount - 1));
|
||||||
}
|
}
|
||||||
int shift = pos - getOffset();
|
int shift = pos - getOffset();
|
||||||
setOffset(pos);
|
setOffset(pos);
|
||||||
@@ -711,16 +691,14 @@ public class TokenImpl implements Token {
|
|||||||
* Moves the starting offset of this token.
|
* Moves the starting offset of this token.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* <b>Note:</b> You should not modify <code>Token</code> instances you
|
* <b>Note:</b> You should not modify <code>Token</code> instances you did not
|
||||||
* did not create yourself (e.g., came from an
|
* create yourself (e.g., came from an <code>RSyntaxDocument</code>). If you do,
|
||||||
* <code>RSyntaxDocument</code>). If you do, rendering issues and/or
|
* rendering issues and/or runtime exceptions will likely occur. You have been
|
||||||
* runtime exceptions will likely occur. You have been warned!
|
* warned!
|
||||||
*
|
*
|
||||||
* @param amt
|
* @param amt The amount to move the starting offset. This should be between
|
||||||
* The amount to move the starting offset. This should be
|
* <code>0</code> and <code>textCount</code>, inclusive.
|
||||||
* between <code>0</code> and <code>textCount</code>, inclusive.
|
* @throws IllegalArgumentException If <code>amt</code> is an invalid value.
|
||||||
* @throws IllegalArgumentException
|
|
||||||
* If <code>amt</code> is an invalid value.
|
|
||||||
* @see #makeStartAt(int)
|
* @see #makeStartAt(int)
|
||||||
*/
|
*/
|
||||||
public void moveOffset(int amt) {
|
public void moveOffset(int amt) {
|
||||||
@@ -733,19 +711,14 @@ public class TokenImpl implements Token {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of this token to a particular segment of a document.
|
* Sets the value of this token to a particular segment of a document. The "next
|
||||||
* The "next token" value is cleared.
|
* token" value is cleared.
|
||||||
*
|
*
|
||||||
* @param line
|
* @param line The segment from which to get the token.
|
||||||
* The segment from which to get the token.
|
* @param beg The first character's position in <code>line</code>.
|
||||||
* @param beg
|
* @param end The last character's position in <code>line</code>.
|
||||||
* The first character's position in <code>line</code>.
|
* @param offset The offset into the document at which this token begins.
|
||||||
* @param end
|
* @param type A token type listed as "generic" above.
|
||||||
* The last character's position in <code>line</code>.
|
|
||||||
* @param offset
|
|
||||||
* The offset into the document at which this token begins.
|
|
||||||
* @param type
|
|
||||||
* A token type listed as "generic" above.
|
|
||||||
*/
|
*/
|
||||||
public void set(final char[] line, final int beg, final int end, final int offset, final int type) {
|
public void set(final char[] line, final int beg, final int end, final int offset, final int type) {
|
||||||
this.text = line;
|
this.text = line;
|
||||||
@@ -759,8 +732,7 @@ public class TokenImpl implements Token {
|
|||||||
/**
|
/**
|
||||||
* Sets whether this token is a hyperlink.
|
* Sets whether this token is a hyperlink.
|
||||||
*
|
*
|
||||||
* @param hyperlink
|
* @param hyperlink Whether this token is a hyperlink.
|
||||||
* Whether this token is a hyperlink.
|
|
||||||
* @see #isHyperlink()
|
* @see #isHyperlink()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -769,17 +741,16 @@ public class TokenImpl implements Token {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the language index for this token. If this value is positive, it
|
* Sets the language index for this token. If this value is positive, it denotes
|
||||||
* denotes a specific "secondary" language this token represents (such as
|
* a specific "secondary" language this token represents (such as JavaScript
|
||||||
* JavaScript code or CSS embedded in an HTML file). If this value is
|
* code or CSS embedded in an HTML file). If this value is <code>0</code>, this
|
||||||
* <code>0</code>, this token is in the "main" language being edited.
|
* token is in the "main" language being edited. Negative values are invalid and
|
||||||
* Negative values are invalid and treated as <code>0</code>.
|
* treated as <code>0</code>.
|
||||||
*
|
*
|
||||||
* @param languageIndex
|
* @param languageIndex The new language index. A value of <code>0</code>
|
||||||
* The new language index. A value of
|
* denotes the "main" language, any positive value denotes
|
||||||
* <code>0</code> denotes the "main" language, any positive value
|
* a specific secondary language. Negative values will be
|
||||||
* denotes a specific secondary language. Negative values will
|
* treated as <code>0</code>.
|
||||||
* be treated as <code>0</code>.
|
|
||||||
* @see #getLanguageIndex()
|
* @see #getLanguageIndex()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -788,11 +759,9 @@ public class TokenImpl implements Token {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the "next token" pointer of this token to point to the specified
|
* Sets the "next token" pointer of this token to point to the specified token.
|
||||||
* token.
|
|
||||||
*
|
*
|
||||||
* @param nextToken
|
* @param nextToken The new next token.
|
||||||
* The new next token.
|
|
||||||
* @see #getNextToken()
|
* @see #getNextToken()
|
||||||
*/
|
*/
|
||||||
public void setNextToken(Token nextToken) {
|
public void setNextToken(Token nextToken) {
|
||||||
@@ -802,8 +771,7 @@ public class TokenImpl implements Token {
|
|||||||
/**
|
/**
|
||||||
* Sets the offset into the document at which this token resides.
|
* Sets the offset into the document at which this token resides.
|
||||||
*
|
*
|
||||||
* @param offset
|
* @param offset The new offset into the document.
|
||||||
* The new offset into the document.
|
|
||||||
* @see #getOffset()
|
* @see #getOffset()
|
||||||
*/
|
*/
|
||||||
public void setOffset(int offset) {
|
public void setOffset(int offset) {
|
||||||
@@ -843,16 +811,18 @@ public class TokenImpl implements Token {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns this token as a <code>String</code>, which is useful for
|
* Returns this token as a <code>String</code>, which is useful for debugging.
|
||||||
* debugging.
|
|
||||||
*
|
*
|
||||||
* @return A string describing this token.
|
* @return A string describing this token.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[Token: " + (getType() == Token.NULL ? "<null token>"
|
return "[Token: "
|
||||||
: "text: '" + (text == null ? "<null>" : getLexeme() + "'; " + "offset: " + getOffset() + "; type: " + getType() + "; "
|
+ (getType() == Token.NULL ? "<null token>"
|
||||||
+ "isPaintable: " + isPaintable() + "; nextToken==null: " + (nextToken == null)))
|
: "text: '" + (text == null ? "<null>"
|
||||||
|
: getLexeme() + "'; " + "offset: " + getOffset() + "; type: " + getType() + "; "
|
||||||
|
+ "isPaintable: " + isPaintable() + "; nextToken==null: "
|
||||||
|
+ (nextToken == null)))
|
||||||
+ "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,11 +10,12 @@ import javax.swing.text.TabExpander;
|
|||||||
*/
|
*/
|
||||||
public final class TokenUtils {
|
public final class TokenUtils {
|
||||||
|
|
||||||
private TokenUtils() {}
|
private TokenUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifies the passed-in token list to start at the specified offset.
|
* Modifies the passed-in token list to start at the specified offset. For
|
||||||
* For example, if the token list covered positions 20-60 in the document
|
* example, if the token list covered positions 20-60 in the document
|
||||||
* (inclusive) like so:
|
* (inclusive) like so:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
@@ -22,50 +23,46 @@ public final class TokenUtils {
|
|||||||
* 20 30 31 40 41 50 51 60
|
* 20 30 31 40 41 50 51 60
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* and you used this method to make the token list start at position 44,
|
* and you used this method to make the token list start at position 44, then
|
||||||
* then the token list would be modified to be the following:
|
* the token list would be modified to be the following:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* [part-of-old-token3] -> [token4]
|
* [part-of-old-token3] -> [token4]
|
||||||
* 44 50 51 60
|
* 44 50 51 60
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Tokens that come before the specified position are forever lost, and
|
* Tokens that come before the specified position are forever lost, and the
|
||||||
* the token containing that position is made to begin at that position if
|
* token containing that position is made to begin at that position if
|
||||||
* necessary. All token types remain the same as they were originally.
|
* necessary. All token types remain the same as they were originally.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* This method can be useful if you are only interested in part of a token
|
* This method can be useful if you are only interested in part of a token list
|
||||||
* list (i.e., the line it represents), but you don't want to modify the
|
* (i.e., the line it represents), but you don't want to modify the token list
|
||||||
* token list yourself.
|
* yourself.
|
||||||
*
|
*
|
||||||
* @param tokenList
|
* @param tokenList The list to make start at the specified position. This
|
||||||
* The list to make start at the specified position.
|
* parameter is modified.
|
||||||
* This parameter is modified.
|
* @param pos The position at which the new token list is to start. If
|
||||||
* @param pos
|
* this position is not in the passed-in token list, returned
|
||||||
* The position at which the new token list is to start. If
|
* token list will either be <code>null</code> or the
|
||||||
* this position is not in the passed-in token list,
|
* unpaintable token(s) at the end of the passed-in token list.
|
||||||
* returned token list will either be <code>null</code> or the
|
* @param e How to expand tabs.
|
||||||
* unpaintable token(s) at the end of the passed-in token list.
|
* @param textArea The text area from which the token list came.
|
||||||
* @param e
|
* @param x0 The initial x-pixel position of the old token list.
|
||||||
* How to expand tabs.
|
|
||||||
* @param textArea
|
|
||||||
* The text area from which the token list came.
|
|
||||||
* @param x0
|
|
||||||
* The initial x-pixel position of the old token list.
|
|
||||||
* @return Information about the "sub" token list. This will be
|
* @return Information about the "sub" token list. This will be
|
||||||
* <code>null</code> if <code>pos</code> was not a valid offset
|
* <code>null</code> if <code>pos</code> was not a valid offset into the
|
||||||
* into the token list.
|
* token list.
|
||||||
* @see #getSubTokenList(Token, int, TabExpander, RSyntaxTextArea, float,
|
* @see #getSubTokenList(Token, int, TabExpander, RSyntaxTextArea, float,
|
||||||
* TokenImpl)
|
* TokenImpl)
|
||||||
*/
|
*/
|
||||||
public static TokenSubList getSubTokenList(Token tokenList, int pos, TabExpander e, final RSyntaxTextArea textArea, float x0) {
|
public static TokenSubList getSubTokenList(Token tokenList, int pos, TabExpander e, final RSyntaxTextArea textArea,
|
||||||
|
float x0) {
|
||||||
return getSubTokenList(tokenList, pos, e, textArea, x0, null);
|
return getSubTokenList(tokenList, pos, e, textArea, x0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifies the passed-in token list to start at the specified offset.
|
* Modifies the passed-in token list to start at the specified offset. For
|
||||||
* For example, if the token list covered positions 20-60 in the document
|
* example, if the token list covered positions 20-60 in the document
|
||||||
* (inclusive) like so:
|
* (inclusive) like so:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
@@ -73,48 +70,42 @@ public final class TokenUtils {
|
|||||||
* 20 30 31 40 41 50 51 60
|
* 20 30 31 40 41 50 51 60
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* and you used this method to make the token list start at position 44,
|
* and you used this method to make the token list start at position 44, then
|
||||||
* then the token list would be modified to be the following:
|
* the token list would be modified to be the following:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* [part-of-old-token3] -> [token4]
|
* [part-of-old-token3] -> [token4]
|
||||||
* 44 50 51 60
|
* 44 50 51 60
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Tokens that come before the specified position are forever lost, and
|
* Tokens that come before the specified position are forever lost, and the
|
||||||
* the token containing that position is made to begin at that position if
|
* token containing that position is made to begin at that position if
|
||||||
* necessary. All token types remain the same as they were originally.
|
* necessary. All token types remain the same as they were originally.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* This method can be useful if you are only interested in part of a token
|
* This method can be useful if you are only interested in part of a token list
|
||||||
* list (i.e., the line it represents), but you don't want to modify the
|
* (i.e., the line it represents), but you don't want to modify the token list
|
||||||
* token list yourself.
|
* yourself.
|
||||||
*
|
*
|
||||||
* @param tokenList
|
* @param tokenList The list to make start at the specified position. This
|
||||||
* The list to make start at the specified position.
|
* parameter is modified.
|
||||||
* This parameter is modified.
|
* @param pos The position at which the new token list is to start. If
|
||||||
* @param pos
|
* this position is not in the passed-in token list, returned
|
||||||
* The position at which the new token list is to start. If
|
* token list will either be <code>null</code> or the
|
||||||
* this position is not in the passed-in token list,
|
* unpaintable token(s) at the end of the passed-in token list.
|
||||||
* returned token list will either be <code>null</code> or the
|
* @param e How to expand tabs.
|
||||||
* unpaintable token(s) at the end of the passed-in token list.
|
* @param textArea The text area from which the token list came.
|
||||||
* @param e
|
* @param x0 The initial x-pixel position of the old token list.
|
||||||
* How to expand tabs.
|
* @param tempToken A temporary token to use when creating the token list
|
||||||
* @param textArea
|
* result. This may be <code>null</code> but callers can pass
|
||||||
* The text area from which the token list came.
|
* in a "buffer" token for performance if desired.
|
||||||
* @param x0
|
|
||||||
* The initial x-pixel position of the old token list.
|
|
||||||
* @param tempToken
|
|
||||||
* A temporary token to use when creating the token list
|
|
||||||
* result. This may be <code>null</code> but callers can pass in
|
|
||||||
* a "buffer" token for performance if desired.
|
|
||||||
* @return Information about the "sub" token list. This will be
|
* @return Information about the "sub" token list. This will be
|
||||||
* <code>null</code> if <code>pos</code> was not a valid offset
|
* <code>null</code> if <code>pos</code> was not a valid offset into the
|
||||||
* into the token list.
|
* token list.
|
||||||
* @see #getSubTokenList(Token, int, TabExpander, RSyntaxTextArea, float)
|
* @see #getSubTokenList(Token, int, TabExpander, RSyntaxTextArea, float)
|
||||||
*/
|
*/
|
||||||
public static TokenSubList getSubTokenList(Token tokenList, int pos, TabExpander e, final RSyntaxTextArea textArea, float x0,
|
public static TokenSubList getSubTokenList(Token tokenList, int pos, TabExpander e, final RSyntaxTextArea textArea,
|
||||||
TokenImpl tempToken) {
|
float x0, TokenImpl tempToken) {
|
||||||
if (tempToken == null) {
|
if (tempToken == null) {
|
||||||
tempToken = new TokenImpl();
|
tempToken = new TokenImpl();
|
||||||
}
|
}
|
||||||
@@ -146,7 +137,6 @@ public final class TokenUtils {
|
|||||||
/**
|
/**
|
||||||
* A sub-list of tokens.
|
* A sub-list of tokens.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "checkstyle:visibilitymodifier" })
|
|
||||||
public static class TokenSubList {
|
public static class TokenSubList {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,8 +144,8 @@ public final class TokenUtils {
|
|||||||
*/
|
*/
|
||||||
public Token tokenList;
|
public Token tokenList;
|
||||||
/**
|
/**
|
||||||
* The width, in pixels, of the part of the token list "removed from
|
* The width, in pixels, of the part of the token list "removed from the front."
|
||||||
* the front." This way, you know the x-offset of the "new" token list.
|
* This way, you know the x-offset of the "new" token list.
|
||||||
*/
|
*/
|
||||||
public float x;
|
public float x;
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import javax.swing.event.MouseInputAdapter;
|
|||||||
* @author Robert Futrell
|
* @author Robert Futrell
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "checkstyle:magicnumber" })
|
|
||||||
class SizeGrip extends JPanel {
|
class SizeGrip extends JPanel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,11 +49,10 @@ class SizeGrip extends JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overridden to ensure that the cursor for this component is appropriate
|
* Overridden to ensure that the cursor for this component is appropriate for
|
||||||
* for the orientation.
|
* the orientation.
|
||||||
*
|
*
|
||||||
* @param o
|
* @param o The new orientation.
|
||||||
* The new orientation.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void applyComponentOrientation(ComponentOrientation o) {
|
public void applyComponentOrientation(ComponentOrientation o) {
|
||||||
@@ -97,8 +95,7 @@ class SizeGrip extends JPanel {
|
|||||||
/**
|
/**
|
||||||
* Paints this panel.
|
* Paints this panel.
|
||||||
*
|
*
|
||||||
* @param g
|
* @param g The graphics context.
|
||||||
* The graphics context.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent(Graphics g) {
|
protected void paintComponent(Graphics g) {
|
||||||
@@ -151,8 +148,7 @@ class SizeGrip extends JPanel {
|
|||||||
* Ensures that the cursor for this component is appropriate for the
|
* Ensures that the cursor for this component is appropriate for the
|
||||||
* orientation.
|
* orientation.
|
||||||
*
|
*
|
||||||
* @param ltr
|
* @param ltr Whether the current component orientation is LTR.
|
||||||
* Whether the current component orientation is LTR.
|
|
||||||
*/
|
*/
|
||||||
protected void possiblyFixCursor(boolean ltr) {
|
protected void possiblyFixCursor(boolean ltr) {
|
||||||
int cursor = Cursor.NE_RESIZE_CURSOR;
|
int cursor = Cursor.NE_RESIZE_CURSOR;
|
||||||
@@ -185,12 +181,10 @@ class SizeGrip extends JPanel {
|
|||||||
private class MouseHandler extends MouseInputAdapter {
|
private class MouseHandler extends MouseInputAdapter {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: We use SwingUtilities.convertPointToScreen() instead of just
|
* NOTE: We use SwingUtilities.convertPointToScreen() instead of just using the
|
||||||
* using
|
* locations relative to the corner component because the latter proved buggy -
|
||||||
* the locations relative to the corner component because the latter
|
* stretch the window too wide and some kind of arithmetic error started
|
||||||
* proved
|
* happening somewhere - our window would grow way too large.
|
||||||
* buggy - stretch the window too wide and some kind of arithmetic error
|
|
||||||
* started happening somewhere - our window would grow way too large.
|
|
||||||
*/
|
*/
|
||||||
private Point origPos;
|
private Point origPos;
|
||||||
|
|
||||||
|
|||||||
@@ -24,19 +24,17 @@ import javax.swing.text.DefaultEditorKit;
|
|||||||
* <li>INSERT key toggles between insert and overwrite modes.
|
* <li>INSERT key toggles between insert and overwrite modes.
|
||||||
* <li>Ctrl+DELETE key deletes all text between the caret and the end of the
|
* <li>Ctrl+DELETE key deletes all text between the caret and the end of the
|
||||||
* current line.
|
* current line.
|
||||||
* <li>Ctrl+Shift+Up and Ctrl+Shift+Down move the current line up and
|
* <li>Ctrl+Shift+Up and Ctrl+Shift+Down move the current line up and down,
|
||||||
* down, respectively.
|
* respectively.
|
||||||
* <li>Ctrl+J joins lines.
|
* <li>Ctrl+J joins lines.
|
||||||
* <li>Ctrl+Z is undo and Ctrl+Y is redo.
|
* <li>Ctrl+Z is undo and Ctrl+Y is redo.
|
||||||
* <li>Ctrl+Up and Ctrl+Down shift the visible area of the text area up and
|
* <li>Ctrl+Up and Ctrl+Down shift the visible area of the text area up and down
|
||||||
* down one line, respectively.
|
* one line, respectively.
|
||||||
* <li>F2 and Shift+F2 moves to the next and previous bookmarks,
|
* <li>F2 and Shift+F2 moves to the next and previous bookmarks, respectively.
|
||||||
* respectively.
|
|
||||||
* <li>Ctrl+F2 toggles whether a bookmark is on the current line.
|
* <li>Ctrl+F2 toggles whether a bookmark is on the current line.
|
||||||
* <li>etc.
|
* <li>etc.
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "checkstyle:linelength" })
|
|
||||||
public class RTADefaultInputMap extends InputMap {
|
public class RTADefaultInputMap extends InputMap {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,12 +48,14 @@ public class RTADefaultInputMap extends InputMap {
|
|||||||
int shift = InputEvent.SHIFT_MASK;
|
int shift = InputEvent.SHIFT_MASK;
|
||||||
boolean isOSX = RTextArea.isOSX();
|
boolean isOSX = RTextArea.isOSX();
|
||||||
int moveByWordMod = isOSX ? alt : defaultModifier;
|
int moveByWordMod = isOSX ? alt : defaultModifier;
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, 0), isOSX ? DefaultEditorKit.beginAction : DefaultEditorKit.beginLineAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, 0),
|
||||||
|
isOSX ? DefaultEditorKit.beginAction : DefaultEditorKit.beginLineAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, shift),
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, shift),
|
||||||
isOSX ? DefaultEditorKit.selectionBeginAction : DefaultEditorKit.selectionBeginLineAction);
|
isOSX ? DefaultEditorKit.selectionBeginAction : DefaultEditorKit.selectionBeginLineAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, defaultModifier), DefaultEditorKit.beginAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, defaultModifier), DefaultEditorKit.beginAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, defaultModifier | shift), DefaultEditorKit.selectionBeginAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, defaultModifier | shift), DefaultEditorKit.selectionBeginAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_END, 0), isOSX ? DefaultEditorKit.endAction : DefaultEditorKit.endLineAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_END, 0),
|
||||||
|
isOSX ? DefaultEditorKit.endAction : DefaultEditorKit.endLineAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_END, shift),
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_END, shift),
|
||||||
isOSX ? DefaultEditorKit.selectionEndAction : DefaultEditorKit.selectionEndLineAction);
|
isOSX ? DefaultEditorKit.selectionEndAction : DefaultEditorKit.selectionEndLineAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_END, defaultModifier), DefaultEditorKit.endAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_END, defaultModifier), DefaultEditorKit.endAction);
|
||||||
@@ -63,7 +63,8 @@ public class RTADefaultInputMap extends InputMap {
|
|||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), DefaultEditorKit.backwardAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), DefaultEditorKit.backwardAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, shift), DefaultEditorKit.selectionBackwardAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, shift), DefaultEditorKit.selectionBackwardAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, moveByWordMod), DefaultEditorKit.previousWordAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, moveByWordMod), DefaultEditorKit.previousWordAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, moveByWordMod | shift), DefaultEditorKit.selectionPreviousWordAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, moveByWordMod | shift),
|
||||||
|
DefaultEditorKit.selectionPreviousWordAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), DefaultEditorKit.downAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), DefaultEditorKit.downAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, shift), DefaultEditorKit.selectionDownAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, shift), DefaultEditorKit.selectionDownAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, defaultModifier), RTextAreaEditorKit.rtaScrollDownAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, defaultModifier), RTextAreaEditorKit.rtaScrollDownAction);
|
||||||
@@ -78,10 +79,12 @@ public class RTADefaultInputMap extends InputMap {
|
|||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, alt), RTextAreaEditorKit.rtaLineUpAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, alt), RTextAreaEditorKit.rtaLineUpAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0), DefaultEditorKit.pageUpAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0), DefaultEditorKit.pageUpAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, shift), RTextAreaEditorKit.rtaSelectionPageUpAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, shift), RTextAreaEditorKit.rtaSelectionPageUpAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, defaultModifier | shift), RTextAreaEditorKit.rtaSelectionPageLeftAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, defaultModifier | shift),
|
||||||
|
RTextAreaEditorKit.rtaSelectionPageLeftAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0), DefaultEditorKit.pageDownAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0), DefaultEditorKit.pageDownAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, shift), RTextAreaEditorKit.rtaSelectionPageDownAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, shift), RTextAreaEditorKit.rtaSelectionPageDownAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, defaultModifier | shift), RTextAreaEditorKit.rtaSelectionPageRightAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, defaultModifier | shift),
|
||||||
|
RTextAreaEditorKit.rtaSelectionPageRightAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_CUT, 0), DefaultEditorKit.cutAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_CUT, 0), DefaultEditorKit.cutAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_COPY, 0), DefaultEditorKit.copyAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_COPY, 0), DefaultEditorKit.copyAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_PASTE, 0), DefaultEditorKit.pasteAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_PASTE, 0), DefaultEditorKit.pasteAction);
|
||||||
@@ -99,7 +102,8 @@ public class RTADefaultInputMap extends InputMap {
|
|||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_D, defaultModifier), RTextAreaEditorKit.rtaDeleteLineAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_D, defaultModifier), RTextAreaEditorKit.rtaDeleteLineAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_J, defaultModifier), RTextAreaEditorKit.rtaJoinLinesAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_J, defaultModifier), RTextAreaEditorKit.rtaJoinLinesAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, shift), DefaultEditorKit.deletePrevCharAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, shift), DefaultEditorKit.deletePrevCharAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, defaultModifier), RTextAreaEditorKit.rtaDeletePrevWordAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, defaultModifier),
|
||||||
|
RTextAreaEditorKit.rtaDeletePrevWordAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), DefaultEditorKit.insertTabAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), DefaultEditorKit.insertTabAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), DefaultEditorKit.insertBreakAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), DefaultEditorKit.insertBreakAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, shift), DefaultEditorKit.insertBreakAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, shift), DefaultEditorKit.insertBreakAction);
|
||||||
@@ -114,8 +118,10 @@ public class RTADefaultInputMap extends InputMap {
|
|||||||
if (isOSX) {
|
if (isOSX) {
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, defaultModifier), DefaultEditorKit.beginLineAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, defaultModifier), DefaultEditorKit.beginLineAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, defaultModifier), DefaultEditorKit.endLineAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, defaultModifier), DefaultEditorKit.endLineAction);
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, defaultModifier | shift), DefaultEditorKit.selectionBeginLineAction);
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, defaultModifier | shift),
|
||||||
put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, defaultModifier | shift), DefaultEditorKit.selectionEndLineAction);
|
DefaultEditorKit.selectionBeginLineAction);
|
||||||
|
put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, defaultModifier | shift),
|
||||||
|
DefaultEditorKit.selectionEndLineAction);
|
||||||
}
|
}
|
||||||
/* NOTE: Currently, macros aren't part of the default input map for */
|
/* NOTE: Currently, macros aren't part of the default input map for */
|
||||||
/* RTextArea, as they display their own popup windows, etc. which */
|
/* RTextArea, as they display their own popup windows, etc. which */
|
||||||
@@ -134,8 +140,8 @@ public class RTADefaultInputMap extends InputMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the default modifier key for a system. For example, on Windows
|
* Returns the default modifier key for a system. For example, on Windows this
|
||||||
* this would be the CTRL key (<code>InputEvent.CTRL_MASK</code>).
|
* would be the CTRL key (<code>InputEvent.CTRL_MASK</code>).
|
||||||
*
|
*
|
||||||
* @return The default modifier key.
|
* @return The default modifier key.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import javax.swing.text.Position;
|
|||||||
* @author Robert Futrell
|
* @author Robert Futrell
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class RTATextTransferHandler extends TransferHandler {
|
public class RTATextTransferHandler extends TransferHandler {
|
||||||
|
|
||||||
private JTextComponent exportComp;
|
private JTextComponent exportComp;
|
||||||
@@ -47,23 +46,20 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
private boolean withinSameComponent;
|
private boolean withinSameComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to find a flavor that can be used to import a Transferable to a
|
* Try to find a flavor that can be used to import a Transferable to a specified
|
||||||
* specified text component.
|
* text component. The set of usable flavors are tried in the following order:
|
||||||
* The set of usable flavors are tried in the following order:
|
|
||||||
* <ol>
|
* <ol>
|
||||||
* <li>First, an attempt is made to find a flavor matching the content
|
* <li>First, an attempt is made to find a flavor matching the content tyep of
|
||||||
* tyep of the EditorKit for the component.
|
* the EditorKit for the component.
|
||||||
* <li>Second, an attempt to find a text/plain flavor is made.
|
* <li>Second, an attempt to find a text/plain flavor is made.
|
||||||
* <li>Third, an attempt to find a flavor representing a String
|
* <li>Third, an attempt to find a flavor representing a String reference in the
|
||||||
* reference in the same VM is made.
|
* same VM is made.
|
||||||
* <li>Lastly, DataFlavor.stringFlavor is searched for.
|
* <li>Lastly, DataFlavor.stringFlavor is searched for.
|
||||||
* </ol>
|
* </ol>
|
||||||
*
|
*
|
||||||
* @param flavors
|
* @param flavors The flavors to check if c will accept them.
|
||||||
* The flavors to check if c will accept them.
|
* @param c The text component to see whether it will accept any of the
|
||||||
* @param c
|
* specified data flavors as input.
|
||||||
* The text component to see whether it will accept any of the
|
|
||||||
* specified data flavors as input.
|
|
||||||
*/
|
*/
|
||||||
protected DataFlavor getImportFlavor(DataFlavor[] flavors, JTextComponent c) {
|
protected DataFlavor getImportFlavor(DataFlavor[] flavors, JTextComponent c) {
|
||||||
DataFlavor refFlavor = null;
|
DataFlavor refFlavor = null;
|
||||||
@@ -105,38 +101,38 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
last = 0;
|
last = 0;
|
||||||
for (int counter = 0; counter < nch; counter++) {
|
for (int counter = 0; counter < nch; counter++) {
|
||||||
switch (buff[counter]) {
|
switch (buff[counter]) {
|
||||||
case '\r':
|
case '\r':
|
||||||
if (lastWasCR) {
|
if (lastWasCR) {
|
||||||
if (counter == 0) {
|
if (counter == 0) {
|
||||||
sbuff.append('\n');
|
sbuff.append('\n');
|
||||||
} else {
|
|
||||||
buff[counter - 1] = '\n';
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
lastWasCR = true;
|
buff[counter - 1] = '\n';
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
case '\n':
|
lastWasCR = true;
|
||||||
if (lastWasCR) {
|
}
|
||||||
if (counter > (last + 1)) {
|
break;
|
||||||
sbuff.append(buff, last, counter - last - 1);
|
case '\n':
|
||||||
}
|
if (lastWasCR) {
|
||||||
// else nothing to do, can skip \r, next write will
|
if (counter > (last + 1)) {
|
||||||
// write \n
|
sbuff.append(buff, last, counter - last - 1);
|
||||||
lastWasCR = false;
|
|
||||||
last = counter;
|
|
||||||
}
|
}
|
||||||
break;
|
// else nothing to do, can skip \r, next write will
|
||||||
default:
|
// write \n
|
||||||
if (lastWasCR) {
|
lastWasCR = false;
|
||||||
if (counter == 0) {
|
last = counter;
|
||||||
sbuff.append('\n');
|
}
|
||||||
} else {
|
break;
|
||||||
buff[counter - 1] = '\n';
|
default:
|
||||||
}
|
if (lastWasCR) {
|
||||||
lastWasCR = false;
|
if (counter == 0) {
|
||||||
|
sbuff.append('\n');
|
||||||
|
} else {
|
||||||
|
buff[counter - 1] = '\n';
|
||||||
}
|
}
|
||||||
break;
|
lastWasCR = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
} // End fo switch (buff[counter]).
|
} // End fo switch (buff[counter]).
|
||||||
} // End of for (int counter = 0; counter < nch; counter++).
|
} // End of for (int counter = 0; counter < nch; counter++).
|
||||||
if (last < nch) {
|
if (last < nch) {
|
||||||
@@ -159,14 +155,13 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the type of transfer actions supported by the source. Some
|
* This is the type of transfer actions supported by the source. Some models are
|
||||||
* models are not mutable, so a transfer operation of COPY only should
|
* not mutable, so a transfer operation of COPY only should be advertised in
|
||||||
* be advertised in that case.
|
* that case.
|
||||||
*
|
*
|
||||||
* @param c
|
* @param c The component holding the data to be transfered. This argument is
|
||||||
* The component holding the data to be transfered. This
|
* provided to enable sharing of TransferHandlers by multiple
|
||||||
* argument is provided to enable sharing of TransferHandlers by
|
* components.
|
||||||
* multiple components.
|
|
||||||
* @return If the text component is editable, COPY_OR_MOVE is returned,
|
* @return If the text component is editable, COPY_OR_MOVE is returned,
|
||||||
* otherwise just COPY is allowed.
|
* otherwise just COPY is allowed.
|
||||||
*/
|
*/
|
||||||
@@ -182,10 +177,9 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
/**
|
/**
|
||||||
* Create a Transferable to use as the source for a data transfer.
|
* Create a Transferable to use as the source for a data transfer.
|
||||||
*
|
*
|
||||||
* @param comp
|
* @param comp The component holding the data to be transfered. This argument is
|
||||||
* The component holding the data to be transfered. This
|
* provided to enable sharing of TransferHandlers by multiple
|
||||||
* argument is provided to enable sharing of TransferHandlers by
|
* components.
|
||||||
* multiple components.
|
|
||||||
* @return The representation of the data to be transfered.
|
* @return The representation of the data to be transfered.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -199,16 +193,13 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called after data has been exported. This method should
|
* This method is called after data has been exported. This method should remove
|
||||||
* remove the data that was transfered if the action was MOVE.
|
* the data that was transfered if the action was MOVE.
|
||||||
*
|
*
|
||||||
* @param source
|
* @param source The component that was the source of the data.
|
||||||
* The component that was the source of the data.
|
* @param data The data that was transferred or possibly null if the action is
|
||||||
* @param data
|
* <code>NONE</code>.
|
||||||
* The data that was transferred or possibly null
|
* @param action The actual action that was performed.
|
||||||
* if the action is <code>NONE</code>.
|
|
||||||
* @param action
|
|
||||||
* The actual action that was performed.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void exportDone(JComponent source, Transferable data, int action) {
|
protected void exportDone(JComponent source, Transferable data, int action) {
|
||||||
@@ -229,16 +220,13 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method causes a transfer to a component from a clipboard or a
|
* This method causes a transfer to a component from a clipboard or a DND drop
|
||||||
* DND drop operation. The Transferable represents the data to be
|
* operation. The Transferable represents the data to be imported into the
|
||||||
* imported into the component.
|
* component.
|
||||||
*
|
*
|
||||||
* @param comp
|
* @param comp The component to receive the transfer. This argument is provided
|
||||||
* The component to receive the transfer. This
|
* to enable sharing of TransferHandlers by multiple components.
|
||||||
* argument is provided to enable sharing of TransferHandlers by
|
* @param t The data to import
|
||||||
* multiple components.
|
|
||||||
* @param t
|
|
||||||
* The data to import
|
|
||||||
* @return <code>true</code> iff the data was inserted into the component.
|
* @return <code>true</code> iff the data was inserted into the component.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -274,15 +262,13 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method indicates if a component would accept an import of the
|
* This method indicates if a component would accept an import of the given set
|
||||||
* given set of data flavors prior to actually attempting to import it.
|
* of data flavors prior to actually attempting to import it.
|
||||||
*
|
*
|
||||||
* @param comp
|
* @param comp The component to receive the transfer. This argument is
|
||||||
* The component to receive the transfer. This argument is
|
* provided to enable sharing of TransferHandlers by multiple
|
||||||
* provided to enable sharing of TransferHandlers by multiple
|
* components.
|
||||||
* components.
|
* @param flavors The data formats available.
|
||||||
* @param flavors
|
|
||||||
* The data formats available.
|
|
||||||
* @return <code>true</code> iff the data can be inserted.
|
* @return <code>true</code> iff the data can be inserted.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -313,7 +299,8 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
p0 = doc.createPosition(start);
|
p0 = doc.createPosition(start);
|
||||||
p1 = doc.createPosition(end);
|
p1 = doc.createPosition(end);
|
||||||
plainData = c.getSelectedText();
|
plainData = c.getSelectedText();
|
||||||
} catch (BadLocationException ble) {}
|
} catch (BadLocationException ble) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -324,20 +311,15 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an object which represents the data to be transferred. The
|
* Returns an object which represents the data to be transferred. The class of
|
||||||
* class
|
* the object returned is defined by the representation class of the flavor.
|
||||||
* of the object returned is defined by the representation class of the
|
|
||||||
* flavor.
|
|
||||||
*
|
*
|
||||||
* @param flavor
|
* @param flavor the requested flavor for the data
|
||||||
* the requested flavor for the data
|
|
||||||
* @see DataFlavor#getRepresentationClass
|
* @see DataFlavor#getRepresentationClass
|
||||||
* @exception IOException
|
* @exception IOException if the data is no longer available in
|
||||||
* if the data is no longer available
|
* the requested flavor.
|
||||||
* in the requested flavor.
|
* @exception UnsupportedFlavorException if the requested data flavor is not
|
||||||
* @exception UnsupportedFlavorException
|
* supported.
|
||||||
* if the requested data flavor is
|
|
||||||
* not supported.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
|
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
|
||||||
@@ -361,15 +343,11 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of DataFlavor objects indicating the flavors the
|
* Returns an array of DataFlavor objects indicating the flavors the data can be
|
||||||
* data
|
* provided in. The array should be ordered according to preference for
|
||||||
* can be provided in. The array should be ordered according to
|
* providing the data (from most richly descriptive to least descriptive).
|
||||||
* preference
|
|
||||||
* for providing the data (from most richly descriptive to least
|
|
||||||
* descriptive).
|
|
||||||
*
|
*
|
||||||
* @return an array of data flavors in which this data can be
|
* @return an array of data flavors in which this data can be transferred
|
||||||
* transferred
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public DataFlavor[] getTransferDataFlavors() {
|
public DataFlavor[] getTransferDataFlavors() {
|
||||||
@@ -391,13 +369,11 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not the specified data flavor is supported for
|
* Returns whether or not the specified data flavor is supported for this
|
||||||
* this object.
|
* object.
|
||||||
*
|
*
|
||||||
* @param flavor
|
* @param flavor the requested flavor for the data
|
||||||
* the requested flavor for the data
|
* @return boolean indicating whether or not the data flavor is supported
|
||||||
* @return boolean indicating whether or not the data flavor is
|
|
||||||
* supported
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||||
@@ -411,14 +387,11 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not the specified data flavor is an plain flavor
|
* Returns whether or not the specified data flavor is an plain flavor that is
|
||||||
* that
|
* supported.
|
||||||
* is supported.
|
|
||||||
*
|
*
|
||||||
* @param flavor
|
* @param flavor the requested flavor for the data
|
||||||
* the requested flavor for the data
|
* @return boolean indicating whether or not the data flavor is supported
|
||||||
* @return boolean indicating whether or not the data flavor is
|
|
||||||
* supported
|
|
||||||
*/
|
*/
|
||||||
protected boolean isPlainFlavor(DataFlavor flavor) {
|
protected boolean isPlainFlavor(DataFlavor flavor) {
|
||||||
DataFlavor[] flavors = plainFlavors;
|
DataFlavor[] flavors = plainFlavors;
|
||||||
@@ -431,22 +404,19 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should the plain text flavors be offered? If so, the method
|
* Should the plain text flavors be offered? If so, the method getPlainData
|
||||||
* getPlainData should be implemented to provide something reasonable.
|
* should be implemented to provide something reasonable.
|
||||||
*/
|
*/
|
||||||
protected boolean isPlainSupported() {
|
protected boolean isPlainSupported() {
|
||||||
return plainData != null;
|
return plainData != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not the specified data flavor is a String flavor
|
* Returns whether or not the specified data flavor is a String flavor that is
|
||||||
* that
|
* supported.
|
||||||
* is supported.
|
|
||||||
*
|
*
|
||||||
* @param flavor
|
* @param flavor the requested flavor for the data
|
||||||
* the requested flavor for the data
|
* @return boolean indicating whether or not the data flavor is supported
|
||||||
* @return boolean indicating whether or not the data flavor is
|
|
||||||
* supported
|
|
||||||
*/
|
*/
|
||||||
protected boolean isStringFlavor(DataFlavor flavor) {
|
protected boolean isStringFlavor(DataFlavor flavor) {
|
||||||
DataFlavor[] flavors = stringFlavors;
|
DataFlavor[] flavors = stringFlavors;
|
||||||
@@ -463,7 +433,8 @@ public class RTATextTransferHandler extends TransferHandler {
|
|||||||
try {
|
try {
|
||||||
Document doc = c.getDocument();
|
Document doc = c.getDocument();
|
||||||
doc.remove(p0.getOffset(), p1.getOffset() - p0.getOffset());
|
doc.remove(p0.getOffset(), p1.getOffset() - p0.getOffset());
|
||||||
} catch (BadLocationException e) {}
|
} catch (BadLocationException e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
|
|||||||
// FIXME: Replace Utilities calls with custom versions (in RSyntaxUtilities) to
|
// FIXME: Replace Utilities calls with custom versions (in RSyntaxUtilities) to
|
||||||
// cut down on all of the modelToViews, as each call causes
|
// cut down on all of the modelToViews, as each call causes
|
||||||
// a getTokenList => expensive!
|
// a getTokenList => expensive!
|
||||||
@SuppressWarnings({ "checkstyle:constantname" })
|
|
||||||
public class RTextAreaEditorKit extends DefaultEditorKit {
|
public class RTextAreaEditorKit extends DefaultEditorKit {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,14 +68,13 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
*/
|
*/
|
||||||
public static final String rtaDeletePrevWordAction = "RTA.DeletePrevWordAction";
|
public static final String rtaDeletePrevWordAction = "RTA.DeletePrevWordAction";
|
||||||
/**
|
/**
|
||||||
* The name of the action taken to delete the remainder of the line (from
|
* The name of the action taken to delete the remainder of the line (from the
|
||||||
* the caret position to the end of the line).
|
* caret position to the end of the line).
|
||||||
*/
|
*/
|
||||||
public static final String rtaDeleteRestOfLineAction = "RTA.DeleteRestOfLineAction";
|
public static final String rtaDeleteRestOfLineAction = "RTA.DeleteRestOfLineAction";
|
||||||
/**
|
/**
|
||||||
* The name of the action that completes the word at the caret position
|
* The name of the action that completes the word at the caret position with the
|
||||||
* with the last word in the document that starts with the text up to the
|
* last word in the document that starts with the text up to the caret.
|
||||||
* caret.
|
|
||||||
*/
|
*/
|
||||||
public static final String rtaDumbCompleteWordAction = "RTA.DumbCompleteWordAction";
|
public static final String rtaDumbCompleteWordAction = "RTA.DumbCompleteWordAction";
|
||||||
/**
|
/**
|
||||||
@@ -136,13 +134,13 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
*/
|
*/
|
||||||
public static final String rtaRedoAction = "RTA.RedoAction";
|
public static final String rtaRedoAction = "RTA.RedoAction";
|
||||||
/**
|
/**
|
||||||
* The name of the action to scroll the text area down one line
|
* The name of the action to scroll the text area down one line without changing
|
||||||
* without changing the caret's position.
|
* the caret's position.
|
||||||
*/
|
*/
|
||||||
public static final String rtaScrollDownAction = "RTA.ScrollDownAction";
|
public static final String rtaScrollDownAction = "RTA.ScrollDownAction";
|
||||||
/**
|
/**
|
||||||
* The name of the action to scroll the text area up one line
|
* The name of the action to scroll the text area up one line without changing
|
||||||
* without changing the caret's position.
|
* the caret's position.
|
||||||
*/
|
*/
|
||||||
public static final String rtaScrollUpAction = "RTA.ScrollUpAction";
|
public static final String rtaScrollUpAction = "RTA.ScrollUpAction";
|
||||||
/**
|
/**
|
||||||
@@ -166,13 +164,13 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
*/
|
*/
|
||||||
public static final String rtaTimeDateAction = "RTA.TimeDateAction";
|
public static final String rtaTimeDateAction = "RTA.TimeDateAction";
|
||||||
/**
|
/**
|
||||||
* Toggles whether the current line has a bookmark, if this text area
|
* Toggles whether the current line has a bookmark, if this text area is in an
|
||||||
* is in an {@link RTextScrollPane}.
|
* {@link RTextScrollPane}.
|
||||||
*/
|
*/
|
||||||
public static final String rtaToggleBookmarkAction = "RTA.ToggleBookmarkAction";
|
public static final String rtaToggleBookmarkAction = "RTA.ToggleBookmarkAction";
|
||||||
/**
|
/**
|
||||||
* The name of the action taken when the user hits the Insert key (thus
|
* The name of the action taken when the user hits the Insert key (thus toggling
|
||||||
* toggling between insert and overwrite modes).
|
* between insert and overwrite modes).
|
||||||
*/
|
*/
|
||||||
public static final String rtaToggleTextModeAction = "RTA.ToggleTextModeAction";
|
public static final String rtaToggleTextModeAction = "RTA.ToggleTextModeAction";
|
||||||
/**
|
/**
|
||||||
@@ -180,8 +178,7 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
*/
|
*/
|
||||||
public static final String rtaUndoAction = "RTA.UndoAction";
|
public static final String rtaUndoAction = "RTA.UndoAction";
|
||||||
/**
|
/**
|
||||||
* The name of the action for unselecting any selected text in the text
|
* The name of the action for unselecting any selected text in the text area.
|
||||||
* area.
|
|
||||||
*/
|
*/
|
||||||
public static final String rtaUnselectAction = "RTA.UnselectAction";
|
public static final String rtaUnselectAction = "RTA.UnselectAction";
|
||||||
/**
|
/**
|
||||||
@@ -189,21 +186,24 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
*/
|
*/
|
||||||
public static final String rtaUpperSelectionCaseAction = "RTA.UpperCaseAction";
|
public static final String rtaUpperSelectionCaseAction = "RTA.UpperCaseAction";
|
||||||
/**
|
/**
|
||||||
* The actions that <code>RTextAreaEditorKit</code> adds to those of
|
* The actions that <code>RTextAreaEditorKit</code> adds to those of the default
|
||||||
* the default editor kit.
|
* editor kit.
|
||||||
*/
|
*/
|
||||||
private static final RecordableTextAction[] defaultActions = { new BeginAction(beginAction, false),
|
private static final RecordableTextAction[] defaultActions = { new BeginAction(beginAction, false),
|
||||||
new BeginAction(selectionBeginAction, true), new BeginLineAction(beginLineAction, false),
|
new BeginAction(selectionBeginAction, true), new BeginLineAction(beginLineAction, false),
|
||||||
new BeginLineAction(selectionBeginLineAction, true), new BeginRecordingMacroAction(),
|
new BeginLineAction(selectionBeginLineAction, true), new BeginRecordingMacroAction(),
|
||||||
new BeginWordAction(beginWordAction, false), new BeginWordAction(selectionBeginWordAction, true), new ClipboardHistoryAction(),
|
new BeginWordAction(beginWordAction, false), new BeginWordAction(selectionBeginWordAction, true),
|
||||||
new CopyAction(), new CutAction(), new DefaultKeyTypedAction(), new DeleteLineAction(), new DeleteNextCharAction(),
|
new ClipboardHistoryAction(), new CopyAction(), new CutAction(), new DefaultKeyTypedAction(),
|
||||||
new DeletePrevCharAction(), new DeletePrevWordAction(), new DeleteRestOfLineAction(), new DumbCompleteWordAction(),
|
new DeleteLineAction(), new DeleteNextCharAction(), new DeletePrevCharAction(), new DeletePrevWordAction(),
|
||||||
new EndAction(endAction, false), new EndAction(selectionEndAction, true), new EndLineAction(endLineAction, false),
|
new DeleteRestOfLineAction(), new DumbCompleteWordAction(), new EndAction(endAction, false),
|
||||||
new EndLineAction(selectionEndLineAction, true), new EndRecordingMacroAction(), new EndWordAction(endWordAction, false),
|
new EndAction(selectionEndAction, true), new EndLineAction(endLineAction, false),
|
||||||
new EndWordAction(endWordAction, true), new InsertBreakAction(), new InsertContentAction(), new InsertTabAction(),
|
new EndLineAction(selectionEndLineAction, true), new EndRecordingMacroAction(),
|
||||||
new InvertSelectionCaseAction(), new JoinLinesAction(), new LowerSelectionCaseAction(), new LineMoveAction(rtaLineUpAction, -1),
|
new EndWordAction(endWordAction, false), new EndWordAction(endWordAction, true), new InsertBreakAction(),
|
||||||
|
new InsertContentAction(), new InsertTabAction(), new InvertSelectionCaseAction(), new JoinLinesAction(),
|
||||||
|
new LowerSelectionCaseAction(), new LineMoveAction(rtaLineUpAction, -1),
|
||||||
new LineMoveAction(rtaLineDownAction, 1), new NextBookmarkAction(rtaNextBookmarkAction, true),
|
new LineMoveAction(rtaLineDownAction, 1), new NextBookmarkAction(rtaNextBookmarkAction, true),
|
||||||
new NextBookmarkAction(rtaPrevBookmarkAction, false), new NextVisualPositionAction(forwardAction, false, SwingConstants.EAST),
|
new NextBookmarkAction(rtaPrevBookmarkAction, false),
|
||||||
|
new NextVisualPositionAction(forwardAction, false, SwingConstants.EAST),
|
||||||
new NextVisualPositionAction(backwardAction, false, SwingConstants.WEST),
|
new NextVisualPositionAction(backwardAction, false, SwingConstants.WEST),
|
||||||
new NextVisualPositionAction(selectionForwardAction, true, SwingConstants.EAST),
|
new NextVisualPositionAction(selectionForwardAction, true, SwingConstants.EAST),
|
||||||
new NextVisualPositionAction(selectionBackwardAction, true, SwingConstants.WEST),
|
new NextVisualPositionAction(selectionBackwardAction, true, SwingConstants.WEST),
|
||||||
@@ -213,13 +213,16 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
new NextVisualPositionAction(selectionDownAction, true, SwingConstants.SOUTH),
|
new NextVisualPositionAction(selectionDownAction, true, SwingConstants.SOUTH),
|
||||||
new NextOccurrenceAction(rtaNextOccurrenceAction), new PreviousOccurrenceAction(rtaPrevOccurrenceAction),
|
new NextOccurrenceAction(rtaNextOccurrenceAction), new PreviousOccurrenceAction(rtaPrevOccurrenceAction),
|
||||||
new NextWordAction(nextWordAction, false), new NextWordAction(selectionNextWordAction, true),
|
new NextWordAction(nextWordAction, false), new NextWordAction(selectionNextWordAction, true),
|
||||||
new PageAction(rtaSelectionPageLeftAction, true, true), new PageAction(rtaSelectionPageRightAction, false, true),
|
new PageAction(rtaSelectionPageLeftAction, true, true),
|
||||||
new PasteAction(), new PlaybackLastMacroAction(), new PreviousWordAction(previousWordAction, false),
|
new PageAction(rtaSelectionPageRightAction, false, true), new PasteAction(), new PlaybackLastMacroAction(),
|
||||||
new PreviousWordAction(selectionPreviousWordAction, true), new RedoAction(), new ScrollAction(rtaScrollUpAction, -1),
|
new PreviousWordAction(previousWordAction, false),
|
||||||
new ScrollAction(rtaScrollDownAction, 1), new SelectAllAction(), new SelectLineAction(), new SelectWordAction(),
|
new PreviousWordAction(selectionPreviousWordAction, true), new RedoAction(),
|
||||||
new SetReadOnlyAction(), new SetWritableAction(), new ToggleBookmarkAction(), new ToggleTextModeAction(), new UndoAction(),
|
new ScrollAction(rtaScrollUpAction, -1), new ScrollAction(rtaScrollDownAction, 1), new SelectAllAction(),
|
||||||
new UnselectAction(), new UpperSelectionCaseAction(), new VerticalPageAction(pageUpAction, -1, false),
|
new SelectLineAction(), new SelectWordAction(), new SetReadOnlyAction(), new SetWritableAction(),
|
||||||
new VerticalPageAction(pageDownAction, 1, false), new VerticalPageAction(rtaSelectionPageUpAction, -1, true),
|
new ToggleBookmarkAction(), new ToggleTextModeAction(), new UndoAction(), new UnselectAction(),
|
||||||
|
new UpperSelectionCaseAction(), new VerticalPageAction(pageUpAction, -1, false),
|
||||||
|
new VerticalPageAction(pageDownAction, 1, false),
|
||||||
|
new VerticalPageAction(rtaSelectionPageUpAction, -1, true),
|
||||||
new VerticalPageAction(rtaSelectionPageDownAction, 1, true) };
|
new VerticalPageAction(rtaSelectionPageDownAction, 1, true) };
|
||||||
/**
|
/**
|
||||||
* The amount of characters read at a time when reading a file.
|
* The amount of characters read at a time when reading a file.
|
||||||
@@ -236,8 +239,7 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
/**
|
/**
|
||||||
* Creates an icon row header to use in the gutter for a text area.
|
* Creates an icon row header to use in the gutter for a text area.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area.
|
||||||
* The text area.
|
|
||||||
* @return The icon row header.
|
* @return The icon row header.
|
||||||
*/
|
*/
|
||||||
public IconRowHeader createIconRowHeader(RTextArea textArea) {
|
public IconRowHeader createIconRowHeader(RTextArea textArea) {
|
||||||
@@ -247,8 +249,7 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
/**
|
/**
|
||||||
* Creates a line number list to use in the gutter for a text area.
|
* Creates a line number list to use in the gutter for a text area.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area.
|
||||||
* The text area.
|
|
||||||
* @return The line number list.
|
* @return The line number list.
|
||||||
*/
|
*/
|
||||||
public LineNumberList createLineNumberList(RTextArea textArea) {
|
public LineNumberList createLineNumberList(RTextArea textArea) {
|
||||||
@@ -256,9 +257,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the set of commands that can be used
|
* Fetches the set of commands that can be used on a text component that is
|
||||||
* on a text component that is using a model and
|
* using a model and view produced by this kit.
|
||||||
* view produced by this kit.
|
|
||||||
*
|
*
|
||||||
* @return the command list
|
* @return the command list
|
||||||
*/
|
*/
|
||||||
@@ -268,22 +268,16 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts content from the given stream, which will be
|
* Inserts content from the given stream, which will be treated as plain text.
|
||||||
* treated as plain text. This method is overridden merely
|
* This method is overridden merely so we can increase the number of characters
|
||||||
* so we can increase the number of characters read at a time.
|
* read at a time.
|
||||||
*
|
*
|
||||||
* @param in
|
* @param in The stream to read from
|
||||||
* The stream to read from
|
* @param doc The destination for the insertion.
|
||||||
* @param doc
|
* @param pos The location in the document to place the content >= 0.
|
||||||
* The destination for the insertion.
|
* @exception IOException on any I/O error
|
||||||
* @param pos
|
* @exception BadLocationException if pos represents an invalid location within
|
||||||
* The location in the document to place the
|
* the document.
|
||||||
* content >= 0.
|
|
||||||
* @exception IOException
|
|
||||||
* on any I/O error
|
|
||||||
* @exception BadLocationException
|
|
||||||
* if pos represents an invalid
|
|
||||||
* location within the document.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void read(Reader in, Document doc, int pos) throws IOException, BadLocationException {
|
public void read(Reader in, Document doc, int pos) throws IOException, BadLocationException {
|
||||||
@@ -303,44 +297,44 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
last = 0;
|
last = 0;
|
||||||
for (int counter = 0; counter < nch; counter++) {
|
for (int counter = 0; counter < nch; counter++) {
|
||||||
switch (buff[counter]) {
|
switch (buff[counter]) {
|
||||||
case '\r':
|
case '\r':
|
||||||
if (lastWasCR) {
|
if (lastWasCR) {
|
||||||
isCR = true;
|
isCR = true;
|
||||||
if (counter == 0) {
|
if (counter == 0) {
|
||||||
doc.insertString(pos, "\n", null);
|
doc.insertString(pos, "\n", null);
|
||||||
pos++;
|
pos++;
|
||||||
} else {
|
|
||||||
buff[counter - 1] = '\n';
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
lastWasCR = true;
|
buff[counter - 1] = '\n';
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
case '\n':
|
lastWasCR = true;
|
||||||
if (lastWasCR) {
|
}
|
||||||
if (counter > (last + 1)) {
|
break;
|
||||||
doc.insertString(pos, new String(buff, last, counter - last - 1), null);
|
case '\n':
|
||||||
pos += (counter - last - 1);
|
if (lastWasCR) {
|
||||||
}
|
if (counter > (last + 1)) {
|
||||||
// else nothing to do, can skip \r, next write will
|
doc.insertString(pos, new String(buff, last, counter - last - 1), null);
|
||||||
// write \n
|
pos += (counter - last - 1);
|
||||||
lastWasCR = false;
|
|
||||||
last = counter;
|
|
||||||
isCRLF = true;
|
|
||||||
}
|
}
|
||||||
break;
|
// else nothing to do, can skip \r, next write will
|
||||||
default:
|
// write \n
|
||||||
if (lastWasCR) {
|
lastWasCR = false;
|
||||||
isCR = true;
|
last = counter;
|
||||||
if (counter == 0) {
|
isCRLF = true;
|
||||||
doc.insertString(pos, "\n", null);
|
}
|
||||||
pos++;
|
break;
|
||||||
} else {
|
default:
|
||||||
buff[counter - 1] = '\n';
|
if (lastWasCR) {
|
||||||
}
|
isCR = true;
|
||||||
lastWasCR = false;
|
if (counter == 0) {
|
||||||
|
doc.insertString(pos, "\n", null);
|
||||||
|
pos++;
|
||||||
|
} else {
|
||||||
|
buff[counter - 1] = '\n';
|
||||||
}
|
}
|
||||||
break;
|
lastWasCR = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
} // End of switch (buff[counter]).
|
} // End of switch (buff[counter]).
|
||||||
} // End of for (int counter = 0; counter < nch; counter++).
|
} // End of for (int counter = 0; counter < nch; counter++).
|
||||||
if (last < nch) {
|
if (last < nch) {
|
||||||
@@ -418,8 +412,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the position of the caret between the beginning of the line,
|
* Toggles the position of the caret between the beginning of the line, and the
|
||||||
* and the first non-whitespace character on the line.
|
* first non-whitespace character on the line.
|
||||||
*/
|
*/
|
||||||
public static class BeginLineAction extends RecordableTextAction {
|
public static class BeginLineAction extends RecordableTextAction {
|
||||||
|
|
||||||
@@ -571,8 +565,7 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action for displaying a popup with a list of recently pasted text
|
* Action for displaying a popup with a list of recently pasted text snippets.
|
||||||
* snippets.
|
|
||||||
*/
|
*/
|
||||||
public static class ClipboardHistoryAction extends RecordableTextAction {
|
public static class ClipboardHistoryAction extends RecordableTextAction {
|
||||||
|
|
||||||
@@ -772,8 +765,7 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the character of content that follows the current caret
|
* Deletes the character of content that follows the current caret position.
|
||||||
* position.
|
|
||||||
*/
|
*/
|
||||||
public static class DeleteNextCharAction extends RecordableTextAction {
|
public static class DeleteNextCharAction extends RecordableTextAction {
|
||||||
|
|
||||||
@@ -810,7 +802,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
doc.remove(dot, delChars);
|
doc.remove(dot, delChars);
|
||||||
beep = false;
|
beep = false;
|
||||||
}
|
}
|
||||||
} catch (BadLocationException bl) {}
|
} catch (BadLocationException bl) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (beep) {
|
if (beep) {
|
||||||
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
|
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
|
||||||
@@ -827,8 +820,7 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the character of content that precedes the current caret
|
* Deletes the character of content that precedes the current caret position.
|
||||||
* position.
|
|
||||||
*/
|
*/
|
||||||
public static class DeletePrevCharAction extends RecordableTextAction {
|
public static class DeletePrevCharAction extends RecordableTextAction {
|
||||||
|
|
||||||
@@ -861,7 +853,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
doc.remove(dot - delChars, delChars);
|
doc.remove(dot - delChars, delChars);
|
||||||
beep = false;
|
beep = false;
|
||||||
}
|
}
|
||||||
} catch (BadLocationException bl) {}
|
} catch (BadLocationException bl) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (beep) {
|
if (beep) {
|
||||||
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
|
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
|
||||||
@@ -906,8 +899,7 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the starting offset to delete. Exists so subclasses can
|
* Returns the starting offset to delete. Exists so subclasses can override.
|
||||||
* override.
|
|
||||||
*/
|
*/
|
||||||
protected int getPreviousWordStart(RTextArea textArea, int end) throws BadLocationException {
|
protected int getPreviousWordStart(RTextArea textArea, int end) throws BadLocationException {
|
||||||
return Utilities.getPreviousWord(textArea, end);
|
return Utilities.getPreviousWord(textArea, end);
|
||||||
@@ -951,10 +943,10 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the most recent word in the document that matches the "word" up
|
* Finds the most recent word in the document that matches the "word" up to the
|
||||||
* to the current caret position, and auto-completes the rest. Repeatedly
|
* current caret position, and auto-completes the rest. Repeatedly calling this
|
||||||
* calling this action at the same location in the document goes one
|
* action at the same location in the document goes one match back each time it
|
||||||
* match back each time it is called.
|
* is called.
|
||||||
*/
|
*/
|
||||||
public static class DumbCompleteWordAction extends RecordableTextAction {
|
public static class DumbCompleteWordAction extends RecordableTextAction {
|
||||||
|
|
||||||
@@ -1038,15 +1030,13 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>Utilities.getWordStart()</code> treats spans of whitespace and
|
* <code>Utilities.getWordStart()</code> treats spans of whitespace and single
|
||||||
* single non-letter chars as "words." This method is used to filter
|
* non-letter chars as "words." This method is used to filter that kind of thing
|
||||||
* that kind of thing out - non-words should not be suggested by this
|
* out - non-words should not be suggested by this action.
|
||||||
* action.
|
|
||||||
*
|
*
|
||||||
* @param prefix
|
* @param prefix The prefix characters before the caret.
|
||||||
* The prefix characters before the caret.
|
* @return Whether the prefix could be part of a "word" in the context of the
|
||||||
* @return Whether the prefix could be part of a "word" in the context
|
* text area's current content.
|
||||||
* of the text area's current content.
|
|
||||||
*/
|
*/
|
||||||
protected boolean isAcceptablePrefix(String prefix) {
|
protected boolean isAcceptablePrefix(String prefix) {
|
||||||
return prefix.length() > 0 && Character.isLetter(prefix.charAt(prefix.length() - 1));
|
return prefix.length() > 0 && Character.isLetter(prefix.charAt(prefix.length() - 1));
|
||||||
@@ -1269,8 +1259,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Overridden for Sun bug 4515750. Sun fixed this in a more complicated
|
* Overridden for Sun bug 4515750. Sun fixed this in a more complicated way, but
|
||||||
* way, but I'm not sure why. See BasicTextUI#getActionMap() and
|
* I'm not sure why. See BasicTextUI#getActionMap() and
|
||||||
* BasicTextUI.TextActionWrapper.
|
* BasicTextUI.TextActionWrapper.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -1310,8 +1300,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Places a tab character into the document. If there is a selection, it
|
* Places a tab character into the document. If there is a selection, it is
|
||||||
* is removed before the tab is added.
|
* removed before the tab is added.
|
||||||
*/
|
*/
|
||||||
public static class InsertTabAction extends RecordableTextAction {
|
public static class InsertTabAction extends RecordableTextAction {
|
||||||
|
|
||||||
@@ -1681,8 +1671,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action to move the selection and/or caret. Constructor indicates
|
* Action to move the selection and/or caret. Constructor indicates direction to
|
||||||
* direction to use.
|
* use.
|
||||||
*/
|
*/
|
||||||
public static class NextVisualPositionAction extends RecordableTextAction {
|
public static class NextVisualPositionAction extends RecordableTextAction {
|
||||||
|
|
||||||
@@ -1700,28 +1690,27 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
Caret caret = textArea.getCaret();
|
Caret caret = textArea.getCaret();
|
||||||
int dot = caret.getDot();
|
int dot = caret.getDot();
|
||||||
/*
|
/*
|
||||||
* Move to the beginning/end of selection on a "non-shifted"
|
* Move to the beginning/end of selection on a "non-shifted" left- or
|
||||||
* left- or right-keypress. We shouldn't have to worry about
|
* right-keypress. We shouldn't have to worry about navigation filters as, if
|
||||||
* navigation filters as, if one is being used, it let us get
|
* one is being used, it let us get to that position before.
|
||||||
* to that position before.
|
|
||||||
*/
|
*/
|
||||||
if (!select) {
|
if (!select) {
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case SwingConstants.EAST:
|
case SwingConstants.EAST:
|
||||||
int mark = caret.getMark();
|
int mark = caret.getMark();
|
||||||
if (dot != mark) {
|
if (dot != mark) {
|
||||||
caret.setDot(Math.max(dot, mark));
|
caret.setDot(Math.max(dot, mark));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SwingConstants.WEST:
|
case SwingConstants.WEST:
|
||||||
mark = caret.getMark();
|
mark = caret.getMark();
|
||||||
if (dot != mark) {
|
if (dot != mark) {
|
||||||
caret.setDot(Math.min(dot, mark));
|
caret.setDot(Math.min(dot, mark));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Position.Bias[] bias = new Position.Bias[1];
|
Position.Bias[] bias = new Position.Bias[1];
|
||||||
@@ -1735,7 +1724,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
dot = filter.getNextVisualPositionFrom(textArea, dot, Position.Bias.Forward, direction, bias);
|
dot = filter.getNextVisualPositionFrom(textArea, dot, Position.Bias.Forward, direction, bias);
|
||||||
} else {
|
} else {
|
||||||
dot = textArea.getUI().getNextVisualPositionFrom(textArea, dot, Position.Bias.Forward, direction, bias);
|
dot = textArea.getUI().getNextVisualPositionFrom(textArea, dot, Position.Bias.Forward, direction,
|
||||||
|
bias);
|
||||||
}
|
}
|
||||||
if (select) {
|
if (select) {
|
||||||
caret.moveDot(dot);
|
caret.moveDot(dot);
|
||||||
@@ -1836,7 +1826,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
if (left) {
|
if (left) {
|
||||||
selectedIndex = textArea.viewToModel(new Point(visible.x, visible.y));
|
selectedIndex = textArea.viewToModel(new Point(visible.x, visible.y));
|
||||||
} else {
|
} else {
|
||||||
selectedIndex = textArea.viewToModel(new Point(visible.x + visible.width - 1, visible.y + visible.height - 1));
|
selectedIndex = textArea
|
||||||
|
.viewToModel(new Point(visible.x + visible.width - 1, visible.y + visible.height - 1));
|
||||||
}
|
}
|
||||||
Document doc = textArea.getDocument();
|
Document doc = textArea.getDocument();
|
||||||
if ((selectedIndex != 0) && (selectedIndex > (doc.getLength() - 1))) {
|
if ((selectedIndex != 0) && (selectedIndex > (doc.getLength() - 1))) {
|
||||||
@@ -2026,8 +2017,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scrolls the text area one line up or down, without changing
|
* Scrolls the text area one line up or down, without changing the caret
|
||||||
* the caret position.
|
* position.
|
||||||
*/
|
*/
|
||||||
public static class ScrollAction extends RecordableTextAction {
|
public static class ScrollAction extends RecordableTextAction {
|
||||||
|
|
||||||
@@ -2357,8 +2348,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scrolls up/down vertically. The select version of this action extends
|
* Scrolls up/down vertically. The select version of this action extends the
|
||||||
* the selection, instead of simply moving the caret.
|
* selection, instead of simply moving the caret.
|
||||||
*/
|
*/
|
||||||
public static class VerticalPageAction extends RecordableTextAction {
|
public static class VerticalPageAction extends RecordableTextAction {
|
||||||
|
|
||||||
@@ -2392,7 +2383,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
if (visible.contains(dotBounds.x, dotBounds.y)) {
|
if (visible.contains(dotBounds.x, dotBounds.y)) {
|
||||||
// Dot is currently visible, base the new
|
// Dot is currently visible, base the new
|
||||||
// location off the old, or
|
// location off the old, or
|
||||||
newIndex = textArea.viewToModel(new Point(x, constrainY(textArea, dotBounds.y + yOffset, 0, 0)));
|
newIndex = textArea
|
||||||
|
.viewToModel(new Point(x, constrainY(textArea, dotBounds.y + yOffset, 0, 0)));
|
||||||
} else {
|
} else {
|
||||||
// Dot isn't visible, choose the top or the bottom
|
// Dot isn't visible, choose the top or the bottom
|
||||||
// for the new location.
|
// for the new location.
|
||||||
@@ -2414,7 +2406,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
textArea.setCaretPosition(newIndex);
|
textArea.setCaretPosition(newIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (BadLocationException ble) {}
|
} catch (BadLocationException ble) {
|
||||||
|
}
|
||||||
} // End of if (selectedIndex!=-1).
|
} // End of if (selectedIndex!=-1).
|
||||||
else {
|
else {
|
||||||
yOffset = direction * scrollAmount;
|
yOffset = direction * scrollAmount;
|
||||||
@@ -2463,7 +2456,8 @@ public class RTextAreaEditorKit extends DefaultEditorKit {
|
|||||||
visible.y = y;
|
visible.y = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (BadLocationException ble) {}
|
} catch (BadLocationException ble) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ import javax.swing.text.View;
|
|||||||
import org.fife.ui.rsyntaxtextarea.DocumentRange;
|
import org.fife.ui.rsyntaxtextarea.DocumentRange;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The highlighter implementation used by {@link RTextArea}s. It knows to
|
* The highlighter implementation used by {@link RTextArea}s. It knows to always
|
||||||
* always paint "mark all" highlights below selection highlights.
|
* paint "mark all" highlights below selection highlights.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* Most of this code is copied from javax.swing.text.DefaultHighlighter;
|
* Most of this code is copied from javax.swing.text.DefaultHighlighter;
|
||||||
@@ -43,8 +43,7 @@ public class RTextAreaHighlighter extends BasicHighlighter {
|
|||||||
*/
|
*/
|
||||||
protected RTextArea textArea;
|
protected RTextArea textArea;
|
||||||
/**
|
/**
|
||||||
* The "mark all" highlights (to be painted separately from other
|
* The "mark all" highlights (to be painted separately from other highlights).
|
||||||
* highlights).
|
|
||||||
*/
|
*/
|
||||||
private List<HighlightInfo> markAllHighlights;
|
private List<HighlightInfo> markAllHighlights;
|
||||||
|
|
||||||
@@ -106,8 +105,7 @@ public class RTextAreaHighlighter extends BasicHighlighter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of "mark all" highlights currently shown in the
|
* Returns the number of "mark all" highlights currently shown in the editor.
|
||||||
* editor.
|
|
||||||
*
|
*
|
||||||
* @return The "mark all" highlight count.
|
* @return The "mark all" highlight count.
|
||||||
*/
|
*/
|
||||||
@@ -116,8 +114,8 @@ public class RTextAreaHighlighter extends BasicHighlighter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of "mark all" highlights in the text area. If there are
|
* Returns a list of "mark all" highlights in the text area. If there are no
|
||||||
* no such highlights, this will be an empty list.
|
* such highlights, this will be an empty list.
|
||||||
*
|
*
|
||||||
* @return The list of "mark all" highlight ranges.
|
* @return The list of "mark all" highlight ranges.
|
||||||
*/
|
*/
|
||||||
@@ -142,31 +140,25 @@ public class RTextAreaHighlighter extends BasicHighlighter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When leaf Views (such as LabelView) are rendering they should
|
* When leaf Views (such as LabelView) are rendering they should call into this
|
||||||
* call into this method. If a highlight is in the given region it will
|
* method. If a highlight is in the given region it will be drawn immediately.
|
||||||
* be drawn immediately.
|
|
||||||
*
|
*
|
||||||
* @param g
|
* @param g Graphics used to draw
|
||||||
* Graphics used to draw
|
* @param lineStart starting offset of view
|
||||||
* @param lineStart
|
* @param lineEnd ending offset of view
|
||||||
* starting offset of view
|
* @param viewBounds Bounds of View
|
||||||
* @param lineEnd
|
* @param editor JTextComponent
|
||||||
* ending offset of view
|
* @param view View instance being rendered
|
||||||
* @param viewBounds
|
|
||||||
* Bounds of View
|
|
||||||
* @param editor
|
|
||||||
* JTextComponent
|
|
||||||
* @param view
|
|
||||||
* View instance being rendered
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void paintLayeredHighlights(Graphics g, int lineStart, int lineEnd, Shape viewBounds, JTextComponent editor, View view) {
|
public void paintLayeredHighlights(Graphics g, int lineStart, int lineEnd, Shape viewBounds, JTextComponent editor,
|
||||||
|
View view) {
|
||||||
paintListLayered(g, lineStart, lineEnd, viewBounds, editor, view, markAllHighlights);
|
paintListLayered(g, lineStart, lineEnd, viewBounds, editor, view, markAllHighlights);
|
||||||
super.paintLayeredHighlights(g, lineStart, lineEnd, viewBounds, editor, view);
|
super.paintLayeredHighlights(g, lineStart, lineEnd, viewBounds, editor, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void paintListLayered(Graphics g, int lineStart, int lineEnd, Shape viewBounds, JTextComponent editor, View view,
|
protected void paintListLayered(Graphics g, int lineStart, int lineEnd, Shape viewBounds, JTextComponent editor,
|
||||||
List<? extends HighlightInfo> highlights) {
|
View view, List<? extends HighlightInfo> highlights) {
|
||||||
for (int i = highlights.size() - 1; i >= 0; i--) {
|
for (int i = highlights.size() - 1; i >= 0; i--) {
|
||||||
HighlightInfo tag = highlights.get(i);
|
HighlightInfo tag = highlights.get(i);
|
||||||
if (tag instanceof LayeredHighlightInfo) {
|
if (tag instanceof LayeredHighlightInfo) {
|
||||||
@@ -175,7 +167,8 @@ public class RTextAreaHighlighter extends BasicHighlighter {
|
|||||||
int highlightEnd = lhi.getEndOffset() + 1; // "+1" workaround
|
int highlightEnd = lhi.getEndOffset() + 1; // "+1" workaround
|
||||||
// for Java
|
// for Java
|
||||||
// highlight issues
|
// highlight issues
|
||||||
if ((lineStart < highlightStart && lineEnd > highlightStart) || (lineStart >= highlightStart && lineStart < highlightEnd)) {
|
if ((lineStart < highlightStart && lineEnd > highlightStart)
|
||||||
|
|| (lineStart >= highlightStart && lineStart < highlightEnd)) {
|
||||||
lhi.paintLayeredHighlights(g, lineStart, lineEnd, viewBounds, editor, view);
|
lhi.paintLayeredHighlights(g, lineStart, lineEnd, viewBounds, editor, view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,7 +192,8 @@ public class RTextAreaHighlighter extends BasicHighlighter {
|
|||||||
/**
|
/**
|
||||||
* Information about a highlight being painted by this highlighter.
|
* Information about a highlight being painted by this highlighter.
|
||||||
*/
|
*/
|
||||||
public interface HighlightInfo extends Highlighter.Highlight {}
|
public interface HighlightInfo extends Highlighter.Highlight {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about a layered highlight being painted by this highlighter.
|
* Information about a layered highlight being painted by this highlighter.
|
||||||
@@ -207,8 +201,8 @@ public class RTextAreaHighlighter extends BasicHighlighter {
|
|||||||
public interface LayeredHighlightInfo extends HighlightInfo {
|
public interface LayeredHighlightInfo extends HighlightInfo {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restricts the region based on the receivers offsets and messages
|
* Restricts the region based on the receivers offsets and messages the painter
|
||||||
* the painter to paint the region.
|
* to paint the region.
|
||||||
*/
|
*/
|
||||||
void paintLayeredHighlights(Graphics g, int p0, int p1, Shape viewBounds, JTextComponent editor, View view);
|
void paintLayeredHighlights(Graphics g, int p0, int p1, Shape viewBounds, JTextComponent editor, View view);
|
||||||
}
|
}
|
||||||
@@ -256,21 +250,16 @@ public class RTextAreaHighlighter extends BasicHighlighter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A straightforward implementation of <code>HighlightInfo</code> for
|
* A straightforward implementation of <code>HighlightInfo</code> for painting
|
||||||
* painting layered highlights.
|
* layered highlights.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "checkstyle:visibilitymodifier" })
|
|
||||||
protected static class LayeredHighlightInfoImpl extends HighlightInfoImpl implements LayeredHighlightInfo {
|
protected static class LayeredHighlightInfoImpl extends HighlightInfoImpl implements LayeredHighlightInfo {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: This implementation is a "hack" so typing at the "end" of the
|
* NOTE: This implementation is a "hack" so typing at the "end" of the highlight
|
||||||
* highlight
|
* does not extend it to include the newly-typed chars, which is the standard
|
||||||
* does not extend it to include the newly-typed chars, which is the
|
* behavior of Swing Highlights. It assumes that the "p1" Position set is
|
||||||
* standard
|
* actually 1 char too short, and will render the selection as if that "extra"
|
||||||
* behavior of Swing Highlights. It assumes that the "p1" Position set
|
|
||||||
* is
|
|
||||||
* actually 1 char too short, and will render the selection as if that
|
|
||||||
* "extra"
|
|
||||||
* char should be highlighted.
|
* char should be highlighted.
|
||||||
*/
|
*/
|
||||||
public int x;
|
public int x;
|
||||||
@@ -302,7 +291,8 @@ public class RTextAreaHighlighter extends BasicHighlighter {
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void paintLayeredHighlights(Graphics g, int p0, int p1, Shape viewBounds, JTextComponent editor, View view) {
|
public void paintLayeredHighlights(Graphics g, int p0, int p1, Shape viewBounds, JTextComponent editor,
|
||||||
|
View view) {
|
||||||
int start = getStartOffset();
|
int start = getStartOffset();
|
||||||
int end = getEndOffset();
|
int end = getEndOffset();
|
||||||
end++; // Workaround for Java highlight issues
|
end++; // Workaround for Java highlight issues
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ import org.fife.ui.rsyntaxtextarea.DocumentRange;
|
|||||||
import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
|
import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A singleton class that can perform advanced find/replace operations
|
* A singleton class that can perform advanced find/replace operations in an
|
||||||
* in an {@link RTextArea}. Simply create a {@link SearchContext} and call
|
* {@link RTextArea}. Simply create a {@link SearchContext} and call one of the
|
||||||
* one of the following methods:
|
* following methods:
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link #find(JTextArea, SearchContext)}
|
* <li>{@link #find(JTextArea, SearchContext)}
|
||||||
@@ -42,21 +42,18 @@ public final class SearchEngine {
|
|||||||
/**
|
/**
|
||||||
* Private constructor to prevent instantiation.
|
* Private constructor to prevent instantiation.
|
||||||
*/
|
*/
|
||||||
private SearchEngine() {}
|
private SearchEngine() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the next instance of the string/regular expression specified
|
* Finds the next instance of the string/regular expression specified from the
|
||||||
* from the caret position. If a match is found, it is selected in this
|
* caret position. If a match is found, it is selected in this text area.
|
||||||
* text area.
|
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area in which to search.
|
||||||
* The text area in which to search.
|
* @param context What to search for and all search options.
|
||||||
* @param context
|
|
||||||
* What to search for and all search options.
|
|
||||||
* @return The result of the operation.
|
* @return The result of the operation.
|
||||||
* @throws PatternSyntaxException
|
* @throws PatternSyntaxException If this is a regular expression search but the
|
||||||
* If this is a regular expression search
|
* search text is an invalid regular expression.
|
||||||
* but the search text is an invalid regular expression.
|
|
||||||
* @see #replace(RTextArea, SearchContext)
|
* @see #replace(RTextArea, SearchContext)
|
||||||
* @see #replaceAll(RTextArea, SearchContext)
|
* @see #replaceAll(RTextArea, SearchContext)
|
||||||
*/
|
*/
|
||||||
@@ -108,19 +105,15 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the next instance of the string/regular expression specified
|
* Finds the next instance of the string/regular expression specified from the
|
||||||
* from the caret position. If a match is found, it is selected in this
|
* caret position. If a match is found, it is selected in this text area.
|
||||||
* text area.
|
|
||||||
*
|
*
|
||||||
* @param findIn
|
* @param findIn The text to search in.
|
||||||
* The text to search in.
|
* @param context The search context.
|
||||||
* @param context
|
* @return The result of the operation. "Mark all" will always be zero, since
|
||||||
* The search context.
|
* this method does not perform that operation.
|
||||||
* @return The result of the operation. "Mark all" will always be zero,
|
* @throws PatternSyntaxException If this is a regular expression search but the
|
||||||
* since this method does not perform that operation.
|
* search text is an invalid regular expression.
|
||||||
* @throws PatternSyntaxException
|
|
||||||
* If this is a regular expression search
|
|
||||||
* but the search text is an invalid regular expression.
|
|
||||||
*/
|
*/
|
||||||
private static SearchResult findImpl(String findIn, SearchContext context) {
|
private static SearchResult findImpl(String findIn, SearchContext context) {
|
||||||
String text = context.getSearchFor();
|
String text = context.getSearchFor();
|
||||||
@@ -140,7 +133,8 @@ public final class SearchEngine {
|
|||||||
Point regExPos = null;
|
Point regExPos = null;
|
||||||
int start = 0;
|
int start = 0;
|
||||||
do {
|
do {
|
||||||
regExPos = getNextMatchPosRegEx(text, findIn.substring(start), forward, context.getMatchCase(), context.getWholeWord());
|
regExPos = getNextMatchPosRegEx(text, findIn.substring(start), forward, context.getMatchCase(),
|
||||||
|
context.getWholeWord());
|
||||||
if (regExPos != null) {
|
if (regExPos != null) {
|
||||||
if (regExPos.x != regExPos.y) {
|
if (regExPos.x != regExPos.y) {
|
||||||
regExPos.translate(start, start);
|
regExPos.translate(start, start);
|
||||||
@@ -159,18 +153,15 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a <code>CharSequence</code> for a text area that doesn't make a
|
* Returns a <code>CharSequence</code> for a text area that doesn't make a copy
|
||||||
* copy of its contents for iteration. This conserves memory but is likely
|
* of its contents for iteration. This conserves memory but is likely just a tad
|
||||||
* just a tad slower.
|
* slower.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area whose document is the basis for the
|
||||||
* The text area whose document is the basis for the
|
* <code>CharSequence</code>.
|
||||||
* <code>CharSequence</code>.
|
* @param start The starting offset of the sequence (or ending offset if
|
||||||
* @param start
|
* <code>forward</code> is <code>false</code>).
|
||||||
* The starting offset of the sequence (or ending offset if
|
* @param forward Whether we're searching forward or backward.
|
||||||
* <code>forward</code> is <code>false</code>).
|
|
||||||
* @param forward
|
|
||||||
* Whether we're searching forward or backward.
|
|
||||||
* @return The character sequence.
|
* @return The character sequence.
|
||||||
*/
|
*/
|
||||||
private static CharSequence getFindInCharSequence(RTextArea textArea, int start, boolean forward) {
|
private static CharSequence getFindInCharSequence(RTextArea textArea, int start, boolean forward) {
|
||||||
@@ -188,8 +179,8 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the text in which to search, as a string. This is used
|
* Returns the text in which to search, as a string. This is used internally to
|
||||||
* internally to grab the smallest buffer possible in which to search.
|
* grab the smallest buffer possible in which to search.
|
||||||
*/
|
*/
|
||||||
private static String getFindInText(JTextArea textArea, int start, boolean forward) {
|
private static String getFindInText(JTextArea textArea, int start, boolean forward) {
|
||||||
// Be smart about the text we grab to search in. We grab more than
|
// Be smart about the text we grab to search in. We grab more than
|
||||||
@@ -210,40 +201,34 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called internally by
|
* This method is called internally by <code>getNextMatchPosRegExImpl</code> and
|
||||||
* <code>getNextMatchPosRegExImpl</code> and is used to get the locations
|
* is used to get the locations of all regular-expression matches, and possibly
|
||||||
* of all regular-expression matches, and possibly their replacement
|
* their replacement strings.
|
||||||
* strings.
|
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* Returns either:
|
* Returns either:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>A list of points representing the starting and ending positions
|
* <li>A list of points representing the starting and ending positions of all
|
||||||
* of all matches returned by the specified matcher, or
|
* matches returned by the specified matcher, or
|
||||||
* <li>A list of <code>RegExReplaceInfo</code>s describing the matches
|
* <li>A list of <code>RegExReplaceInfo</code>s describing the matches found by
|
||||||
* found by the matcher and the replacement strings for each.
|
* the matcher and the replacement strings for each.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* If <code>replacement</code> is <code>null</code>, this method call is
|
* If <code>replacement</code> is <code>null</code>, this method call is assumed
|
||||||
* assumed to be part of a "find" operation and points are returned. If
|
* to be part of a "find" operation and points are returned. If if is
|
||||||
* if is non-<code>null</code>, it is assumed to be part of a "replace"
|
* non-<code>null</code>, it is assumed to be part of a "replace" operation and
|
||||||
* operation and the <code>RegExReplaceInfo</code>s are returned.
|
* the <code>RegExReplaceInfo</code>s are returned.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* @param m
|
* @param m The matcher.
|
||||||
* The matcher.
|
* @param replaceStr The string to replace matches with. This is a "template"
|
||||||
* @param replaceStr
|
* string and can contain captured group references in the
|
||||||
* The string to replace matches with. This is a
|
* form "<code>${digit}</code>".
|
||||||
* "template" string and can contain captured group references in
|
|
||||||
* the form "<code>${digit}</code>".
|
|
||||||
* @return A list of result objects.
|
* @return A list of result objects.
|
||||||
* @throws IndexOutOfBoundsException
|
* @throws IndexOutOfBoundsException If <code>replaceStr</code> references an
|
||||||
* If <code>replaceStr</code> references
|
* invalid group (less than zero or greater
|
||||||
* an invalid group (less than zero or greater than the number
|
* than the number of groups matched).
|
||||||
* of
|
|
||||||
* groups matched).
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
|
||||||
private static List getMatches(Matcher m, String replaceStr) {
|
private static List getMatches(Matcher m, String replaceStr) {
|
||||||
ArrayList matches = new ArrayList();
|
ArrayList matches = new ArrayList();
|
||||||
while (m.find()) {
|
while (m.find()) {
|
||||||
@@ -258,31 +243,26 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches <code>searchIn</code> for an occurrence of
|
* Searches <code>searchIn</code> for an occurrence of <code>searchFor</code>
|
||||||
* <code>searchFor</code> either forwards or backwards, matching
|
* either forwards or backwards, matching case or not.
|
||||||
* case or not.
|
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* Most clients will have no need to call this method directly.
|
* Most clients will have no need to call this method directly.
|
||||||
*
|
*
|
||||||
* @param searchFor
|
* @param searchFor The string to look for.
|
||||||
* The string to look for.
|
* @param searchIn The string to search in.
|
||||||
* @param searchIn
|
* @param forward Whether to search forward or backward in
|
||||||
* The string to search in.
|
* <code>searchIn</code>.
|
||||||
* @param forward
|
* @param matchCase If <code>true</code>, do a case-sensitive search for
|
||||||
* Whether to search forward or backward in
|
* <code>searchFor</code>.
|
||||||
* <code>searchIn</code>.
|
* @param wholeWord If <code>true</code>, <code>searchFor</code> occurrences
|
||||||
* @param matchCase
|
* embedded in longer words in <code>searchIn</code> don't
|
||||||
* If <code>true</code>, do a case-sensitive search for
|
* count as matches.
|
||||||
* <code>searchFor</code>.
|
* @return The starting position of a match, or <code>-1</code> if no match was
|
||||||
* @param wholeWord
|
* found.
|
||||||
* If <code>true</code>, <code>searchFor</code>
|
|
||||||
* occurrences embedded in longer words in <code>searchIn</code>
|
|
||||||
* don't count as matches.
|
|
||||||
* @return The starting position of a match, or <code>-1</code> if no
|
|
||||||
* match was found.
|
|
||||||
*/
|
*/
|
||||||
public static int getNextMatchPos(String searchFor, String searchIn, boolean forward, boolean matchCase, boolean wholeWord) {
|
public static int getNextMatchPos(String searchFor, String searchIn, boolean forward, boolean matchCase,
|
||||||
|
boolean wholeWord) {
|
||||||
// Make our variables lower case if we're ignoring case.
|
// Make our variables lower case if we're ignoring case.
|
||||||
if (!matchCase) {
|
if (!matchCase) {
|
||||||
return getNextMatchPosImpl(searchFor.toLowerCase(), searchIn.toLowerCase(), forward, matchCase, wholeWord);
|
return getNextMatchPosImpl(searchFor.toLowerCase(), searchIn.toLowerCase(), forward, matchCase, wholeWord);
|
||||||
@@ -291,28 +271,23 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actually does the work of matching; assumes searchFor and searchIn
|
* Actually does the work of matching; assumes searchFor and searchIn are
|
||||||
* are already upper/lower-cased appropriately.<br>
|
* already upper/lower-cased appropriately.<br>
|
||||||
* The reason this method is here is to attempt to speed up
|
* The reason this method is here is to attempt to speed up
|
||||||
* <code>FindInFilesDialog</code>; since it repeatedly calls
|
* <code>FindInFilesDialog</code>; since it repeatedly calls this method instead
|
||||||
* this method instead of <code>getNextMatchPos</code>, it gets better
|
* of <code>getNextMatchPos</code>, it gets better performance as it no longer
|
||||||
* performance as it no longer has to allocate a lower-cased string for
|
* has to allocate a lower-cased string for every call.
|
||||||
* every call.
|
|
||||||
*
|
*
|
||||||
* @param searchFor
|
* @param searchFor The string to search for.
|
||||||
* The string to search for.
|
* @param searchIn The string to search in.
|
||||||
* @param searchIn
|
* @param goForward Whether the search is forward or backward.
|
||||||
* The string to search in.
|
* @param matchCase Whether the search is case-sensitive.
|
||||||
* @param goForward
|
* @param wholeWord Whether only whole words should be matched.
|
||||||
* Whether the search is forward or backward.
|
* @return The location of the next match, or <code>-1</code> if no match was
|
||||||
* @param matchCase
|
* found.
|
||||||
* Whether the search is case-sensitive.
|
|
||||||
* @param wholeWord
|
|
||||||
* Whether only whole words should be matched.
|
|
||||||
* @return The location of the next match, or <code>-1</code> if no
|
|
||||||
* match was found.
|
|
||||||
*/
|
*/
|
||||||
private static int getNextMatchPosImpl(String searchFor, String searchIn, boolean goForward, boolean matchCase, boolean wholeWord) {
|
private static int getNextMatchPosImpl(String searchFor, String searchIn, boolean goForward, boolean matchCase,
|
||||||
|
boolean wholeWord) {
|
||||||
if (wholeWord) {
|
if (wholeWord) {
|
||||||
int len = searchFor.length();
|
int len = searchFor.length();
|
||||||
int temp = goForward ? 0 : searchIn.length();
|
int temp = goForward ? 0 : searchIn.length();
|
||||||
@@ -339,29 +314,22 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches <code>searchIn</code> for an occurrence of <code>regEx</code>
|
* Searches <code>searchIn</code> for an occurrence of <code>regEx</code> either
|
||||||
* either forwards or backwards, matching case or not.
|
* forwards or backwards, matching case or not.
|
||||||
*
|
*
|
||||||
* @param regEx
|
* @param regEx The regular expression to look for.
|
||||||
* The regular expression to look for.
|
* @param searchIn The string to search in.
|
||||||
* @param searchIn
|
* @param goForward Whether to search forward. If <code>false</code>, search
|
||||||
* The string to search in.
|
* backward.
|
||||||
* @param goForward
|
* @param matchCase Whether or not to do a case-sensitive search for
|
||||||
* Whether to search forward. If <code>false</code>,
|
* <code>regEx</code>.
|
||||||
* search backward.
|
* @param wholeWord If <code>true</code>, <code>regEx</code> occurrences
|
||||||
* @param matchCase
|
* embedded in longer words in <code>searchIn</code> don't
|
||||||
* Whether or not to do a case-sensitive search for
|
* count as matches.
|
||||||
* <code>regEx</code>.
|
* @return A <code>Point</code> representing the starting and ending position of
|
||||||
* @param wholeWord
|
* the match, or <code>null</code> if no match was found.
|
||||||
* If <code>true</code>, <code>regEx</code>
|
* @throws PatternSyntaxException If <code>regEx</code> is an invalid regular
|
||||||
* occurrences embedded in longer words in <code>searchIn</code>
|
* expression.
|
||||||
* don't count as matches.
|
|
||||||
* @return A <code>Point</code> representing the starting and ending
|
|
||||||
* position of the match, or <code>null</code> if no match was
|
|
||||||
* found.
|
|
||||||
* @throws PatternSyntaxException
|
|
||||||
* If <code>regEx</code> is an invalid
|
|
||||||
* regular expression.
|
|
||||||
* @see #getNextMatchPos
|
* @see #getNextMatchPos
|
||||||
*/
|
*/
|
||||||
private static Point getNextMatchPosRegEx(String regEx, CharSequence searchIn, boolean goForward, boolean matchCase,
|
private static Point getNextMatchPosRegEx(String regEx, CharSequence searchIn, boolean goForward, boolean matchCase,
|
||||||
@@ -370,47 +338,37 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches <code>searchIn</code> for an occurrence of <code>regEx</code>
|
* Searches <code>searchIn</code> for an occurrence of <code>regEx</code> either
|
||||||
* either forwards or backwards, matching case or not.
|
* forwards or backwards, matching case or not.
|
||||||
*
|
*
|
||||||
* @param regEx
|
* @param regEx The regular expression to look for.
|
||||||
* The regular expression to look for.
|
* @param searchIn The string to search in.
|
||||||
* @param searchIn
|
* @param goForward Whether to search forward. If <code>false</code>, search
|
||||||
* The string to search in.
|
* backward.
|
||||||
* @param goForward
|
* @param matchCase Whether or not to do a case-sensitive search for
|
||||||
* Whether to search forward. If <code>false</code>,
|
* <code>regEx</code>.
|
||||||
* search backward.
|
* @param wholeWord If <code>true</code>, <code>regEx</code> occurrences
|
||||||
* @param matchCase
|
* embedded in longer words in <code>searchIn</code> don't
|
||||||
* Whether or not to do a case-sensitive search for
|
* count as matches.
|
||||||
* <code>regEx</code>.
|
* @param replaceStr The string that will replace the match found (if a match is
|
||||||
* @param wholeWord
|
* found). The object returned will contain the replacement
|
||||||
* If <code>true</code>, <code>regEx</code>
|
* string with matched groups substituted. If this value is
|
||||||
* occurrences embedded in longer words in <code>searchIn</code>
|
* <code>null</code>, it is assumed this call is part of a
|
||||||
* don't count as matches.
|
* "find" instead of a "replace" operation.
|
||||||
* @param replaceStr
|
* @return If <code>replaceStr</code> is <code>null</code>, a <code>Point</code>
|
||||||
* The string that will replace the match found (if
|
* representing the starting and ending points of the match. If it is
|
||||||
* a match is found). The object returned will contain the
|
* non-<code>null</code>, an object with information about the match and
|
||||||
* replacement string with matched groups substituted. If this
|
* the morphed string to replace it with. If no match is found,
|
||||||
* value is <code>null</code>, it is assumed this call is part of
|
* <code>null</code> is returned.
|
||||||
* a
|
* @throws PatternSyntaxException If <code>regEx</code> is an invalid regular
|
||||||
* "find" instead of a "replace" operation.
|
* expression.
|
||||||
* @return If <code>replaceStr</code> is <code>null</code>, a
|
* @throws IndexOutOfBoundsException If <code>replaceStr</code> references an
|
||||||
* <code>Point</code> representing the starting and ending points
|
* invalid group (less than zero or greater
|
||||||
* of the match. If it is non-<code>null</code>, an object with
|
* than the number of groups matched).
|
||||||
* information about the match and the morphed string to replace
|
|
||||||
* it with. If no match is found, <code>null</code> is returned.
|
|
||||||
* @throws PatternSyntaxException
|
|
||||||
* If <code>regEx</code> is an invalid
|
|
||||||
* regular expression.
|
|
||||||
* @throws IndexOutOfBoundsException
|
|
||||||
* If <code>replaceStr</code> references
|
|
||||||
* an invalid group (less than zero or greater than the number
|
|
||||||
* of
|
|
||||||
* groups matched).
|
|
||||||
* @see #getNextMatchPos
|
* @see #getNextMatchPos
|
||||||
*/
|
*/
|
||||||
private static Object getNextMatchPosRegExImpl(String regEx, CharSequence searchIn, boolean goForward, boolean matchCase,
|
private static Object getNextMatchPosRegExImpl(String regEx, CharSequence searchIn, boolean goForward,
|
||||||
boolean wholeWord, String replaceStr) {
|
boolean matchCase, boolean wholeWord, String replaceStr) {
|
||||||
if (wholeWord) {
|
if (wholeWord) {
|
||||||
regEx = "\\b" + regEx + "\\b";
|
regEx = "\\b" + regEx + "\\b";
|
||||||
}
|
}
|
||||||
@@ -446,22 +404,18 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns information on how to implement a regular expression "replace"
|
* Returns information on how to implement a regular expression "replace" action
|
||||||
* action in the specified text with the specified replacement string.
|
* in the specified text with the specified replacement string.
|
||||||
*
|
*
|
||||||
* @param searchIn
|
* @param searchIn The string to search in.
|
||||||
* The string to search in.
|
* @param context The search options.
|
||||||
* @param context
|
* @return A <code>RegExReplaceInfo</code> object describing how to implement
|
||||||
* The search options.
|
* the replace.
|
||||||
* @return A <code>RegExReplaceInfo</code> object describing how to
|
* @throws PatternSyntaxException If the search text is an invalid regular
|
||||||
* implement the replace.
|
* expression.
|
||||||
* @throws PatternSyntaxException
|
* @throws IndexOutOfBoundsException If the replacement text references an
|
||||||
* If the search text is an invalid regular
|
* invalid group (less than zero or greater
|
||||||
* expression.
|
* than the number of groups matched).
|
||||||
* @throws IndexOutOfBoundsException
|
|
||||||
* If the replacement text references an
|
|
||||||
* invalid group (less than zero or greater than the number of
|
|
||||||
* groups matched).
|
|
||||||
* @see #getNextMatchPos
|
* @see #getNextMatchPos
|
||||||
*/
|
*/
|
||||||
private static RegExReplaceInfo getRegExReplaceInfo(CharSequence searchIn, SearchContext context) {
|
private static RegExReplaceInfo getRegExReplaceInfo(CharSequence searchIn, SearchContext context) {
|
||||||
@@ -476,39 +430,34 @@ public final class SearchEngine {
|
|||||||
boolean goForward = context.getSearchForward();
|
boolean goForward = context.getSearchForward();
|
||||||
boolean matchCase = context.getMatchCase();
|
boolean matchCase = context.getMatchCase();
|
||||||
boolean wholeWord = context.getWholeWord();
|
boolean wholeWord = context.getWholeWord();
|
||||||
return (RegExReplaceInfo) getNextMatchPosRegExImpl(regex, searchIn, goForward, matchCase, wholeWord, replacement);
|
return (RegExReplaceInfo) getNextMatchPosRegExImpl(regex, searchIn, goForward, matchCase, wholeWord,
|
||||||
|
replacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called internally by <code>getMatches()</code>. This method assumes
|
* Called internally by <code>getMatches()</code>. This method assumes that the
|
||||||
* that the specified matcher has just found a match, and that you want
|
* specified matcher has just found a match, and that you want to get the string
|
||||||
* to get the string with which to replace that match.
|
* with which to replace that match.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* Escapes simply insert the escaped character, except for <code>\n</code>
|
* Escapes simply insert the escaped character, except for <code>\n</code> and
|
||||||
* and <code>\t</code>, which insert a newline and tab respectively.
|
* <code>\t</code>, which insert a newline and tab respectively. Substrings of
|
||||||
* Substrings of the form <code>$\d+</code> are considered to be matched
|
* the form <code>$\d+</code> are considered to be matched groups. To include a
|
||||||
* groups. To include a literal dollar sign in your template, escape it
|
* literal dollar sign in your template, escape it (i.e. <code>\$</code>).
|
||||||
* (i.e. <code>\$</code>).
|
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* Most clients will have no need to call this method directly.
|
* Most clients will have no need to call this method directly.
|
||||||
*
|
*
|
||||||
* @param m
|
* @param m The matcher.
|
||||||
* The matcher.
|
* @param template The template for the replacement string. For example,
|
||||||
* @param template
|
* "<code>foo</code>" would yield the replacement string
|
||||||
* The template for the replacement string. For example,
|
* "<code>foo</code>", while "<code>$1 is the greatest</code>"
|
||||||
* "<code>foo</code>" would yield the replacement string
|
* would yield different values depending on the value of the
|
||||||
* "<code>foo</code>", while "<code>$1 is the greatest</code>"
|
* first captured group in the match.
|
||||||
* would yield different values depending on the value of the
|
|
||||||
* first
|
|
||||||
* captured group in the match.
|
|
||||||
* @return The string to replace the match with.
|
* @return The string to replace the match with.
|
||||||
* @throws IndexOutOfBoundsException
|
* @throws IndexOutOfBoundsException If <code>template</code> references an
|
||||||
* If <code>template</code> references
|
* invalid group (less than zero or greater
|
||||||
* an invalid group (less than zero or greater than the number
|
* than the number of groups matched).
|
||||||
* of
|
|
||||||
* groups matched).
|
|
||||||
*/
|
*/
|
||||||
public static String getReplacementText(Matcher m, CharSequence template) {
|
public static String getReplacementText(Matcher m, CharSequence template) {
|
||||||
// NOTE: This code was mostly ripped off from J2SE's Matcher
|
// NOTE: This code was mostly ripped off from J2SE's Matcher
|
||||||
@@ -521,12 +470,12 @@ public final class SearchEngine {
|
|||||||
if (nextChar == '\\') { // Escape character.
|
if (nextChar == '\\') { // Escape character.
|
||||||
nextChar = template.charAt(++cursor);
|
nextChar = template.charAt(++cursor);
|
||||||
switch (nextChar) { // Special cases.
|
switch (nextChar) { // Special cases.
|
||||||
case 'n':
|
case 'n':
|
||||||
nextChar = '\n';
|
nextChar = '\n';
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
nextChar = '\t';
|
nextChar = '\t';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
result.append(nextChar);
|
result.append(nextChar);
|
||||||
cursor++;
|
cursor++;
|
||||||
@@ -573,8 +522,8 @@ public final class SearchEngine {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the characters on either side of
|
* Returns whether the characters on either side of
|
||||||
* <code>substr(searchIn, startPos, startPos+searchStringLength)</code>
|
* <code>substr(searchIn, startPos, startPos+searchStringLength)</code> are
|
||||||
* are <em>not</em> letters or digits.
|
* <em>not</em> letters or digits.
|
||||||
*/
|
*/
|
||||||
private static boolean isWholeWord(CharSequence searchIn, int offset, int len) {
|
private static boolean isWholeWord(CharSequence searchIn, int offset, int len) {
|
||||||
boolean wsBefore, wsAfter;
|
boolean wsBefore, wsAfter;
|
||||||
@@ -592,15 +541,13 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the caret's dot and mark the same location so that, for the
|
* Makes the caret's dot and mark the same location so that, for the next search
|
||||||
* next search in the specified direction, a match will be found even
|
* in the specified direction, a match will be found even if it was within the
|
||||||
* if it was within the original dot and mark's selection.
|
* original dot and mark's selection.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area.
|
||||||
* The text area.
|
* @param forward Whether the search will be forward through the document
|
||||||
* @param forward
|
* (<code>false</code> means backward).
|
||||||
* Whether the search will be forward through the
|
|
||||||
* document (<code>false</code> means backward).
|
|
||||||
* @return The new dot and mark position.
|
* @return The new dot and mark position.
|
||||||
*/
|
*/
|
||||||
private static int makeMarkAndDotEqual(JTextArea textArea, boolean forward) {
|
private static int makeMarkAndDotEqual(JTextArea textArea, boolean forward) {
|
||||||
@@ -611,19 +558,16 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks all instances of the specified text in this text area. This
|
* Marks all instances of the specified text in this text area. This method is
|
||||||
* method is typically only called directly in response to search events
|
* typically only called directly in response to search events of type
|
||||||
* of type <code>SearchEvent.Type.MARK_ALL</code>. "Mark all" behavior
|
* <code>SearchEvent.Type.MARK_ALL</code>. "Mark all" behavior is automatically
|
||||||
* is automatically performed when {@link #find(JTextArea, SearchContext)}
|
* performed when {@link #find(JTextArea, SearchContext)} or
|
||||||
* or {@link #replace(RTextArea, SearchContext)} is called.
|
* {@link #replace(RTextArea, SearchContext)} is called.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area in which to mark occurrences.
|
||||||
* The text area in which to mark occurrences.
|
* @param context The search context specifying the text to search for. It is
|
||||||
* @param context
|
* assumed that <code>context.getMarkAll()</code> has already
|
||||||
* The search context specifying the text to search for.
|
* been checked and returns <code>true</code>.
|
||||||
* It is assumed that <code>context.getMarkAll()</code> has
|
|
||||||
* already
|
|
||||||
* been checked and returns <code>true</code>.
|
|
||||||
* @return The results of the operation.
|
* @return The results of the operation.
|
||||||
*/
|
*/
|
||||||
public static SearchResult markAll(RTextArea textArea, SearchContext context) {
|
public static SearchResult markAll(RTextArea textArea, SearchContext context) {
|
||||||
@@ -635,19 +579,16 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks all instances of the specified text in this text area. This
|
* Marks all instances of the specified text in this text area. This method is
|
||||||
* method is typically only called directly in response to search events
|
* typically only called directly in response to search events of type
|
||||||
* of type <code>SearchEvent.Type.MARK_ALL</code>. "Mark all" behavior
|
* <code>SearchEvent.Type.MARK_ALL</code>. "Mark all" behavior is automatically
|
||||||
* is automatically performed when {@link #find(JTextArea, SearchContext)}
|
* performed when {@link #find(JTextArea, SearchContext)} or #replace(RTextArea,
|
||||||
* or #replace(RTextArea, SearchContext) is called.
|
* SearchContext) is called.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area in which to mark occurrences.
|
||||||
* The text area in which to mark occurrences.
|
* @param context The search context specifying the text to search for. It is
|
||||||
* @param context
|
* assumed that <code>context.getMarkAll()</code> has already
|
||||||
* The search context specifying the text to search for.
|
* been checked and returns <code>true</code>.
|
||||||
* It is assumed that <code>context.getMarkAll()</code> has
|
|
||||||
* already
|
|
||||||
* been checked and returns <code>true</code>.
|
|
||||||
* @return The results of the operation.
|
* @return The results of the operation.
|
||||||
*/
|
*/
|
||||||
private static SearchResult markAllImpl(RTextArea textArea, SearchContext context) {
|
private static SearchResult markAllImpl(RTextArea textArea, SearchContext context) {
|
||||||
@@ -700,23 +641,20 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the next instance of the regular expression specified from
|
* Finds the next instance of the regular expression specified from the caret
|
||||||
* the caret position. If a match is found, it is replaced with
|
* position. If a match is found, it is replaced with the specified replacement
|
||||||
* the specified replacement string.
|
* string.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area in which to search.
|
||||||
* The text area in which to search.
|
* @param context What to search for and all search options.
|
||||||
* @param context
|
|
||||||
* What to search for and all search options.
|
|
||||||
* @return The result of the operation.
|
* @return The result of the operation.
|
||||||
* @throws PatternSyntaxException
|
* @throws PatternSyntaxException If this is a regular expression search but
|
||||||
* If this is a regular expression search
|
* the search text is an invalid regular
|
||||||
* but the search text is an invalid regular expression.
|
* expression.
|
||||||
* @throws IndexOutOfBoundsException
|
* @throws IndexOutOfBoundsException If this is a regular expression search but
|
||||||
* If this is a regular expression search
|
* the replacement text references an invalid
|
||||||
* but the replacement text references an invalid group (less
|
* group (less than zero or greater than the
|
||||||
* than
|
* number of groups matched).
|
||||||
* zero or greater than the number of groups matched).
|
|
||||||
* @see #replace(RTextArea, SearchContext)
|
* @see #replace(RTextArea, SearchContext)
|
||||||
* @see #find(JTextArea, SearchContext)
|
* @see #find(JTextArea, SearchContext)
|
||||||
*/
|
*/
|
||||||
@@ -778,23 +716,20 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the next instance of the text/regular expression specified from
|
* Finds the next instance of the text/regular expression specified from the
|
||||||
* the caret position. If a match is found, it is replaced with the
|
* caret position. If a match is found, it is replaced with the specified
|
||||||
* specified replacement string.
|
* replacement string.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area in which to search.
|
||||||
* The text area in which to search.
|
* @param context What to search for and all search options.
|
||||||
* @param context
|
|
||||||
* What to search for and all search options.
|
|
||||||
* @return The result of the operation.
|
* @return The result of the operation.
|
||||||
* @throws PatternSyntaxException
|
* @throws PatternSyntaxException If this is a regular expression search but
|
||||||
* If this is a regular expression search
|
* the search text is an invalid regular
|
||||||
* but the search text is an invalid regular expression.
|
* expression.
|
||||||
* @throws IndexOutOfBoundsException
|
* @throws IndexOutOfBoundsException If this is a regular expression search but
|
||||||
* If this is a regular expression search
|
* the replacement text references an invalid
|
||||||
* but the replacement text references an invalid group (less
|
* group (less than zero or greater than the
|
||||||
* than
|
* number of groups matched).
|
||||||
* zero or greater than the number of groups matched).
|
|
||||||
* @see #replaceAll(RTextArea, SearchContext)
|
* @see #replaceAll(RTextArea, SearchContext)
|
||||||
* @see #find(JTextArea, SearchContext)
|
* @see #find(JTextArea, SearchContext)
|
||||||
*/
|
*/
|
||||||
@@ -849,22 +784,19 @@ public final class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces all instances of the text/regular expression specified in
|
* Replaces all instances of the text/regular expression specified in the
|
||||||
* the specified document with the specified replacement.
|
* specified document with the specified replacement.
|
||||||
*
|
*
|
||||||
* @param textArea
|
* @param textArea The text area in which to search.
|
||||||
* The text area in which to search.
|
* @param context What to search for and all search options.
|
||||||
* @param context
|
|
||||||
* What to search for and all search options.
|
|
||||||
* @return The result of the operation.
|
* @return The result of the operation.
|
||||||
* @throws PatternSyntaxException
|
* @throws PatternSyntaxException If this is a regular expression search but
|
||||||
* If this is a regular expression search
|
* the replacement text is an invalid regular
|
||||||
* but the replacement text is an invalid regular expression.
|
* expression.
|
||||||
* @throws IndexOutOfBoundsException
|
* @throws IndexOutOfBoundsException If this is a regular expression search but
|
||||||
* If this is a regular expression search
|
* the replacement text references an invalid
|
||||||
* but the replacement text references an invalid group (less
|
* group (less than zero or greater than the
|
||||||
* than
|
* number of groups matched).
|
||||||
* zero or greater than the number of groups matched).
|
|
||||||
* @see #replace(RTextArea, SearchContext)
|
* @see #replace(RTextArea, SearchContext)
|
||||||
* @see #find(JTextArea, SearchContext)
|
* @see #find(JTextArea, SearchContext)
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in new issue
Block a user