JAVA

JavaFX Thread + Task를 활용한 API 호출 애플리케이션

지오준 2024. 12. 31.
반응형

JavaFX Thread + Task를 활용한 API 호출 애플리케이션

JavaFX 애플리케이션은 UI 업데이트가 단일 쓰레드(즉, JavaFX Application Thread)에서 이루어져야 하는 제약이 있습니다. 이로 인해 외부 API 호출이나 긴 작업은 별도의 백그라운드 쓰레드에서 처리한 후, UI를 갱신해야 합니다. 이를 위해 JavaFX는 Task 클래스를 제공하며, 이를 활용하면 백그라운드 작업과 UI 갱신을 안전하게 수행할 수 있습니다.

이 블로그에서는 JavaFX의 ThreadTask를 사용하여 API 호출 애플리케이션을 만드는 방법을 샘플 코드와 함께 자세히 설명하겠습니다.


주요 개념

Task란?

Task는 JavaFX에서 백그라운드 작업을 수행하기 위한 기본 클래스입니다. TaskRunnableFuture를 확장하여 작업 결과를 반환하거나 작업 중 예외를 처리할 수 있도록 설계되었습니다.

UI와 쓰레드의 분리

JavaFX 애플리케이션에서는 긴 작업이 UI 쓰레드를 블록하지 않도록 별도의 쓰레드에서 작업을 처리해야 합니다. Task와 같은 도구를 사용하면 이 과정을 간단히 구현할 수 있습니다.


구현 단계

1. API 호출용 JavaFX 프로젝트 생성

먼저 JavaFX 프로젝트를 설정하고 기본적인 UI 레이아웃을 작성합니다.

예제 UI 설계:

  • TextField: 사용자 입력
  • Button: API 호출 트리거
  • ProgressBar: 작업 진행률 표시
  • TextArea: API 응답 출력
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ApiApp extends Application {

    @Override
    public void start(Stage primaryStage) {
        TextField inputField = new TextField();
        Button callApiButton = new Button("Call API");
        ProgressBar progressBar = new ProgressBar(0);
        TextArea resultArea = new TextArea();
        resultArea.setEditable(false);

        VBox root = new VBox(10, inputField, callApiButton, progressBar, resultArea);
        root.setStyle("-fx-padding: 10;");

        Scene scene = new Scene(root, 400, 300);
        primaryStage.setTitle("API Caller");
        primaryStage.setScene(scene);
        primaryStage.show();

        callApiButton.setOnAction(event -> {
            String input = inputField.getText();
            if (!input.isEmpty()) {
                callApi(input, progressBar, resultArea);
            } else {
                resultArea.setText("Input cannot be empty.");
            }
        });
    }

    private void callApi(String input, ProgressBar progressBar, TextArea resultArea) {
        ApiTask task = new ApiTask(input);

        progressBar.progressProperty().bind(task.progressProperty());

        task.setOnSucceeded(e -> resultArea.setText(task.getValue()));
        task.setOnFailed(e -> resultArea.setText("Failed to fetch data: " + task.getException().getMessage()));

        Thread thread = new Thread(task);
        thread.setDaemon(true);
        thread.start();
    }

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

2. Task를 사용한 API 호출 구현

Task를 사용하여 API 호출 로직을 작성합니다. 다음은 샘플 Task 클래스입니다.

import javafx.concurrent.Task;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class ApiTask extends Task<String> {

    private final String input;

    public ApiTask(String input) {
        this.input = input;
    }

    @Override
    protected String call() throws Exception {
        updateProgress(0, 100);

        URL url = new URL("https://api.example.com/data?query=" + input);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");

        updateProgress(20, 100);

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
            StringBuilder response = new StringBuilder();
            String line;

            while ((line = reader.readLine()) != null) {
                response.append(line).append("\n");
                updateProgress(response.length(), connection.getContentLength());
            }

            updateProgress(100, 100);
            return response.toString();
        } catch (Exception e) {
            updateProgress(0, 100);
            throw e;
        }
    }
}

실행 및 테스트

이제 애플리케이션을 실행하고 다양한 입력값으로 API 호출을 테스트할 수 있습니다. UI는 API 호출 중에도 응답성을 유지하며, 진행 상태와 결과를 적절히 표시합니다.


주요 기능 요약

  • Task의 활용: 백그라운드에서 API 호출을 처리하고, UI 쓰레드에서 결과를 업데이트.
  • ProgressBar 연동: 작업 진행 상황을 사용자에게 실시간으로 표시.
  • 예외 처리: 실패 시 사용자에게 명확한 오류 메시지 제공.

위 코드는 JavaFX와 Task를 사용하여 API 호출을 처리하는 방법을 간단히 보여줍니다. 이를 확장하여 다양한 애플리케이션에 활용할 수 있습니다.

반응형

댓글