AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79245585
Accepted
Adalberto J. Brasaca
Adalberto J. Brasaca
Asked: 2024-12-03 04:58:15 +0800 CST2024-12-03 04:58:15 +0800 CST 2024-12-03 04:58:15 +0800 CST

JavaFX - Atualizando ProgressBar na Criação de Nós

  • 772

Já vi muito código na plataforma sobre atualização do ProgressBar usando thread, mas tudo está relacionado a algum cálculo realizado ou atualização de alguma propriedade de controle. Não sei se é possível, mas o que preciso é que o ProgressBar mostre o progresso na criação de 225 (15 X 15) a 2500 (50 x 50) TextFields. Abaixo estão os arquivos e o .fxml. Quando incluí a parte do código do thread, a grade parou de aparecer. Agradeço desde já.

A aplicação

insira a descrição da imagem aqui

Aplicação de grade.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class GridCenterApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(GridCenterApplication.class.getResource("main-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load());
        stage.setTitle("Grid");
        stage.setScene(scene);
        stage.setMaximized(true);
        stage.show();
    }

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

Controle de grade.java

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;

import java.net.URL;
import java.util.ResourceBundle;

public class GridCenterController implements Initializable {

    @FXML
    private ScrollPane scpGrid;

    @FXML
    private Spinner<Integer> spnCols;

    @FXML
    private Spinner<Integer> spnRows;

    @FXML
    private ProgressBar pgbProgress;

    GridPane gridPane;

    private final int CELL_HORIZONTAL_GAP = 1;
    private final int CELL_VERTICAL_GAP = 1;
    private final int CELL_HORIZONTAL_SIZE = 40;
    private final int CELL_VERTICAL_SIZE = 40;

    private int totalCols = 0;
    private int totalRows = 0;

    @FXML
    void onMnuItemNewGridAction(ActionEvent event) {

        if(!(scpGrid.getContent() == null)){
            scpGrid.setContent(null);
        }

        totalCols = spnCols.getValue();
        totalRows = spnRows.getValue();

        var newGrid = new Grid(totalCols, totalRows, CELL_HORIZONTAL_GAP, CELL_VERTICAL_GAP, CELL_HORIZONTAL_SIZE,
                CELL_VERTICAL_SIZE, pgbProgress);
        gridPane = newGrid.getGrid();
        scpGrid.setContent(gridPane);
    }

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        SpinnerValueFactory<Integer> numberOfCols = new SpinnerValueFactory.IntegerSpinnerValueFactory(15, 50);
        SpinnerValueFactory<Integer> numberOfRows = new SpinnerValueFactory.IntegerSpinnerValueFactory(15, 50);
        spnCols.setValueFactory(numberOfCols);
        spnRows.setValueFactory(numberOfRows);
        scpGrid.contentProperty().addListener((observableValue, oldValue, newValue) -> {
            if (newValue != null && newValue.isVisible()) {
               pgbProgress.setProgress(0);
            }
        });

    }
}

Grade.java

import javafx.concurrent.Task;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;

public class Grid {

    private final GridPane grid;

    public Grid(int totalCols, int totalRows, int CELL_HORIZONTAL_GAP, int CELL_VERTICAL_GAP, int CELL_HORIZONTAL_SIZE,
                int CELL_VERTICAL_SIZE, ProgressBar pgbProgress) {

        grid = new GridPane();
        grid.setHgap(CELL_HORIZONTAL_GAP);
        grid.setVgap(CELL_VERTICAL_GAP);
        TextField[][] arrayLetterField = new TextField[totalCols][totalRows];

        Task<Void> task = new Task<Void>() {
            @Override
            protected Void call() throws Exception {

                pgbProgress.setProgress(0);
                double total = totalCols * totalRows;
                double i = 1.0;

                for (int row = 0; row < totalRows; row++) {
                    for (int col = 0; col < totalCols; col++) {
                        arrayLetterField[col][row] = new TextField();
                        arrayLetterField[col][row].setMinSize(CELL_HORIZONTAL_SIZE, CELL_VERTICAL_SIZE);
                        arrayLetterField[col][row].setMaxSize(CELL_HORIZONTAL_SIZE, CELL_VERTICAL_SIZE );
                        grid.add(arrayLetterField[col][row], col, row);
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }

                        updateProgress(i, total);
                        i++;
                    }
                }
                return null;
            }
        };

