Cross-Platform Swing GUI App Example

Swing is an old GUI framework that is still useful and competitive by 2024 standards. It comes with Java so no extra installation is needed. Downside is that you can only target desktop platforms, with no web or mobile support, unlike JavaFX. It has a lot of widgets with capabilities to create your own custom ones.

Enough intro. Here is a simple, cross-platform Swing GUI app example that does not look horribly outdated (ie. not Metal). It uses Nimbus look & feel (which is easily customizable) and works with Java 11+. Screenshots (scaled to same resolution):

Java 17, MacOS

Java 11, Manjaro

The results are respectably similar, with some differences in line height. You can compile the below source with:

javac -g:none Chat.java
jar cvfe Chat.jar Chat Chat*.class
rm Chat*.class

Double-clicking the jar file should open the app, and it is less than 3200 bytes on either platform. Chat.java file:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;

class Chat {
    public static void changeFontSize(int delta) {
        var def = UIManager.getLookAndFeelDefaults();
        for (var key : def.keySet()) {
            try {
                var fr = (FontUIResource) def.get(key);
                var nf = new FontUIResource(fr.getName(),
                    fr.getStyle(), fr.getSize() + delta);
                def.put(key, nf);
            } catch (ClassCastException ex) {}
        }
    }

    public static void main(String args[]) {
        try {
            UIManager.setLookAndFeel(new NimbusLookAndFeel());
        } catch (UnsupportedLookAndFeelException ex) {
            System.err.println(ex.toString());
            return;
        }
        changeFontSize(3);

        // Creating the Frame
        var frame = new JFrame("Chat App");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setMinimumSize(new Dimension(650, 400));
        frame.setLocationRelativeTo(null); // screen center

        // Creating the MenuBar and adding menus
        var menus = new JMenuBar();
        var file = new JMenu("File");
        var open = new JMenuItem("Open");
        var save = new JMenuItem("Save");
        file.add(open);
        file.add(save);
        var help = new JMenu("Help");
        var about = new JMenuItem("About");
        help.add(about);
        menus.add(file);
        menus.add(help);

        about.addActionListener(ae -> {
            JOptionPane.showMessageDialog(frame, "Chat v0.1",
                "About", JOptionPane.INFORMATION_MESSAGE);
        });

        // Creating the panel at bottom and adding widgets
        var panel = new JPanel(false); // single-buffered, not visible
        var label = new JLabel("Enter Text");
        var msgBox = new JTextField(20);
        var send = new JButton("Send");
        var reset = new JButton("Reset");
        panel.add(label); // Components Added using Flow Layout
        panel.add(msgBox);
        panel.add(send);
        panel.add(reset);

        // Text Area at the center
        var text = new JTextArea();
        var scroll = new JScrollPane(text);

        msgBox.addKeyListener(new KeyAdapter() {
            @Override
            public void keyTyped(KeyEvent ke) {
                if (ke.getKeyChar() == '\n') { // send when pressed enter
                    send.doClick();
                }
            }
        });
        send.addActionListener(ae -> {
            var msg = msgBox.getText();
            if (msg != null && msg.length() > 0) {
                text.append(msg + "\n");
                msgBox.setText(null);
            }
        });
        reset.addActionListener(ae -> {
            text.setText(null);
        });

        // Adding Components to the frame.
        frame.add(scroll, BorderLayout.CENTER);
        frame.add(panel, BorderLayout.SOUTH);
        frame.add(menus, BorderLayout.NORTH);
        frame.setVisible(true);
    }
}

Efficient Fences

Farmers and Fences

Think of a farmer enclosing her piece of land with a fence. She is considering square and circle as possible shapes for her land: She wants to save money, of course, on fence building expenses. She comes up with a scale-independent metric to compare these shapes, enclosing efficiency: $$2\sqrt{\pi A}\over F$$ where \(F\) is the length of the fence used and \(A\) is the area of the enclosed region. Higher enclosing efficiency means enclosing more area with less fence. Square and Circle's enclosing efficiencies are 0.8862 and 1 respectively. The latter is known to be the best efficiency by a lone shape.

