Hello guys so i have to make two threads that sell train tickets simultaneously and display there output on two different windows, i have create a class that generates the tickets and a Runnable but i am not sure how to display the output of the two different threads in the two different Text area boxes i have tried to pass the TextBox parameter but it didn’t work any ideas please ?
SellTicketThreadProc:
public class SellTicketThreadProc implements Runnable { private CTicketBiz cTicketBiz; public SellTicketThreadProc(CTicketBiz newobj){ cTicketBiz = newobj; } public void sellticket(){ String color; switch(Thread.currentThread().getName()){ case "Thread 1": color = ThreadColor.ANSI_CYAN; break; case "Thread 2": color = ThreadColor.ANSI_PURPLE; break; default: color = ThreadColor.ANSI_GREEN; } System.out.println(color + Thread.currentThread().getName() + " Random number: " + cTicketBiz.GetRandTicket() + " Remaining tickets are: " + cTicketBiz.GetBalanceNum() ); } @Override public void run() { while (cTicketBiz.GetBalanceNum() != 0) { sellticket(); } } }
CTicketBiz:
public class CTicketBiz { private int[] m_pTicket; //Point to the array that saves the ticket information private int m_nSoldNum; // Sold ticket number private int m_nBalanceNum; // Remaining ticket number private int m_nTotalNum; // Generate the ticket. Initialize the movie ticket array. void GenerateTicket(int totalTickets){ m_nTotalNum = totalTickets; m_pTicket = new int[m_nTotalNum]; m_nBalanceNum = m_nTotalNum; m_nSoldNum = 0; for (int i = 0; i < m_nTotalNum; i++) { m_pTicket[i] = i + 1; } } // Get a ticket randomly public synchronized int GetRandTicket(){ if (m_nBalanceNum <= 0) return 0; int temp = 0; do { temp = new Random().nextInt(m_pTicket.length); } while (m_pTicket[temp] == 0); m_pTicket[temp] = 0; m_nBalanceNum--; m_nSoldNum++; return temp + 1; } // Get the remaining ticket number int GetBalanceNum(){ return m_nBalanceNum; } }
Controller:
import javafx.fxml.FXML; import javafx.event.ActionEvent; import javafx.scene.control.Button; import javafx.scene.control.TextField; import javafx.scene.control.TextArea; public class Controller { @FXML private TextField ticketsToSell; @FXML private Button startSelling; @FXML private TextArea displayThread1; @FXML private TextArea getDisplayThread2; @FXML public void onButtonClicked(ActionEvent e){ if(e.getSource().equals(startSelling)){ CTicketBiz cTicketBiz = new CTicketBiz(); cTicketBiz.GenerateTicket(6); SellTicketThreadProc tw = new SellTicketThreadProc(cTicketBiz); Thread t1 = new Thread (tw,"Thread 1"); Thread t2 = new Thread (tw,"Thread 2"); t1.start(); t2.start(); } } @FXML public void handleKeyReleased(){ String text = ticketsToSell.getText(); boolean disableButton = text.isEmpty() || text.trim().isEmpty(); startSelling.setDisable(disableButton); } }
Advertisement
Answer
Here is a quick runnable application to demonstrate how to update 2 separate textareas from background threads like you have make sure to read through the comments that explain whats going on. Obviously this is not the same exact thing as your program but I kept the core concept.
public class Main extends Application { private AtomicInteger totalTickets = new AtomicInteger(100); private boolean isSellingTickets = false; @Override public void start(Stage stage) { VBox vBoxContainer = new VBox(); vBoxContainer.setAlignment(Pos.CENTER); vBoxContainer.setPrefSize(400,250); TextArea textAreaTop = new TextArea(); TextArea textAreaBottom = new TextArea(); vBoxContainer.getChildren().addAll(textAreaTop, textAreaBottom); Button controlSalesButton = new Button("Start Ticket Sales"); controlSalesButton.setOnAction(event -> { if(isSellingTickets) { isSellingTickets = false; controlSalesButton.setText("Start Ticket Sales"); } else { isSellingTickets = true; //I didn't name these threads because I never reference them again // of course create var name if you need them new Thread(() -> sellTickets(textAreaTop)).start(); new Thread(() -> sellTickets(textAreaBottom)).start(); // This is on the main Thread so no need for Platform.runLater(...) controlSalesButton.setText("Stop Ticket Sales"); } }); vBoxContainer.getChildren().add(controlSalesButton); stage.setScene(new Scene(vBoxContainer)); stage.show(); } private void sellTickets(TextArea textArea){//This Whole Function is on another thread don't forget about that while(isSellingTickets && totalTickets.get()>1) { //Continue selling tickets until you stop // And Make Sure there is tickets to sell //Platform.runLater(... is used to update the main thread by pushing updates to // the JavaFX Application Thread at some unspecified time in the future. Platform.runLater(() -> { textArea.appendText("SOLD Ticket Number:" + (int) (Math.random() * 1000 + 1000) + " t" + totalTickets.decrementAndGet() + " Left to selln"); }); try { Thread.sleep((int) (Math.random() * 1000 + 100));//Different selling speeds this is irrelevant } catch (InterruptedException e) { e.printStackTrace(); } } } }
If you have any questions let me know