        pgbProgress.progressProperty().bind(task.progressProperty());
        new Thread(task).start();

    }

    public GridPane getGrid() {
        return grid;
    }

}

visualização-principal.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.Spinner?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>

<BorderPane prefHeight="767.0" prefWidth="1053.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.gridpanetest.GridCenterController">
    <top>
        <VBox prefWidth="100.0" BorderPane.alignment="CENTER">
            <children>
                <MenuBar fx:id="mnuBar" prefHeight="25.0" prefWidth="360.0">
                    <menus>
                        <Menu mnemonicParsing="false" text="Grid">
                            <items>
                                <MenuItem mnemonicParsing="false" onAction="#onMnuItemNewGridAction" text="New grid" />
                            </items>
                        </Menu>
                    </menus>
                </MenuBar>
            <Pane prefHeight="80.0" prefWidth="1053.0">
               <children>
                  <Label layoutX="26.0" layoutY="15.0" text="Columns" />
                  <Label layoutX="26.0" layoutY="46.0" text="Rows" />
                  <Spinner fx:id="spnCols" layoutX="79.0" layoutY="11.0" prefHeight="25.0" prefWidth="57.0" />
                  <Spinner fx:id="spnRows" layoutX="79.0" layoutY="42.0" prefHeight="25.0" prefWidth="57.0" />
                  <ProgressBar fx:id="pgbProgress" focusTraversable="false" layoutX="185.0" layoutY="31.0" prefWidth="200.0" progress="0.0" />
               </children>
            </Pane>
            </children>
        </VBox>
    </top>
   <center>
        <ScrollPane fx:id="scpGrid" style="-fx-background-color: #dbbb92; -fx-background: #dbbb92;" BorderPane.alignment="CENTER" />
   </center>
</BorderPane>
multithreading
  • 1 1 respostas
  • 31 Views

