JavaFXアプリにリアルタイムチャートを埋め込む方法【WebSocket連携】

JavaFX × WebSocketでリアルタイム表示に挑戦! 本記事では、JavaFXアプリにリアルタイムで更新されるチャートを組み込む方法を、WebSocketを使ったデータ連携とともに解説します。IoTや金融アプリケーション、センサーデータの可視化にも応用可能な技術です。


この記事の対象読者

  • JavaFXを用いたデスクトップアプリケーションを開発している方
  • リアルタイムデータをグラフ表示したい方
  • WebSocketをJavaで扱いたい方

使用するライブラリ・技術

  • JavaFX(GUI構築)
  • JFreeChart または XChart(チャート描画)
  • Java WebSocket API(リアルタイム通信)
  • Maven(依存管理)

1. プロジェクトの準備(Maven)

<!-- pom.xml に以下を追加 -->
<dependencies>
    <!-- JavaFX -->
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-controls</artifactId>
        <version>17</version>
    </dependency>

    <!-- WebSocket クライアント -->
    <dependency>
        <groupId>org.java-websocket</groupId>
        <artifactId>Java-WebSocket</artifactId>
        <version>1.5.2</version>
    </dependency>

    <!-- XChart(軽量チャート) -->
    <dependency>
        <groupId>org.knowm.xchart</groupId>
        <artifactId>xchart</artifactId>
        <version>3.8.0</version>
    </dependency>
</dependencies>

2. WebSocketクライアントの作成(Java側)

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;

public class ChartWebSocketClient extends WebSocketClient {
    private final DataHandler handler;

    public ChartWebSocketClient(URI serverUri, DataHandler handler) {
        super(serverUri);
        this.handler = handler;
    }

    @Override
    public void onOpen(ServerHandshake handshake) {
        System.out.println("接続しました。");
    }

    @Override
    public void onMessage(String message) {
        handler.onDataReceived(Double.parseDouble(message));
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        System.out.println("接続が切断されました。");
    }

    @Override
    public void onError(Exception ex) {
        ex.printStackTrace();
    }

    public interface DataHandler {
        void onDataReceived(double value);
    }
}

3. JavaFXでリアルタイムチャートを表示

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import org.knowm.xchart.XYChart;
import org.knowm.xchart.XYSeries;
import org.knowm.xchart.XYChartBuilder;
import org.knowm.xchart.XChartPanel;

import java.util.*;

public class RealTimeChartApp extends Application {
    private final List<Double> xData = new ArrayList<>();
    private final List<Double> yData = new ArrayList<>();
    private XYSeries series;

    @Override
    public void start(Stage primaryStage) {
        XYChart chart = new XYChartBuilder()
                .width(600)
                .height(400)
                .title("リアルタイムデータ")
                .xAxisTitle("時刻")
                .yAxisTitle("値")
                .build();
        series = chart.addSeries("データ", xData, yData);

        XChartPanel<XYChart> chartPanel = new XChartPanel<>(chart);
        BorderPane root = new BorderPane(chartPanel);
        Scene scene = new Scene(root, 600, 400);
        primaryStage.setScene(scene);
        primaryStage.setTitle("JavaFXリアルタイムチャート");
        primaryStage.show();

        ChartWebSocketClient client = new ChartWebSocketClient(
            URI.create("ws://localhost:8080/data"),
            value -> {
                if (xData.size() > 100) {
                    xData.remove(0);
                    yData.remove(0);
                }
                xData.add((double) System.currentTimeMillis());
                yData.add(value);
                series.replaceData(xData, yData);
                chartPanel.repaint();
            }
        );
        client.connect();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

4. WebSocketサーバ(Node.js例)

テスト用には簡単なNode.jsサーバでダミー値を送信できます

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

setInterval(() => {
  const value = (Math.random() * 100).toFixed(2);
  wss.clients.forEach(client => {
    if (client.readyState === WebSocket.OPEN) {
      client.send(value);
    }
  });
}, 1000);

まとめ

JavaFX × WebSocketを使うことで、デスクトップアプリでもWebアプリ並みのリアルタイム性を持たせることが可能です。XChartを使うことで軽量かつ柔軟な描画ができ、IoTや業務アプリケーションへの展開にも応用できます。

タイトルとURLをコピーしました