Tutorial

Building Your First Real-Time Dashboard with Oorian

Step-by-step guide to building a live dashboard that updates automatically using Oorian's SSE communication mode.

M. WarbleFebruary 12, 20263 min read
Building Your First Real-Time Dashboard with Oorian

Dashboards are the perfect showcase for Oorian's server-push capabilities. In this tutorial, we'll build a real-time metrics dashboard that updates automatically without any page refreshes.

Choosing the Right Communication Mode

For dashboards, SSE (Server-Sent Events) is ideal. The server pushes updates to the browser, but user interactions still use standard HTTP requests. This gives us the best of both worlds: live updates with simple infrastructure.

Setting Up the Dashboard Page

@Page(value = "/dashboard", communication = Communication.SSE)
public class DashboardPage extends HtmlPage
{
    private Div activeUsers;
    private Div requestsPerSecond;
    private Div cpuUsage;
    private Div memoryUsage;

    @Override
    protected void createBody(Body body)
    {
        Div container = new Div();
        container.setDisplay(Display.GRID);
        container.addStyleAttribute("grid-template-columns", "repeat(4, 1fr)");
        container.addStyleAttribute("gap", "20px");
        container.setPadding("20px");

        activeUsers = createMetricCard("Active Users", "0");
        requestsPerSecond = createMetricCard("Requests/sec", "0");
        cpuUsage = createMetricCard("CPU Usage", "0%");
        memoryUsage = createMetricCard("Memory", "0 MB");

        container.addElement(activeUsers);
        container.addElement(requestsPerSecond);
        container.addElement(cpuUsage);
        container.addElement(memoryUsage);

        body.addElement(container);

        // Start live updates
        startMetricUpdates();
    }

    private Div createMetricCard(String title, String initialValue)
    {
        Div card = new Div();
        card.setBackgroundColor("#ffffff");
        card.setBorderRadius("8px");
        card.setPadding("24px");
        card.addStyleAttribute("box-shadow", "0 2px 4px rgba(0,0,0,0.1)");

        H3 titleEl = new H3();
        titleEl.setText(title);
        titleEl.setColor("#6b7280");
        titleEl.setFontSize("14px");
        titleEl.setMargin("0 0 8px 0");
        card.addElement(titleEl);

        Div value = new Div();
        value.setText(initialValue);
        value.setFontSize("32px");
        value.setFontWeight("700");
        value.setColor("#1f2937");
        card.addElement(value);

        return card;
    }
}

Adding Live Updates with Worker Threads

Oorian's worker threads let you run background tasks that update the UI. Here's how to implement the live metrics:

private void startMetricUpdates()
{
    OorianWorkerThread.create(() -> {
        while (true)
        {
            try
            {
                // Fetch current metrics
                Metrics metrics = metricsService.getCurrentMetrics();

                // Update UI elements
                updateMetricValue(activeUsers, String.valueOf(metrics.getActiveUsers()));
                updateMetricValue(requestsPerSecond, String.valueOf(metrics.getRequestsPerSecond()));
                updateMetricValue(cpuUsage, metrics.getCpuUsage() + "%");
                updateMetricValue(memoryUsage, metrics.getMemoryUsage() + " MB");

                // Push changes to browser
                sendUpdate();

                // Wait before next update
                Thread.sleep(2000);
            }
            catch (InterruptedException e)
            {
                Thread.currentThread().interrupt();
                break;
            }
        }
    });
}

private void updateMetricValue(Div card, String value)
{
    // Get the value div (second child)
    Div valueDiv = (Div) card.getElements().get(1);
    valueDiv.setText(value);
}

Adding a Chart with Live Data

Let's add a line chart that shows request history:

private CjChart requestChart;
private List<Integer> requestHistory = new ArrayList<>();

private void createChart(Div container)
{
    requestChart = new CjChart(ChartType.LINE);
    requestChart.setLabels(generateTimeLabels(20));

    CjDataset dataset = new CjDataset("Requests/sec");
    dataset.setBorderColor("rgb(37, 99, 235)");
    dataset.setTension(0.4);
    requestChart.addDataset(dataset);

    container.addElement(requestChart);
}

private void updateChart(int newValue)
{
    requestHistory.add(newValue);
    if (requestHistory.size() > 20)
    {
        requestHistory.remove(0);
    }

    // Update chart data
    requestChart.getDatasets().get(0).setData(requestHistory);
    requestChart.update();
}

Handling User Interactions

Even with live updates, users can interact with the dashboard. Add a refresh button:

private void createRefreshButton(Div container)
{
    Button refresh = new Button("Force Refresh");
    refresh.registerListener(this, MouseClickedEvent.class);
    container.addElement(refresh);
}

@Override
public void onEvent(MouseClickedEvent event)
{
    // Immediately update all metrics
    Metrics metrics = metricsService.getCurrentMetrics();
    updateMetricValue(activeUsers, String.valueOf(metrics.getActiveUsers()));
    // ... update other metrics
}

Conclusion

Building real-time dashboards with Oorian is straightforward. SSE provides efficient server push, worker threads handle background updates, and you write everything in familiar Java. No JavaScript required, no complex WebSocket infrastructure needed.

Related Articles

Tutorial

Getting Started with Oorian: Your First Java Web Application

December 31, 2025
Security

Security by Default: How Oorian Protects Your Applications

January 11, 2026
Announcement

Why We Built Oorian: The Story Behind the Framework

January 7, 2026