2014-10-28 4 views
4

Я создал графический интерфейс с использованием JavaFX, и есть три переключателя, и после того, как пользователь нажимает кнопку «Отправить», и создается другой поток, и в зависимости от того, какой протокол был проверен, поток выполняет требуемый вывод и выводит результат на консоль.Как разместить задачи в JavaFX?

Но пока поток работает (занимает около 30 секунд для завершения одного процесса), я могу проверить любой радиообъектив. Для этого создается другой поток и выводится с другим продолжающимся потоком. Таким образом, мой выходной ящик - просто беспорядок! Я смотрел на задачу asynchronous, но я не уверен, что это связано с ней.

Вот что мне нужно: если задача запущена, и я нажимаю кнопку отправки во время ее работы, дождитесь, пока предыдущая задача закончится, и THEN выполнит задачу.

Вот код псевдо моего кода

class TestMain{ 


main class{ 
launch(args); 
} 

declaring a new textfield with name m_status update here 
once submit button is clicked { 


create a new thread to run 



} 
} 


class ThreadBlahBlah implements Runnable{ 

if(first checkbox was selected){ 
//do these fancy stuff 
Platform.runLater(new Runnable() { 
@Override 
    public void run() { 
    TestMain.m_status_update.setText("Test Completed!") ; 


} 
else(second checkbox was selected){ 
//do these other fancy stuff 
Platform.runLater(new Runnable() { 
    @Override 
    public void run() { 
    TestMain.m_status_update.setText("Test Completed!") ; 

} 


} 

Пожалуйста, не рекомендуют мне отключить радио кнопки во время выполнения задания, потому что я хочу, чтобы мои очереди задач, как связанный список.

ответ

5

Используйте однопоточный исполнитель для выполнения своих задач:

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.atomic.AtomicInteger; 

import javafx.application.Application; 
import javafx.beans.binding.Bindings; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.concurrent.Task; 
import javafx.geometry.Insets; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.control.TextArea; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.HBox; 
import javafx.stage.Stage; 

public class QueuedTaskExample extends Application { 

    private AtomicInteger taskCount = new AtomicInteger(0); 

    private ExecutorService exec = Executors.newSingleThreadExecutor(r -> { 
     Thread t = new Thread(r); 
     t.setDaemon(true); // allows app to exit if tasks are running 
     return t ; 
    }); 

    // Use the following if you want the tasks to run concurrently, instead of consecutively: 

    // private ExecutorService exec = Executors.newCachedThreadPool(r -> { 
    //  Thread t = new Thread(r); 
    //  t.setDaemon(true); 
    //  return t ; 
    // }); 


    @Override 
    public void start(Stage primaryStage) { 

     // Just keep track of number of tasks pending/running for a status label: 
     IntegerProperty pendingTasks = new SimpleIntegerProperty(0); 

     Button startButton = new Button("Start"); 
     TextArea textArea = new TextArea(); 
     textArea.setEditable(true); 
     startButton.setOnAction(event -> { 
      Task<Void> task = createTask(); 
      // add text to text area if task's message changes: 
      task.messageProperty().addListener((obs, oldMessage, newMessage) -> { 
       textArea.appendText(newMessage); 
       textArea.appendText("\n"); 
      }); 

      // for maintaining status label: 
      pendingTasks.set(pendingTasks.get()+1); 
      task.setOnSucceeded(taskEvent -> pendingTasks.set(pendingTasks.get()-1)); 

      // run task in single-thread executor (will queue if another task is running): 
      exec.submit(task); 
     }); 

     // layout etc 
     HBox controls = new HBox(startButton); 
     controls.setAlignment(Pos.CENTER); 
     controls.setPadding(new Insets(10)); 

     Label statusLabel = new Label(); 
     statusLabel.textProperty().bind(Bindings.format("Pending/running tasks: %s", pendingTasks)); 

     BorderPane root = new BorderPane(textArea, statusLabel, null, controls, null); 
     Scene scene = new Scene(root, 600, 400); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    @Override 
    public void stop() { 
     exec.shutdownNow(); 
    } 

    // Trivial task that counts slowly to 5, updating its message as it goes: 
    private Task<Void> createTask() { 
     final int taskNumber = taskCount.incrementAndGet(); 
     return new Task<Void>() { 
      @Override 
      public Void call() throws Exception { 
       for (int count=1; count<=5; count++) { 
        Thread.sleep(1000); 
        updateMessage("Task "+taskNumber+": Count "+count); 
       } 
       return null ; 
      } 
     }; 
    } 

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

Когда пользователь нажимает на переключатель, сначала отключите все переключатели, чтобы пользователь не мог нажимать на другие переключатели во время выполнения вашей задачи.

Когда вы закончили фоновое задание, включите все переключатели, чтобы пользователь мог выбрать другую задачу.

См. Node.setDisabled() (RadioButton extends Node).

Если вам нужно поставить задачи в очередь, то ваш фоновый поток должен поддерживать список задач aa, а когда пользователь нажимает, добавьте задачу в список, который должен потреблять фоновый поток (запустите другую задачу, если текущий завершен и их больше).

Для расширенного резьбового исполнения см. Executors и ExecutorService.

+0

Но что, если я в порядке с пользователем, выбирающей кнопкой радио во время выполнения задачи. Задача должна начинаться после завершения предыдущего. Своего рода, как в очереди! как связанный список – Indigo

+0

@OctavianRox Затем вы должны сохранить список задач в фоновом потоке, а когда пользователь нажимает, добавьте задачу в список, который должен потреблять фоновый поток (запустите другую задачу, если текущий завершен, и там более). – icza

Смежные вопросы