Simple message bus: Java and AWT

This is the Java and AWT implementation of the message bus program. The principles of the message bus are described in the main message bus article. Do read that article first.

Java has its own abstraction for sockets. Each Worker is a separate thread. That would be expensive it there were hundreds of clients, but in this small example it does not matter.

AWP is Java’s GUI library, the Abstract Window Toolkit.

The source code

// -*- coding: us-ascii-unix -*-
import java.awt.      Button;
import java.awt.      Color;
import java.awt.      Dimension;
import java.awt.      Graphics;
import java.awt.      FlowLayout;

import javax.swing.   WindowConstants;

import java.io.       BufferedReader;
import java.io.       BufferedWriter;
import java.io.       InputStream;
import java.io.       InputStreamReader;
import java.io.       OutputStream;
import java.io.       OutputStreamWriter;
import java.io.       Reader;

import java.net.      ServerSocket;
import java.net.      Socket;

import java.util.     AbstractMap;
import java.util.     HashMap;
import java.util.     Vector;

//---------------------------------------------------------------------------------------- Server
class Server extends Thread {
    private ServerSocket _daemon_sock;

    Server() throws java.io.IOException {
        _daemon_sock = new ServerSocket(4711);
    }

    public void run() {
        try {
            while (true) {
                Socket new_server_sock = _daemon_sock.accept();
                new Worker(new_server_sock).start();
            }
        }
        catch (Exception e) { e.printStackTrace(); System.exit(1); }
    }
};

//---------------------------------------------------------------------------------------- Worker
class Worker extends Thread {
    static Vector<Worker> _workers = new Vector<Worker>(10);

    Worker(Socket sock) {
        try {
            var writer = new OutputStreamWriter(sock.getOutputStream());
            _out       = new BufferedWriter(writer);
            _sock      = sock;
            _out.write("" + Gui.instance.current_colour + "\n");
            _out.flush();
            _workers.add(this);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    public void run() {
        try {
            InputStream    is   = _sock.getInputStream();
            Reader         isr  = new InputStreamReader(is );
            BufferedReader in   = new BufferedReader   (isr);
            Vector<Worker> dead = new Vector<Worker>   (10 );
            String         line;
            while (null != (line = in.readLine())) {
                System.out.format("Server received [%s]\n", line);
                line += "\n";
                for (Worker w : _workers) {
                    try {
                        w._out.write(line);
                        w._out.flush();
                    } catch (Exception e) {
                        dead.add(w);
                    }
                }
                for (Worker w : dead)
                    _workers.remove(w);
                dead.clear();
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    private Socket         _sock;
    private BufferedWriter _out;
}

//---------------------------------------------------------------------------------------- Client
class Client extends Thread {
    static Client instance;

    Client() throws Exception {
        _sock    = new Socket("localhost", 4711);
        _writer  = new OutputStreamWriter(_sock.getOutputStream());
        instance = this;
    }

    void notify_server(String colour) {
        System.out.format("Notifying server: colour is %s\n", colour);
        String line = colour + "\n";
        try { _writer.write(line, 0, line.length()); _writer.flush(); }
        catch (Exception e) { e.printStackTrace(); System.exit(1); }
    }

    public void run() {
        try {
            System.out.format("Client::run: Reading\n");
            var is = _sock.getInputStream();
            var in = new BufferedReader(new InputStreamReader(is));
            String line;
            while (null != (line = in.readLine())) {
                Gui.instance.on_incoming_message(line.trim());
            }
        }
        catch (Exception e) { e.printStackTrace(); System.exit(1); }
    }
    private Socket             _sock;
    private OutputStreamWriter _writer;
}

//---------------------------------------------------------------------------------------- GUI
class Gui extends javax.swing.JFrame implements java.awt.event.ActionListener {
    ;      int current_colour;
    static Gui instance;

    Gui() {
        setLayout(new FlowLayout());
        setVisible(true);
        setTitle("Java and AWT");
        add("West", red  );
        add("West", green);
        add("West", blue );
        set_colour(GREEN);
        instance = this;
    }

    private Button btn(String text, int value) {
        Button rval = new Button(text);
        rval.setName("" + value  );
        rval.addActionListener(this);
        rval.setPreferredSize(new Dimension(100, 30));
        return rval;
    }

    public void on_incoming_message(String message) {
        int new_colour = Integer.parseInt(message);
        System.out.format("New colour is %d\n", new_colour);
        set_colour(new_colour);
    }

    @Override
    public void actionPerformed(java.awt.event.ActionEvent e) {
        var b = (Button)e.getSource();
        Client.instance.notify_server(b.getName());
    }

    public void set_colour(int colour) {
        current_colour = colour;
        red  .setBackground(RED   == colour ? new Color(255, 112, 112) : Color.WHITE);
        green.setBackground(GREEN == colour ? new Color(112, 255, 112) : Color.WHITE);
        blue .setBackground(BLUE  == colour ? new Color(112, 112, 255) : Color.WHITE);
    }

    private final int    RED   = 1001;
    private final int    GREEN = 1002;
    private final int    BLUE  = 1003;
    private       Button red   = btn("Red",   RED  );
    private       Button green = btn("Green", GREEN);
    private       Button blue  = btn("Blue",  BLUE );

}

//---------------------------------------------------------------------------------------- main
class redgreenblue {
    public static void main(String[] args) throws Exception {
        try {
            new Server().start();
        } catch (Exception e) {
        }
        Gui main_frame = new Gui();
        main_frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        main_frame.pack();

        new Client().start();
    }
}

You can reach me by email at “lars dash 7 dot sdu dot se” or by telephone +46 705 189090

View source for the content of this page.