1 respostas

  • Voted
  1. Best Answer
    Sai Dandem
    2024-12-03T08:35:09+08:002024-12-03T08:35:09+08:00

    Acredito que o principal problema no seu código é a parte em que você adiciona o campo de texto à grade. É porque você está tentando adicionar o nó filho em um thread diferente e não no thread JavaFX.

    Uma solução rápida pode ser encapsular esse código em Platform.runLater, conforme abaixo:

    int c = col;
    int r = row;
    Platform.runLater(() -> grid.add(arrayLetterField[c][r], c, r));
    

    Mas esse não será o comportamento que você deseja, porque você está adicionando a grade muito cedo, então verá os nós sendo adicionados um por um.

    Para atualizar o scrollPane no final, você pode tentar o código abaixo para obter o comportamento desejado. Eu também incluí a lógica de atualização instantânea de nós, apenas para referência para lhe dar alguma ideia.

    insira a descrição da imagem aqui

    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.beans.property.ObjectProperty;
    import javafx.beans.property.SimpleObjectProperty;
    import javafx.concurrent.Task;
    import javafx.geometry.Insets;
    import javafx.geometry.Pos;
    import javafx.scene.Node;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.layout.GridPane;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.Priority;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    
    public class NodesProgressBarDemo extends Application {
        @Override
        public void start(Stage primaryStage) throws Exception {
            TextField cols = new TextField();
            cols.setPrefWidth(100);
            TextField rows = new TextField();
            rows.setPrefWidth(100);
            Button generateLazily = new Button("Generate Lazily");
            Button generateInstantly = new Button("Generate Instantly");
            HBox row = new HBox(20, new HBox(10, new Label("Columns:"), cols),
                    new HBox(10, new Label("Rows:"), rows),
                    generateLazily, generateInstantly);
            row.setAlignment(Pos.CENTER_LEFT);
    
            ProgressBar progressBar = new ProgressBar();
            progressBar.setProgress(0);
            progressBar.setMaxWidth(Double.MAX_VALUE);
    
            ScrollPane scrollPane = new ScrollPane();
            scrollPane.setFitToHeight(true);
            scrollPane.setFitToWidth(true);
            VBox.setVgrow(scrollPane, Priority.ALWAYS);
    
            generateLazily.setOnAction(e -> updateGridLazily(cols.getText(), rows.getText(), scrollPane, progressBar));
            generateInstantly.setOnAction(e -> updateGridInstantly(cols.getText(), rows.getText(), scrollPane, progressBar));
    
            VBox root = new VBox(10, row, progressBar, scrollPane);
            root.setPadding(new Insets(10));
            Scene scene = new Scene(root, 700, 500);
            primaryStage.setScene(scene);
            primaryStage.setTitle("Nodes ProgressBar Demo");
            primaryStage.show();
        }
    
        private void updateGridLazily(String col, String row, ScrollPane scrollPane, ProgressBar progressBar) {
            int columns = Integer.parseInt(col);
            int rows = Integer.parseInt(row);
    
            ObjectProperty<Node> content = new SimpleObjectProperty<>();
            Task<Void> task = new Task<>() {
                @Override
                protected Void call() {
                    int total = columns * rows;
                    int count = 0;
                    GridPane gridPane = new GridPane();
                    gridPane.setVgap(5);
                    gridPane.setHgap(5);
                    content.set(gridPane);
                    for (int r = 0; r < rows; r++) {
                        for (int c = 0; c < columns; c++) {
                            TextField textField = new TextField();
                            textField.setMinSize(40, 40);
                            textField.setMaxSize(40, 40);
                            gridPane.add(textField, c, r);
    
                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
    
                            count++;
                            updateProgress(count, total);
                        }
                    }
                    return null;
                }
            };
            task.setOnSucceeded(e -> {
                scrollPane.setContent(content.get());
                progressBar.setProgress(0);
            });
            task.progressProperty().addListener((obs, old, val) -> progressBar.setProgress(val.doubleValue()));
            new Thread(task).start();
        }
    
        private void updateGridInstantly(String col, String row, ScrollPane scrollPane, ProgressBar progressBar) {
            int columns = Integer.parseInt(col);
            int rows = Integer.parseInt(row);
    
            GridPane gridPane = new GridPane();
            gridPane.setVgap(5);
            gridPane.setHgap(5);
            scrollPane.setContent(gridPane);
    
            Task<Void> task = new Task<>() {
                @Override
                protected Void call() {
                    int total = columns * rows;
                    int count = 0;
                    for (int r = 0; r < rows; r++) {
                        for (int c = 0; c < columns; c++) {
                            TextField textField = new TextField();
                            textField.setMinSize(40, 40);
                            textField.setMaxSize(40, 40);
                            int r1 = r;
                            int c1 = c;
    
                            Platform.runLater(() -> gridPane.add(textField, c1, r1));
    
                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
    
                            count++;
                            updateProgress(count, total);
                        }
                    }
                    return null;
                }
            };
            task.setOnSucceeded(e -> progressBar.setProgress(0));
            task.progressProperty().addListener((obs, old, val) -> progressBar.setProgress(val.doubleValue()));
            new Thread(task).start();
        }
    }
    

    Tarefa relacionada Javadoc

    • Uma tarefa que modifica o gráfico de cena
    • Uma tarefa que retorna resultados parciais
    • 3

relate perguntas

  • Propriedades JMeter gravando simultaneamente

  • Como usar uma variável de estado Tauri gerenciada dentro de um thread de tempo de execução assíncrono Tauri gerado?

  • Um println extra no thread principal faz com que o Rust execute resultados diferentes

  • ideal para liberar atômicos de baixa contenção dos caches?

  • Rust: Itere em uma pasta e abra cada arquivo

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve