diff --git a/CMakeLists.txt b/CMakeLists.txt
index 40d5617..165118a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,6 +24,7 @@ set(INCLUDE_FILES
include/QSyntaxStyle
include/QGLSLCompleter
include/QGLSLHighlighter
+ include/QJavaHighlighter
include/QLanguage
include/QXMLHighlighter
include/QJSONHighlighter
@@ -35,6 +36,7 @@ set(INCLUDE_FILES
include/internal/QHighlightBlockRule.hpp
include/internal/QCodeEditor.hpp
include/internal/QCXXHighlighter.hpp
+ include/internal/QJavaHighlighter.hpp
include/internal/QLineNumberArea.hpp
include/internal/QStyleSyntaxHighlighter.hpp
include/internal/QSyntaxStyle.hpp
@@ -58,6 +60,7 @@ set(SOURCE_FILES
src/internal/QStyleSyntaxHighlighter.cpp
src/internal/QGLSLCompleter.cpp
src/internal/QGLSLHighlighter.cpp
+ src/internal/QJavaHighlighter.cpp
src/internal/QLanguage.cpp
src/internal/QXMLHighlighter.cpp
src/internal/QJSONHighlighter.cpp
diff --git a/example/resources/code_samples/java.java b/example/resources/code_samples/java.java
new file mode 100644
index 0000000..8124220
--- /dev/null
+++ b/example/resources/code_samples/java.java
@@ -0,0 +1,32 @@
+import java.util.Scanner;
+
+/* This program is simply for demonstrating
+ * the highlighting of Java syntax.
+ */
+
+class Animal { }
+
+class Dog extends Animal { }
+
+public class Example {
+ /** Prompts the user for a string and returns what they entered.
+ * @param message The message to display to the user.
+ * @return The string that the user entered.
+ * */
+ static String prompt(String message) {
+
+ Scanner scanner = new Scanner(System.in);
+
+ System.out.printf("%s: ", message);
+
+ return scanner.nextLine();
+ }
+ public static void main(String[] args) {
+
+ double pi = 3.1415;
+
+ String name = prompt("Enter your name");
+
+ System.out.println("Nice to meet you, " + name + "!");
+ }
+}
diff --git a/example/resources/demo_resources.qrc b/example/resources/demo_resources.qrc
index 146657b..5c8a966 100644
--- a/example/resources/demo_resources.qrc
+++ b/example/resources/demo_resources.qrc
@@ -4,6 +4,7 @@
code_samples/cxx.cpp
code_samples/shader.glsl
code_samples/xml.xml
+ code_samples/java.java
code_samples/json.json
code_samples/lua.lua
code_samples/python.py
diff --git a/example/src/MainWindow.cpp b/example/src/MainWindow.cpp
index 5552835..c568294 100644
--- a/example/src/MainWindow.cpp
+++ b/example/src/MainWindow.cpp
@@ -10,6 +10,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -53,6 +54,7 @@ void MainWindow::initData()
{"C++", loadCode(":/code_samples/cxx.cpp")},
{"GLSL", loadCode(":/code_samples/shader.glsl")},
{"XML", loadCode(":/code_samples/xml.xml")},
+ {"Java", loadCode(":/code_samples/java.java")},
{"JSON", loadCode(":/code_samples/json.json")},
{"LUA", loadCode(":/code_samples/lua.lua")},
{"Python", loadCode(":/code_samples/python.py")}
@@ -70,6 +72,7 @@ void MainWindow::initData()
{"C++", new QCXXHighlighter},
{"GLSL", new QGLSLHighlighter},
{"XML", new QXMLHighlighter},
+ {"Java", new QJavaHighlighter },
{"JSON", new QJSONHighlighter},
{"LUA", new QLuaHighlighter},
{"Python", new QPythonHighlighter},
diff --git a/include/QJavaHighlighter b/include/QJavaHighlighter
new file mode 100644
index 0000000..724e567
--- /dev/null
+++ b/include/QJavaHighlighter
@@ -0,0 +1,3 @@
+#pragma once
+
+#include
diff --git a/include/internal/QJavaHighlighter.hpp b/include/internal/QJavaHighlighter.hpp
new file mode 100644
index 0000000..54222fd
--- /dev/null
+++ b/include/internal/QJavaHighlighter.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+// QCodeEditor
+#include // Required for inheritance
+#include
+
+// Qt
+#include
+#include
+
+class QSyntaxStyle;
+
+/**
+ * @brief Derived to implement highlighting of Java code.
+ */
+class QJavaHighlighter : public QStyleSyntaxHighlighter
+{
+ Q_OBJECT
+public:
+
+ /**
+ * @brief Constructs a new instance of a Java highlighter.
+ * @param document The text document to be highlighted.
+ * This may be a null pointer.
+ */
+ explicit QJavaHighlighter(QTextDocument* document=nullptr);
+
+protected:
+ /**
+ * @brief Derived to highlight blocks of Java code.
+ * @param text The block of text containing Java code.
+ */
+ void highlightBlock(const QString& text) override;
+
+private:
+
+ QVector m_highlightRules;
+
+ QRegularExpression m_commentStartPattern;
+ QRegularExpression m_commentEndPattern;
+};
+
diff --git a/resources/languages/glsl.xml b/resources/languages/glsl.xml
index b543233..595a8fe 100644
--- a/resources/languages/glsl.xml
+++ b/resources/languages/glsl.xml
@@ -351,4 +351,4 @@
iimage2DMSArray
uimage2DMSArray
-
\ No newline at end of file
+
diff --git a/resources/languages/java.xml b/resources/languages/java.xml
new file mode 100644
index 0000000..3fbbdbb
--- /dev/null
+++ b/resources/languages/java.xml
@@ -0,0 +1,62 @@
+
+
+
+ abstract
+ assert
+ break
+ case
+ catch
+ const
+ continue
+ default
+ do
+ else
+ extends
+ final
+ finally
+ for
+ if
+ goto
+ implements
+ import
+ instanceof
+ native
+ new
+ package
+ private
+ protected
+ public
+ return
+ static
+ strictfp
+ super
+ switch
+ synchronized
+ this
+ throw
+ throws
+ transient
+ try
+ volatile
+ while
+
+ true
+ false
+ null
+
+
+
+ boolean
+ byte
+ char
+ class
+ double
+ enum
+ float
+ int
+ interface
+ long
+ short
+ void
+
+
diff --git a/resources/qcodeeditor_resources.qrc b/resources/qcodeeditor_resources.qrc
index ff73feb..bade058 100644
--- a/resources/qcodeeditor_resources.qrc
+++ b/resources/qcodeeditor_resources.qrc
@@ -3,6 +3,7 @@
default_style.xml
languages/glsl.xml
languages/cpp.xml
+ languages/java.xml
languages/lua.xml
languages/python.xml
diff --git a/src/internal/QJavaHighlighter.cpp b/src/internal/QJavaHighlighter.cpp
new file mode 100644
index 0000000..79ad79b
--- /dev/null
+++ b/src/internal/QJavaHighlighter.cpp
@@ -0,0 +1,114 @@
+// QCodeEditor
+#include
+#include
+#include
+
+// Qt
+#include
+
+
+QJavaHighlighter::QJavaHighlighter(QTextDocument* document) :
+ QStyleSyntaxHighlighter(document),
+ m_highlightRules (),
+ m_commentStartPattern(QRegularExpression(R"(/\*)")),
+ m_commentEndPattern (QRegularExpression(R"(\*/)"))
+{
+ Q_INIT_RESOURCE(qcodeeditor_resources);
+
+ QFile fl(":/languages/java.xml");
+
+ if (!fl.open(QIODevice::ReadOnly))
+ {
+ return;
+ }
+
+ QLanguage language(&fl);
+
+ if (!language.isLoaded())
+ {
+ return;
+ }
+
+ auto keys = language.keys();
+ for (auto&& key : keys)
+ {
+ auto names = language.names(key);
+ for (auto&& name : names)
+ {
+ m_highlightRules.append({
+ QRegularExpression(QString(R"(\b%1\b)").arg(name)),
+ key
+ });
+ }
+ }
+
+ // Numbers
+ m_highlightRules.append({
+ QRegularExpression(R"((?<=\b|\s|^)(?i)(?:(?:(?:(?:(?:\d+(?:'\d+)*)?\.(?:\d+(?:'\d+)*)(?:e[+-]?(?:\d+(?:'\d+)*))?)|(?:(?:\d+(?:'\d+)*)\.(?:e[+-]?(?:\d+(?:'\d+)*))?)|(?:(?:\d+(?:'\d+)*)(?:e[+-]?(?:\d+(?:'\d+)*)))|(?:0x(?:[0-9a-f]+(?:'[0-9a-f]+)*)?\.(?:[0-9a-f]+(?:'[0-9a-f]+)*)(?:p[+-]?(?:\d+(?:'\d+)*)))|(?:0x(?:[0-9a-f]+(?:'[0-9a-f]+)*)\.?(?:p[+-]?(?:\d+(?:'\d+)*))))[lf]?)|(?:(?:(?:[1-9]\d*(?:'\d+)*)|(?:0[0-7]*(?:'[0-7]+)*)|(?:0x[0-9a-f]+(?:'[0-9a-f]+)*)|(?:0b[01]+(?:'[01]+)*))(?:u?l{0,2}|l{0,2}u?)))(?=\b|\s|$))"),
+ "Number"
+ });
+
+ // Strings
+ m_highlightRules.append({
+ QRegularExpression(R"("[^\n"]*")"),
+ "String"
+ });
+
+ // Single line
+ m_highlightRules.append({
+ QRegularExpression(R"(//[^\n]*)"),
+ "Comment"
+ });
+}
+
+void QJavaHighlighter::highlightBlock(const QString& text)
+{
+ for (auto& rule : m_highlightRules)
+ {
+ auto matchIterator = rule.pattern.globalMatch(text);
+
+ while (matchIterator.hasNext())
+ {
+ auto match = matchIterator.next();
+
+ setFormat(
+ match.capturedStart(),
+ match.capturedLength(),
+ syntaxStyle()->getFormat(rule.formatName)
+ );
+ }
+ }
+
+ setCurrentBlockState(0);
+
+ int startIndex = 0;
+ if (previousBlockState() != 1)
+ {
+ startIndex = text.indexOf(m_commentStartPattern);
+ }
+
+ while (startIndex >= 0)
+ {
+ auto match = m_commentEndPattern.match(text, startIndex);
+
+ int endIndex = match.capturedStart();
+ int commentLength = 0;
+
+ if (endIndex == -1)
+ {
+ setCurrentBlockState(1);
+ commentLength = text.length() - startIndex;
+ }
+ else
+ {
+ commentLength = endIndex - startIndex + match.capturedLength();
+ }
+
+ setFormat(
+ startIndex,
+ commentLength,
+ syntaxStyle()->getFormat("Comment")
+ );
+ startIndex = text.indexOf(m_commentStartPattern, startIndex + commentLength);
+ }
+}