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:
JavaScript
x
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:
JavaScript
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:
JavaScript
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.
JavaScript
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