The Swing tutorial for the JTextPane and demo code is good and comprehensive, covering multiple ways to interact with the the StyledDocument and add Styles. So, without repeating all of that, here’s a minimal example including only simple style changes on the insert update and selection events.
In the first snippet below, the implementation for the insertUpdate event is shown. For each typed character or pasted text, the entire text of the document will be searched for the word “foo”. For each occurrence, the bold attribute is set for that word. Notice that the update of the attribute happens on a separate AWT thread.
The other functionality of this small application is on select. If the selected word is “bar”, it is set to italic. Notice the dot and mark positions, which might be at the start or the end of the selection. Furthermore, notice that here the predefined ItalicAction from the StyledEditorKit is used, since we’re dealing with a selection. We just have to translate the CaretEvent into an ActionEvent, or rather just make sure to forward the source component of the selection. (The alternative would have been to go with the plain update as in the example above).
Here’s the full file listing, as a stand-alone application.
There are many ways to add line numbers to the JEditorPane and JTextPane Swing components. This post looks at two solutions: One providing a custom ParagraphView which paints a child element that contains the line number for that paragraph. The other implements a separate component which is passed as the RowHeaderView of the JScrollPane. Both support scrolling and line wrapping, and in this example the latter includes current line highlighting, as seen in the image below.
The ParagraphView solution is inspired by Stanislav Lapitsky’s old post on the topic, although with some improvements. The basic idea is to paint the line number in the child of the ParagraphView, using the paintChild() method. The advantage is that the relationship between the line and the line number is already established, so alignment is easy. We just have to count which element we’re dealing with to know which number to print. The two methods below show this part. Notice also that only the index 0 of the ParagraphView should be used for the line number, so we don’t count a wrapped line twice. Furthermore, a mono-spaced font helps with padding and alignment.
In order to create this custom ParagraphView, it has to be returned through a ViewFactory, which again has to be provided through an EditorKit. The file below shows the full implementation. Notice how the default ViewFactory is used for all other elements; only the Paragraph Element gets a custom view.
The second solution renders the line numbers in a completely separate component, which can be a JComponent (or even an old style AWT Component). This component is passed in to the setRowHeaderView() method of JScrollPane. That way, the coupling becomes a bit cleaner than overriding multiple classes and methods as with the the ParagraphView solution. However, the down-side is that we must do the alignment with the Editor component manually. Luckily, the Swing Text Component API provides a solid API for this purpose.
The code below is inspired by Rob Camick’s article, but simplifies several aspects of his stand-alone API style class. At the centre is the translation between the Document model and its onscreen view. The viewToModel() method translates an x,y point on the screen to the nearest character offset, while the modelToView() method goes the other way. That way we can align the line number at the same y point as the line in the editor. In Camick’s code, he loops through the text by character offsets rather than paragraphs; the getRowEnd() method helps by finding the end of a line. Camick also points out the the line number should take the font decent of the editor font into account when positioning the line number. The FontMetrics class helps with measuring sizes of fonts.
Finally worth noting is the synchronisation between the editor and the margin component. Since they are separate, this must be handled through event listeners registered with the editor component. The DocumentListener and ComponentListener notifies of edit, movement and resizing events, while the CaretListener signals movement in the cursor position. All of these events force a repaint, but through a scheduled AWT thread, to make sure the editor view has updated first, as seen in the documentChanged() method at the bottom of the code section below.
Here are the full code listings for both examples, as stand-alone applications.
Following the previous post about a HTTP server based on the Simple Framework library, here’s the Websocket use case. The example gets a bit more complicated with both a HTTP handler, Websocket handler and client, but still a lot simpler than the original example code.
Two interfaces have to be implemented to have a meaningful Websocket server: First, the Service interface, which gets invoked when a new connection and Session is established. From here it is possible to register a FrameListener on the session channel, which is the second interface to implement. The FrameListener methods will get invoked when new Frames, whether it is data or control codes is received. This listener also gets notified about errors and when the session or socket is closed. Two minimal examples of these implementations are shown below, followed by the setup() method which ties it all together and starts the server. Notice how RouterContainer takes both the HTTP and Websocket handlers, and routes the incoming requests appropriately.
To test the core functionality of the Websocket server, a bit more is needed on the client side. First, a HTTP like handshake has to be requested and the response read, then the client must respond to ping control frames, and finally, it can send frames of data itself.
Below is the method which sends the handshake to the server as specified in the Websocket RFC 6455. There’s a few things to note: Currently, details like target path, the host, origin are hard-coded. In a normal client, they should be resolved and set in a proper way. The security key is also hard-coded, but should be generated according to the specification. Finally, note that the line ending has to be “\r\n” or 0xd, 0xa in hex. Therefore, when using a PrintWriter to wrap the raw OutputStream, be careful not to use the println() methods as they might append the incorrect line termination.
What’s useful about a minimal test client like this, is that’s it becomes easy to try out these kind of details in isolation, without distractions from other functionality. Although this example does not go as far as asserting the behaviour, it could easily be extended to an in-memory integration test of the server.
Finally, this test method ties the client together: it first opens the socket connection to the server; gets the IO streams; sends and receives the handshake; starts the ping response handler on a separate thread; sends one frame of its own with a ping, waits for some seconds to observe the server in operation, and finally sends a close operation code before closing the connection.
Here’s the full test case listing, which also includes a HTTP request test. A dependency on the Simple Framework library is needed, for example through the Gradle dependency:
A while back, I ranted about the Simple Framework example code and its unnecessary complexity. It turns out that their HTTP server library is indeed simple, if you just ignore the Spring setup and their example. In fact, as this static file server example shows, it’s very similar to the “hidden” Sun HTTP handler API.
The only interface which has to be implemented is the Container, which is equivalent to the request HttpHandler in the Sun HTTP library. The handle() method takes a normal HTTP request, and the response code and data can be written via the Response object. The first code block below shows a simple handler.
The next block shows how to tie the required Simple Framework classes together to start the server. The Container just mentioned goes into a ContainerSocketProcessor where concurrent processing can be setup up. The processor goes into a SocketConnection which connects to a socket on a given host and port, and the server runs.
Here is the full server example, started and verified as a unit test.
Metrics is a minimal library for various server monitoring metrics, and easy reporting. Supported metrics include rate meters; instant gauges; counters; histograms; timers. Furthermore, various reporting formatting is included. See their Getting started page for more details.
It’s available on Maven Central, so the following Gradle config will include the latest 3.1.0 version.
The simplified tests in the code below will output this report.
Some metrics examples:
When generating a Map, the basis is very often a list of unique elements (i.e. a Set), and often the original elements take part in the new Map, either as keys or values. When the original elements are keys, we might be talking about a cache, where the key is the pointer and the value is the result of some expensive operation. E.g. the key is a filename and the value is the bytes of the file loaded into memory for fast serving. Conversely, when the original elements are values of the new map, we’re often dealing with a look-up table, e.g. from an ID to its User object, or as in the previous article from a short-form string to a specific class reference.
Streams iterating over collections, and lambda functions take some of the dull boilerplate out of creating these kind of maps. However, some of the helper classes, like Collectors, come with rather long method names. To take away even these parts, here are a few helper methods for the identity maps. They come in two forms: One which returns a Collector which can be used in the collect() method of the Stream. Typically, this is useful if other operations, like filtering, is also used. The other helper methods operate directly on the Collection, and take only the mapping function for keys or values. See the full file for further examples and documentation below.
The full code listing, with examples and documentation. This code is under GPL3.
In the last post I ranted about dependency injection framework magic, but even custom magic can cause problems. When objects are constructed and invoked through reflection, the execution flow is no longer apparent in the code. Yet, it still has its place in certain applications, typically mapping external input to object instances, be it language parsing or lexing, or DB output to object mapping. But how to best balance between the abstract world of reflected classes and concrete type-safe code?
The key lies in simplicity, and imposing certain constrains. Dynamically resolving classes and recursive reflective construction of a full object a hierarchy is probably not a good idea. Furthermore, as discussed previously, Java 8 method references now makes it cleaner to pass in factory methods, and avoid the Factory Factory Factory trap.
The following snippet shows the reflective construction of an object, given a few constraints: First off, the name of the input token can be mapped to typed classes. In this example that is done with a generated String to Class map, based on the concrete class references we’re dealing with. They have to be available at compile time, and at the time of writing the code. The advantage is that we avoid the Class.forName() look-up, and the package hierarchy confusion and possible mismatch of tokens and classes. If this is too strict, we can modify the map, e.g. by allowing for case-insensitive matching (by converting both map key and look-up to the same case). Or if there is not a literal mapping, an enum could define the relationship. Either way, the idea is that the code make it clear which classes we plan to deal with, in strongly typed manner.
The next assumption in this example is that the class to be created has only one constructor method, and that it is public. Or if that is not feasible, the constructor to be used could be marked with an Annotation. Just don’t go full-on Guice, and you’ll be fine.
Finally, we assume that the relevant constructor takes zero or more parameters, and if it does have parameters that they can themselves we represented and created from a single String object. These parameter objects are initialized in a helper method, discussed below.
The construction of the parameter classes also contains several assumptions and restrictions. As with the first order classes, we limit ourselves to a pre-defined set of classes. This make it possible to define which constructor or factory methods should be used. In this example, the constructor which takes a single String is used, except for the Password class, where a factory method is used, again taking a single String.
That is all it takes to construct objects through reflection, including its parameter types. The examples above maintain some type-safety, and also restricts the supported types. Finally, some error handling and messaging is in place, and more could be added to make it very clear which classes and input is allowed.
The full code listing below shows the example classes to be constructed and test code to verify them.
As mentioned in the previous post, the SimpleFramework API and server is a minimal alternative in the world of Java application servers like Glassfish, Tomcat. Hosted on GitHub under an Apache v2.0 license, they offer an embeddable HTTP, Servlet and WebSocket capable stack and API. They claim their performance is better than other Java based web servers.
The Dependency Injection Framework Trap
Whether they live up to their name, and is truly easy and simple to use is somewhat debatable, though. They favour Spring for dependency injection, which means part of the code is specified in XML, and is “magically” coupled during runtime. There might be benefits to that, but the downside is that it becomes difficult to read and debug. In fact, their demo application will not start for whatever reason, and all that is offered in terms of output is an InvalidArgumentException without further details deep down from the Spring code.
Don’t get me wrong, the Google Guice framework is not much better. It might specify its module coupling in Java code instead of XML, however, when it comes to following the code and debugging, it is just as obscure. Implementations tend to be hidden behind layers of interfaces. As for the promise of easily re-wireable code, they both fall short. When it comes down to it, a refactoring will typically involve changes in both class content and class relationships, so a dependency injection framework is more likely to get in the way than help.
Finally, when it comes to testability, dependency injection is of course crucial. Being able to inject mocks or other testing objects keeps unit tests small. However, a wiring framework is not needed to describe the class relationships. In fact, my personal experience is that Guice based code is more cumbersome to use in test related code. It takes considerable effort to track down which classes to include in a unit test, and which to leave out, and then to create a test module of it all. At least Spring leaves the class constructors intact and simple.
Making it work
So, with that rant out of the way, what does it take to make the Simple Framework WebSocket Chat Demo work? My solution was to simply shortcut the 114 line XML Spring configuration, and write the same class relations in Java. The following 20 lines achieves the same as the XML.
Furthermore, it’s worth noting that the SimpleFramework is structured in multiple Maven projects, with dependencies between each other, as seen below the code snippet. It highlights another potential problem with the project. A lot of the server code required to make the Chat demo run is in another demo package. It suggest quite a lot of custom code has to be written to use the server API.
The GitHub Maven packages and dependencies at the time of writing:
It is not entirely clear whether the last demo example, “simple-demo-rest”, depends on the “simple-chat” project as the XML suggests, or whether the duplicate ChatRoom class was intended to be used. It might be that the XML was copied, but not updated - highlighting the previous point about hard to maintain and read dependency injection code.
Focusing only on the “simple-demo-chat” example then, this would be what it could look like in the Eclipse Package Explorer, with each directory created as a separate Java project.
Finally, here’s the full main-file hack to make the chat example work. Notice the required helper classes from demo packages.