Cooperating Farmers

What if there are multiple farmers willing to cooperate. If four farmers agree to become land neigbors and share borders, they could for instance build fences like: Each farmer will achieve an efficiency of 1.182 (why?), beating a single Circle's efficiency.

Farmers could go further and use infinite square or regular hexagon grids, which will achieve 1.772 and 1.905 respectively. The downside to these infinite grids is that everyone is surrounded by private property. You with your tractor (having positive width) have to cross other people's land to reach your land. You do not have free access to your land.

Freedom

Let's first define freedom as the proportion of the whole plane from which you can access your land with your tractor. Infinite square/hexagon grids covering whole plane will yield freedom=0. Here is a horizontal infinite grid separating upper/lower half planes with freedom=0.5, that is, each farmer has free access to half of the plane: This configuration yields an enclosing efficiency of 1.418, expectedly better than four farmers above and worse than infinite square/hexagon grids.

What is the Best?

So, what should a finite number of farmers do if they all require freedom=1, that is, free access to the whole plane? Let's start small with just two farmers. Here is a configuration where the two can achieve 1.115: So here are some questions (I think I can answer the first five):
  1. Can you find out the geometry of the two farmer configuration ?
  2. What is the optimal (finite) number of farmers with freedom=1 ?
  3. What is the enclosing efficiency of the optimal farmers with freedom=1 ?
  4. What is the geometry of the optimal farmers with freedom=1 ?
  5. What is the geometry with efficiency=1.504 and freedom=0.5 ?
  6. Is 1.504 the best efficiency for freedom=0.5 ?
  7. Is 1.905 the best overall efficiency ?
  8. What are all the possible freedoms when each farmer must have the same efficiency ?
  9. In general, what are the best efficiencies for all possible freedoms ?

Most Efficient Bucket

A bucket is a truncated cone (also called frustum of a cone or a conic bowl) with open top to store stuff (mostly liquids) in it: Given constant area (side+base), what is the bucket geometry that yields maximum volume?

Let's find out by first defining some variables:
\(q:\) radius of the top, open side
\(r:\) radius of the base
\(h:\) height of the bucket
Then volume and area respectively are: $$V={\pi\over 3}h(q^2+qr+r^2)$$ $$A=\pi[(q+r)\sqrt{h^2+(q-r)^2}+r^2]$$ We can discard the constants since we want to maximize \(V\) for constant \(A\). From the second we can extract: $$h^2=\left({A-r^2\over q+r}\right)^2-(q-r)^2$$ which can be substituted into: $$W=V^2=h^2(q^2+qr+r^2)^2$$ \(W\) is a rational polynomial expression in variables \(q\) and \(r\), so it can be maximized instead of \(V\). Simplifying \(\partial W/\partial q=0\) with WolframAlpha yields: $$(q + 2 r) (2 A r^2 + 3 q^4 - A^2) = 2 r^3 (3 q^2 + 2 q r + r^2)$$ Similarly simplifying \(\partial W/\partial r=0\) yields: $$A (2 q + r) = r (q + 2 r) (3 q + 2 r)$$ Solving both for \(A, q\) (and bringing constants back) yields: $$q={1+\sqrt 7\over 2}r \approx 1.823 r$$ $$h=\root 4\of{7} r \approx 1.627 r$$ $$A=\pi(7/2+\sqrt 7)r^2 \approx 19.31 r^2$$ $$V={\pi\over 3}\root 4\of{7}(7/2+\sqrt 7)r^3 \approx 10.47 r^3$$ Note that side length (also called slant) is also \(q\), and \(V=A h/3\). There is another nice property of this optimal bucket, can you see it?

Having golden ratio not winning this time, here is a model for your 3D printer.
Also there is an article with nice colorful plots showing the unique maxima.