
Hiking, permaculture, software engineering, shogi, TTRPG, and writing take up my time. Hope you enjoy the site! (more…)
Hiking, permaculture, software engineering, shogi, TTRPG, and writing take up my time. Hope you enjoy the site! (more…)
(See my full list of Clojure Swing examples and tutorials at Clojure Swing Interop)
When developing Swing GUIs for Clojure, understanding and using SwingUtilities/invokeLater is crucial.
Don’t confuse “thread” in this case with Clojure threading macros such as -> and —> . Threading here refers to concurrency.
Swing GUI components are not safe to access concurrently. If two threads modify the same Swing component at the same time, the result is unpredictable. Java solved this problem by introducing the event dispatch thread. All modification Swing displays and component values should happen on the event dispatch thread.
There is only one event dispatch thread. You access it by creating a Java Runnable and passing it to SwingUtilities/invokeLater . Lucky for us, all Clojure functions are Java Runnables. Here’s the general format.
1 2 3 4 5 6 |
(defn my-gui-modifier [] ;; Do some Swing changes here ) (defn modit [] (SwingUtilities/invokeLater my-gui-modifier)) |
Remember, ALL the screen rendering and modifications to your Swing components happen on the event dispatch thread. That means, if you tie up the event dispatch thread doing something time consuming, your app will appear to hang. This creates a horrible user experience. Any runnables you create should complete quickly.
On a somewhat related note, any time a Swing component alerts you to an event or a value change, you will want to hand back that thread immediately and use a new thread to do any long tasks associated with the notifications.
(See my full list of Clojure Swing examples and tutorials at Clojure Swing Interop)
Here’s a really brief example for building a Java Swing app using Clojure.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
(ns myswingproject.core (:import [javax.swing SwingUtilities JFrame JLabel])) (defn create-and-show-gui [] (let [my-frame (doto (JFrame. “My Frame”) (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)) my-label (JLabel. “Hello UI”) content-pane (.getContentPane my-frame)] (.add content-pane my-label) (.pack my-frame) (.setVisible my-frame true))) (defn gui [] (SwingUtilities/invokeLater create-and-show-gui)) (gui) |
Sometimes you want a pure Clojure server with a React web client. It is best if you create a new one instead of using other people’s templates, because you can also get the newest libraries, frameworks, and security fixes at the same time. If you are determined to get going now with a Clojure / React JS server, grab the latest copy from https://github.com/TGeneDavis/clojure-server-with-reactjs-template on GitHub. (more…)
These days, many apps default to use of a web interface for their user interfaces. Sometimes you just want a traditional graphic user interface (GUI) with your Clojure code without the hassle of creating a full blown web app. A lot can be said for double clicking an uberjar and seeing an appealing desktop app spring to life.
Those developing on vanilla Clojure running on the JVM have three main desktop options for GUI development: AWT, Swing, and JavaFX. AWT is considered to be an old tech with too many issues for standard development. JavaFX on the other hand is wonderful for huge projects managed by teams of dedicated developers, but a lot of work for little return when used on small projects. Swing still stands strong as the best choice for small projects that need a mature tool for GUI work.
Here are my collection of posts explaining Java Swing interop with Clojure.
Quick Clojure GUI example using Swing
This is a barebones example for getting Swing up and going. It’s nice if you just want to get a “Hello World” with a GUI running.
Event Dispatch and Invoke Later
The first concept needed for successful Clojure Swing programming is an understanding of the event dispatch thread.
Clojure Swing JFrame Introduction
Clojure Swing JFrame example using JLabels and a BorderLayout.
Clojure JButton and ActionListener Example
Clojure Swing JButton using an ActionListener to print a simple message to the console.
Full Sample Clojure Swing Temperature Conversion App
Sometimes, you just need an actual code sample in a real app to see how to put together your own apps correctly. This Clojure Swing app demonstrated JLabel s, JTextField s, the event dispatch thread, ActionListener s, JFrame s and FlowLayout s.
Here’s how you integrate JOptionPane s into your Clojure program. You can have message dialogs, even if you don’t want a windowed application with a JFrame .
JFileChooser example to choose a file to slurp and print in Clojure.
Redis works great with Clojure when you use the Carmine API.
Some of the features of Redis could be duplicated in your app, or are features that exist in the Clojure APIs. So, knowing when to use Clojure and when to use Redis is important. Use Redis when there is a chance that multiple servers may need access to the same messaging, session, or cached data. Also, use Redis anywhere you need an extremely fast-and-simple drop-in replacement for a database.
Note: These tutorials are to help get you started, but not considered final production grade code. Redis, like any database, should NEVER be exposed directly to Internet traffic.
Introduction to Redis with Clojure integrated as the client.
This is basic session and caching management tutorial. Globally accessible data should go in a Redis key-value store.
Clojure Redis Pub/Sub with Carmine
Redis Pub/Sub for messaging between servers or namespaces. Helps prevent circle reference issues, and communications issues between namespaces and servers.
Most of my books are computer programming books, but I really like my Tsume Puzzles book. I am thinking of doing another one eventually.
Here’s the Amazon book blurb.
Centuries before sudoku, crossword puzzles, or word searches challenged Western minds, Japanese military and royalty were creating and enjoying tsume puzzles. Tsume puzzles are mating puzzles for shogi (Japanese chess.) Shogi’s history dates back 1000 years with archeological evidence that shogi existed in Japan at least by the 11th century. Some of the greatest know tsume puzzle books date back several centuries. Tsume puzzles have a long and honored tradition. Tsume are widely recognized to improve shogi skills. Tsume are also fun puzzles that anyone can enjoy. Whether your interest is in improving your shogi game, or just solving puzzles, this book provides many hours of entertaining shogi riddles. In this book you will find: * A complete introduction with rules of tsume puzzles and shogi rules that apply * Over 200 tsume puzzles of varying difficulty * Puzzles ranging from one move to thirteen moves * Solutions * Explanatory notes to many solutions * A quick reference section for those new to tsume and shogi
I finally received my Permaculture Design Certificate. I did 150 hours of course work, read the entire manual of 500 pages of small print, and listened to the entire 80 hours of Bill Mollison’s version of the class from 30 years ago, … before doing my final design and passing the class.
Permaculture? Is it swales? What on earth is a swale?
Swales are a dry-climate, tree-growing system. Permaculture may use swales, but that is a small, small part of permaculture.
Permaculture is often described as “Permanent Agriculture.” However, Permaculture is better described as “Permanent Culture.” That includes:
Permaculture transcends politics, religion, and country. You can throw a prepper, a tree hugger, a Muslim, a Buddhist, a capitalist, and a communist into the same permaculture class and have them all walk away determined to use the knowledge they gained in their individual pursuits. In fact, I’ve seen that happen.
Need Solidity based smart contracts for the Ethereum blockchain? Then you’re at the right place. Solidity based smart contracts are the next disruptive technology for the 21st century.
By now, everyone has heard of Bitcoin. The longstanding second most popular cryptocurrency is Ethereum. However, the difference between Bitcoin and Ethereum is like the difference between paper dollars and gold. Paper dollars have no value, except good faith. Gold has uses in industry and science in addition to being tradable as money.
Ethereum is like gold. You can trade Ethereum as a cryptocurrency, and many do. However, you can also use the Ethereum blockchain to create unstoppable, uncensorable, massively distributed applications. The Ethereum blockchain can host applications and data, making it the next big disruptive technology.
Imagine if you could have got in on the ground level of social media, search engines or even the Internet. The next huge disruptive tech is sitting out there. It is the Ethereum blockchain.
Solidity based smart contracts allow for the development of publicly verifiable information. You can place keys on the blockchain proving authenticity of everything from land titles to certifications and diplomas. Using blockchain apps made with solidity, you can set publicly verifiable contracts up, or set payments or information to be released at some future date.
The first rule taught in software development is, “Comment your code with a reason or purpose for its existence.” This is to say, “Why does this variable, method, or class exist?”
Here’s why.
Heavily used code always suffers from purpose creep. Purpose creep leads to expensive bugs. For example, I once found a bug in code used by hundreds of corporate customers that consisted of a variable being used for two purposes. Most of the time, the variable value was the same value for both purposes. However, after selling the software for many millions of dollars to 100’s of clients that expected to never change their integrations with our code, we had a problem that required new installations and new integrations.
Talk about a preventable problem. One comment explaining the purpose of one variable could have saved the company millions of dollars worth of angry customers.
To prevent purpose creep within a class, method, or variable, stick with the purpose described in the comment, or change the comment. It’s very easy for a maintainer of old code to assume the purpose of a well named variable, but not realize the actual purpose is similar, but not the same as he thinks it is.
The first rule of programming that is thrown out the door in the workplace is, “Comment your code.” Even at the better companies I’ve worked for, almost no one comments their code. Some developers live in a fantasy world where class names, method names and variable names give all the architectural details needed to understand millions of lines of code. I once ran into a 45,000 line class with no comments. I even worked for a company that forbade comments, and you could get called in for a talk with your manager if you made the mistake of leaving a comment in your code–very Dilbertesque.
Every codebase has blocks of code that are so important that they are called constantly. And when an edge case is found, those blocks of code get a conditional thrown in to handle that edge case. Then another edge case is found and a new parameter is passed in to handle that edge case. Another developer under tight deadlines realizes the code is perfect except, it needs to handle his case where ….
As a result, almost every important method and class suffers quickly from purpose creep. By this I mean that if you found someone that actually understands the class or method in question, it will take minutes and sometimes hours for them to describe what is going on in the class or method.
Soon, the most important code in your application is too fragile to change. Ten or twenty edge cases that no one remembers have infiltrated your most important code. And worse yet, there are no comments explaining what can brake if even a minor change happens to your code. Then a maintainer of the code gets stuck working nights and weekends making changes to once simple software.
Detailed commenting of important code helps prevent fragile code. Have a concise explanation of purpose of your code. If the comments are getting hard to follow, then it is time to refactor the code into easily described chunks. Maybe move those edge cases out into their own methods or classes.
Comments containing clear purpose statements can prevent working late nights, lost customers, and even save your company millions of dollars. There’s a lot to be said about the lowly comment.
If you’ve reached Java 9 or above, you’ll notice at some point that the Java’s Object.finalize() method is deprecated. A quick look at the JavaDocs doesn’t give any easy solutions for a quick replacement. (Good luck with PhantomReferences, btw.)
So here’s a drop-in replacement that should have been documented, but I haven’t seen anyone mention this on Stack or anywhere else. Use a cleaner. If what you’re doing is simply destroying references, or something else similar, put the following code in your Java class constructor and copy the guts of finalize() into it. Then delete your old finalize() method.
1 |
Cleaner.<em>create</em>().register(this, () –>{<br> //Put your cleanup code here.<br>});<br> |
Now you’re Java 9 compliant.
What you’re doing with this code change is creating a Runnable that is called when the Cleaner detects that your Object is in need of cleanup.
If you want to get really fancy, create only one cleaner and reference that one cleaner to register your objects during construction. That’s probably what you’ll do in any app that has a lot of objects that need cleaning up.
Here’s some code to make it a bit more clear how to use a Java Cleaner to replace a finalize() method.
First the CleanersExample class:
1 |
package com.terrancedavis;<br><br>import java.lang.ref.Cleaner;<br>import java.util.concurrent.atomic.AtomicInteger;<br><br>public class CleanersExample<br>{<br> private static AtomicInteger <em>instanceCount </em>= new AtomicInteger(0);<br><br> public CleanersExample()<br> {<br><br> Cleaner.<em>create</em>().register(this, () –>{<br> System.<em>out</em>.println(<br> “Current instance count is “+<br> <em>instanceCount</em>.decrementAndGet()<br> );<br> });<br><br> System.<em>out</em>.println(<br> “Current instance count is “+<br> <em>instanceCount</em>.incrementAndGet()<br> );<br> }<br><br> public void sayHi()<br> {<br> System.<em>out</em>.println(“Hi!”);<br> }<br>}<br> |
Next the Main class to use the CleanersExample class:
1 |
import com.terrancedavis.CleanersExample;<br><br>public class Main<br>{<br><br> public static void main(String[] args)<br> {<br> new Main().usingSomeObjects();<br><br> System.<em>gc</em>();<br> try<br> {<br> Thread.<em>sleep</em>(5000);<br> }<br> catch (Exception e)<br> {<br> }<br><br> System.<em>out</em>.println(“All done!”);<br> }<br><br> private void usingSomeObjects()<br> {<br> CleanersExample ce1 = new CleanersExample();<br> CleanersExample ce2 = new CleanersExample();<br><br> ce1.sayHi();<br> ce2.sayHi();<br> }<br>} |
The output will look something like this.
Current instance count is 1
Current instance count is 2
Hi!
Hi!
Current instance count is 1
Current instance count is 0
All done!