Click here for the finished product AsciidocEditor
As well as live preview, some settings of ascii doctor and ace editor can be manipulated from GUI, and ascii doctor's default CSS and source highlighter CodeRay's CSS are brought locally. , If you are strong in CSS, you can use your favorite design.
I'm usually a college student. I started programming after I entered university, and until then I hadn't even touched a computer. The only thing I've been doing in practice since I entered the school is learning algorithms and writing in C language. I think it's important and interesting to learn and implement algorithms. However, I have come to feel that it is not enough. So I decided to make a GUI application.
I'm used to C language, but I haven't learned much about Python because it has a template.
The faculty member said something like "At least one procedural type and one object-oriented type should be touched." So I'm not very familiar with programming languages, so when it comes to object-oriented, the mystery of Java !! With that in mind, I decided to get started with Java.
I bought it because it was recommended in various places. It was easy to read and organized according to its reputation, and I was able to imagine object-oriented programming.
After reading the above introductory book, I felt like getting started, so I checked the Java GUI library. What we learned at this stage is as follows.
As a result of the preliminary research, I thought that I had made a difficult language selection. I thought it would be difficult to collect information because JavaFX would not be included in the JDK.
Since I started with a lot of effort, I will reconsider making it.
At the time of the preliminary survey, some people implemented the markdown editor easily, so I thought about adding the original element to something similar. As I researched various things, I found out about the existence of AsciiDoc. Let's make an AsciiDoc editor! And here is the function of the strongest AsciiDoc editor that I thought of
If you make this, it's only one! !!
... that wasn't the case. : innocent:
AsciidocFX
I think there are other great things, but I aimed to add features that Asciidoc FX does not have to the above features. AsciidocFX can fill the editor frame, but not the preview screen. It turns out that even if you specify toc: left
and the position of the table of contents, you cannot see it in the preview. (Maybe it can be done ...)
Therefore, the final specifications are as follows.
I will introduce the part where development was delayed due to a slight catch.
In JavaFX, the FileChooser
class is used to read and save files.
FileChooser fileChooser = new FileChooser();
File file = fileChooser.showOpenDialog(null);
The problem was the null passed to the argument on the second line, and when I displayed the app in full screen, it stopped responding and I had to kill it. Instead, pass the main Stage
as an argument. A sample that inherits the common Application class
public class Sample1 extends Application {
public static void main(String[] args) {
launch(args);
}
public void start(Stage primaryStage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader();
Parent root = fxmlLoader.load(getClass().getResourceAsStream("/sample1.fxml"));
primaryStage.setTitle("sample 1");
primaryStage.setScene(new Scene(root, 900, 600));
primaryStage.show();
}
}
But this
public class Sample2 extends Application {
static Stage stage;
public static void main(String[] args) {
launch(args);
}
public void start(Stage primaryStage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader();
stage = primaryStage;
Parent root = fxmlLoader.load(getClass().getResourceAsStream("/sample2.fxml"));
stage.setTitle("sample 2");
stage.setScene(new Scene(root, 900, 600));
stage.show();
}
}
Pass to FileChooser
as
FileChooser fileChooser = new FileChooser();
File file = fileChooser.showOpenDialog(Sample2.stage);
This way, even if you move the main window, the FileChooser
window will be attached.
For the Dialog
class
Dialog<ButtonType> dialog = new Dialog<>();
dialog.initOwner(Sample2.stage);
You can do the same with.
asciidoctorj makes the Ruby library asciidoctor available in Java. The string generated from this is poured into JavaFX's WebView
.
I didn't find many examples using asciidoctorj-diagram, so I will write it for reference.
Asciidoctor asciidoctor = org.asciidoctor.Asciidoctor.Factory.create();
After creating an instance with
asciidoctor.requireLibrary("asciidoctor-diagram");
Then you can use functions such as plantuml.
JavaFX WebView
can be loaded and displayed by the load
method or loadContent
method of WebEngine
. This time we'll load the raw HTML as a String
instead of a URL, so we'll use the loadContent
method. However, when I load the HTML with this method, it doesn't display the local image in the path of the src attribute. All I needed was to have the file protocol file: //
in mind. I used jsoup to solve this problem.
ArrayList<Element> src = document.getElementsByAttribute("src");
for (Element e : src) {
String attributeValue = e.attr("src");
if (!attributeValue.contains("data:") &&
!attributeValue.contains("https:") &&
!attributeValue.contains("file:")
) {
attributeValue = Paths.get(attributeValue).toUri().toString();
e.attr("src", attributeValue);
}
}
The file protocol is attached by the toUri
method.
When I click the link displayed in the WebView
of JavaFX, it is loaded by that WebView
, so I can't see the preview of AsciiDoc that I was originally looking at, albeit temporarily. To solve this, I opened it in the default browser.
//viewer is the fxml component of WebView for preview
viewer.getEngine().getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == Worker.State.SCHEDULED) {
String urlLocation = viewer.getEngine().getLocation();
if (urlLocation.contains("http:") || urlLocation.contains("https:")) {
viewer.getEngine().getLoadWorker().cancel();
try {
Desktop.getDesktop().browse(new URI(urlLocation));
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
}
}
}
});
Another problem was the inability to jump within the page for the a tag. This time
viewer.getEngine().setJavaScriptEnabled(true);
By doing so, I made JavaScript executable, added a script tag with jsoup, and loaded the script for the anchor link.
String anchorLinkScript =
"function anchorlink(id_name) {" +
"obj = document.getElementById(id_name);" +
"obj.scrollIntoView(true);" +
"}";
Element body = document.body();
body.appendElement("script").append(anchorLinkScript);
ArrayList<Element> elements = document.getElementsByTag("a");
for (Element e : elements) {
if (!(
e.attr("href").contains("http:") ||
e.attr("href").contains("https:")
)) {
String idName = e.attr("href").substring(1);
e.attr("onclick", "anchorlink(\'" + idName + "\')");
}
}
When I embedded Ace in JavaFX, the Japanese IM on Mac was buggy, so I solved it
I was able to implement some functions like this.
This time, it is converted every time you type a character, so if you use the asciidoctor-diagram function, a .png file will be generated every time you type a character. Moreover, I tried to give a file name to prevent it.
[plantuml, "sample"]
----
Bob->Alice: Hello
----
If you enter in order from the top, sample.png itself will change firmly every time you enter it, but WebView will only display the first generated sample.png (re-app It will be displayed when you start it, and the exported HTML will be loaded without any problem). I'm worried because I have no idea about this.
Another feature I wanted to include PDF output was.
Basically, I had a strong image that an app can be started by double-clicking the icon, so I aimed for that as well. Specifically, I wanted to distribute cross-platform apps by making full use of jlink, install4j, and badass-runtime-plugin. However, I felt that I would never be able to put out the deliverables in public unless I put them out as they are, so I gave up and released them. From Java 13, there may be a jpackage, so look forward to it!
I made this by myself without telling anyone, but after all, it took me four months to release it after creating the repository on GitHub. I made the repository after I thought about making the AsciiDoc editor, so it's been about 8 months since I started Java. Possible reason is
is. I always thought it would take a long time to code until I made this, but it took me several times longer to search for something I didn't understand and swallow it. Also, it was painful that no one was able to tell me how coding was customary in Java, spaghetti, or something that I wouldn't notice. Obviously, maintaining motivation is very important. This time there was a period of slack, and I didn't go as I expected, but I found that even small things can increase my motivation. I was happy every time I thought about small functions that AsciidocFX did not have, and since it was my first GUI, each one worked as expected.
Somehow, when I always do programming-related searches, I had a habit of coming to Qiita first. Qiita is easy because you can get the information you want to know quickly. However, if you want to make something from scratch, it may be important to look at the official documentation first. Since JavaFX 11 is no longer included in the JDK, I knew at first that there was a document Getting Started with JavaFX 11 for that. did not. It was very easy to understand (small average feeling). If I realized the greatness of the official reference a little earlier, I could have shortened the development period. After noticing it, I tried to look at the API documentation of the libraries that I use, including Java. If you have dozens of Firefox tabs open just in the official API docs, you're programming! !! I was excited to feel that. I think this also helped maintain motivation.
I challenged the first GUI in the language I touched for the first time. I wrote that it is difficult to do alone, but there is a good sense of accomplishment (I think that if you are not alone, you can share the sense of accomplishment, so I do not know which one).
If you're just starting out programming, like me, who read this, I recommend that you do some preliminary research before getting started in programming languages (which may be obvious ...). From the beginning of implementation, I think that you will be coding while researching, but it will surely be fun because you will find that the technology will be much better than reading the introductory book and writing examples. Eliminate your resistance to English and read the official docs, Stackoverflow, etc. (because Stackoverflow sometimes has strong people like crap).
And for the senior programmer who happened to see it to the end, I may not have written anything that would be helpful. If you are kind, please take a look at GitHub and encourage me to say "This source code is Akan !!". Also, such a language and library are interesting! Or, I wish I had read this before starting development ... I hope you can tell me an article like that (beggar).
When I read it back, it looks like "What number decoction and Nen", but thank you for reading to the end.
Recommended Posts