如何使用javafx中的进度指示器等待某些操作完成?

时间:2015-01-08 12:32:13

标签: java sockets javafx

我有一个代码向服务器发送命令。

public static void createAndSendCommand(String action, byte[] data) {
    if (action.equals(OE_Constants.ACTION_UPDATE)) {
        File file = new File(OE_Constants.FILE_BACKUP_TOPOLOGY);
        Command command = ConnectionManager.populateData(file);
        FrontEndClient.sendCommandToServer(command);
    }
}

public static boolean sendCommandToServer(Command command) {
    try {
        outStream.writeObject(command);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

我收到的结果如下。

public void receiveResultFromServer() {
    try {
        while(!clientSocket.isClosed()) {
            CommandExecResult result;
            try {
                result = (CommandExecResult) inStream.readObject();
                ConnectionManager.parseCommandExecutionResult(result);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

现在我想等待命令在服务器上成功执行,直到客户端收到它的结果。我想显示一些进度指示器类型的UI ....如何做到这一点? 谢谢!

2 个答案:

答案 0 :(得分:0)

  1. 使用Task or a Service进行长时间运行的服务器调用。
  2. 使用Task.updateProgress()通知当前进度/已完成的工作。
  3. 将正在运行的任务的progressProperty绑定到ProgressBarProgressIndicator

答案 1 :(得分:0)

您指定了标签java和javafx。这是我对javafx的解决方案。这是一个简单的对话框,可以从“外部”'更新。通过绑定。

WorkingDialog.java:

package stackoverflow.progress;

import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;

public final class WorkingDialog extends Stage implements Initializable {

    private static final Logger LOG = Logger.getLogger(WorkingDialog.class.getName());
    public SimpleDoubleProperty progress = new SimpleDoubleProperty(0);

    public WorkingDialog(String title, Stage owner) {
        super();

        setTitle(title);
        initStyle(StageStyle.UTILITY);
        initModality(Modality.APPLICATION_MODAL);
        initOwner(owner);

        double w = 300;
        double h = 200;

        setWidth(w);
        setHeight(h);

        double dx = (owner.getWidth() - w) / 2;
        double dy = (owner.getHeight() - h) / 2;

        setX(owner.xProperty().get() + dx);
        setY(owner.yProperty().get() + dy);

        setResizable(false);
        showDialog(progress);
    }

    public void hideDialog() {
        Platform.runLater(() -> {
            hide();
        });
    }

    public void setTitleText(String title) {
        Platform.runLater(() -> {
            setTitle(title);
        });
    }

    private void showDialog(SimpleDoubleProperty progress) {
        //scene : gridPane : 0,0->progressbar,0,1->borderpane : center->button
        GridPane gridPane = new GridPane();

        gridPane.setGridLinesVisible(false);
        gridPane.setPadding(new Insets(10));
        gridPane.setHgap(5);
        gridPane.setVgap(5);

        setOnCloseRequest((WindowEvent e) -> {
            e.consume();
        });

        ProgressBar pb = new ProgressBar(-1);
        pb.setPrefWidth(300);
        pb.progressProperty().bind(progress);
        BorderPane borderPane = new BorderPane(pb);
        gridPane.add(borderPane, 0, 0);

        Scene scene = new Scene(gridPane);
        setScene(scene);
        sizeToScene();
        show();
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
    }
}

用法示例(WorkingDialogTest.java):

package stackoverflow.progress;

import java.util.logging.Logger;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class WorkingDialogTest extends Application {

    private static final Logger LOG = Logger.getLogger(WorkingDialogTest.class.getName());

    @Override
    public void start(Stage primaryStage) {
        Group group = new Group();
        Scene scene = new Scene(group);

        primaryStage.setTitle("Dialogs");
        primaryStage.setWidth(600);
        primaryStage.setHeight(400);

        Button button = new Button("function");
        button.setOnAction((ActionEvent e) -> {

            WorkingDialog wd = new WorkingDialog("title", primaryStage);
            new Thread(() -> {
                int counter = 10;
                for (int i = 0; i < counter; i++) {
                    try {
                        wd.progress.set(1.0 * i / (counter - 1)); 
                        Thread.sleep(1000); //<-------- do more useful stuff here
                    } catch (InterruptedException ex) {
                    }
                }
                wd.hideDialog();
            }).start();

        });

        HBox hbox = new HBox(button);
        group.getChildren().addAll(hbox);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

看起来像这样:
progress