I'm trying to sum the similar threads inside the ExecutorService. I think I should use join() method, but I wasn't able to do it correctly.
My Code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class Gui extends JFrame implements ActionListener{
private JTextField txtSeats, txtAgents, txtTime;
public int numFirst, numSecond, numThird;
private JTextArea [] bookSeat;
private JButton btn1, btn2;
private String output, name;
private Random ran;
private JPanel p1, p2;
private String [] agentNumber;
private int [] sum;
private int x, z;
public Gui() {//A constructor for the Gui class.
ran = new Random();//Initializing the Random class.
setLayout(new BorderLayout());//Setting the layout for the JFrame.
setTitle("");//the title of the program.
p1 = new JPanel();//Creating the first JPanel to add JButtons and JTextField on it.
p1.setLayout(new FlowLayout());//Setting the first JPanel's layout.
//Creating 3 JTextField with a title for each, and adding each of them to the first JPanel.
txtSeats = new JTextField("Number of seats");
p1.add(txtSeats);
txtAgents = new JTextField("Number of agents");
p1.add(txtAgents);
txtTime = new JTextField("Max waiting time");
p1.add(txtTime);
//Creating 2 JButton with a title for each, and adding each of them to the first JPanel.
btn1 = new JButton("Create seats");
p1.add(btn1);
btn2 = new JButton("Book");
p1.add(btn2);
//Registering the 2 JButton to the ActionListener so they work with the actionPerformed() method when they get clicked.
btn1.addActionListener(this);
btn2.addActionListener(this);
add(p1, BorderLayout.NORTH);//Adding the first JPanel to the main JFrame at the position NORTH.
//Giving some properties to the JFrame layout.
setExtendedState(JFrame.MAXIMIZED_BOTH);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
}//End of the constructor.
public void createSeat() {//A method for creating a number of empty seats depending on the users wish.
//Storing the value of the first JTextField into an integer variable.
//With removing the spaces in it if there is any using "trim()".
numFirst = Integer.parseInt(txtSeats.getText().trim());
//Creating a JTextArea array for the number of seats the user wants to add.
//The size is entered by the user.
bookSeat = new JTextArea[numFirst];
p2 = new JPanel(); //Creating the second JPanel to add JTextArea on it.
p2.setLayout(new FlowLayout()); //Setting the second JPanel's layout.
//for-loop for adding the new JTextArea array into the second JPanel.
//With setting their title and background color and other properties.
for(int i = 0; i < numFirst; i++) {
bookSeat[i] = new JTextArea("Not booked");
bookSeat[i].setBackground(Color.WHITE);
bookSeat[i].setEditable(false);
p2.add(bookSeat[i]);
add(p2, BorderLayout.CENTER);//Adding the second JPanel to the main JFrame at the position CENTER.
setVisible(true);
}
}//End of createSeat() method.
@Override
public void actionPerformed(ActionEvent e) {//A method Overrode from the ActionListener interface.
if(e.getSource().equals(btn1)) {//First case: The JButton "Create seats" is clicked.
//Calling the createSeat() method; to create an empty seats based on the entered number of seats in the first JTextField.
createSeat();
//This method called on a container once new components are added or old ones removed.
//This call is an instruction to tell the layout manager to reset based on the new component list.
//revalidate() will trigger a call to repaint what the component thinks are 'dirty regions.'
//https://stackoverflow.com/questions/1097366/java-swing-revalidate-vs-repaint
revalidate();
}
else if(e.getSource().equals(btn2)) {//Second case: The JButton "Book" is clicked.
//Storing the values of the second and third JTextField into 2 integer variables.
//With removing the spaces in them if there is any using "trim()".
numSecond = Integer.parseInt(txtAgents.getText().trim());
numThird = Integer.parseInt(txtTime.getText().trim());
//Creating an ExecutorService object with fixed thread pool with maximum number of agents threads.
ExecutorService executor = Executors.newFixedThreadPool(numSecond);
//for-loop for the number of times the ExecutorService (thread pool) should run.
//It will keep creating threads until it reaches the maximum number of seats.
for(int i = 0; i < numFirst; i++) {
int count = i;
//Submitting Runnable task to the executor.
executor.execute(new Runnable() {
@Override
public void run() {//A method Overrode from the Runnable interface.
try {
//Getting the name of the current thread & store it in a String variable.
//Then we will have a long name like: pool-1-thread-n (n is a changing thread number).
//We use split("-"); to split it to 4 parts and we take the 4 part which is in position [3].
name = Thread.currentThread().getName();
agentNumber = name.split("-");
//Setting the new text and background color to the JTextArea array after they get booked.
bookSeat[count].setText("Booked by Agent " + agentNumber[3]);
bookSeat[count].setBackground(Color.RED);
revalidate();
//Generating random number between 0 and the waiting time entered by the user.
//And inserting this value inside the sleep() method. For a waiting time between each thread.
x = ran.nextInt(numThird + 1);
Thread.currentThread().sleep(x);
}
catch (Exception e) {}
}//End of run() method.
});//End of the executor.
}//End of the for-loop.
//Temporary solution for finding the similar elements in the array and return the sum for each
//equal threads. BUT NOT WORKING!!!
z = 0;
for(int i = 0; i < numFirst;i++) {
for(int j = 0; j < numFirst; j++) {
if(bookSeat[i].getName().equals(bookSeat[j].getName())) {
sum[i] = z + 1;
}
}
}
//for-loop for storing the booked seats in a String variable.
output = "";
for(int i = 1; i <= numSecond; i++) {
String allAgents = String.valueOf(i);
output += ("\n" + "Agent " + allAgents + " booked " + sum + " seats.");
}
//Displaying a Message Dialog with the information of each agent's booking.
JOptionPane.showMessageDialog(this,output);
//Shutdown the executor.
executor.shutdown();
//Wait until all tasks are finished.
while(!executor.isTerminated()) {
System.out.println("The booking has finished");
}
}//End of else if condition.
}//End of actionPerformed() method.
public static void main(String [] args) {//Main method.
new Gui(); //Calling the Gui.
}//End of Main method.
}//End of the class.
As you may see, I have tried with doing a nested for loop for checking the elements in the array if they were similar and return the sum of them. But this still didn't work!
z = 0;
for(int i = 0; i < numFirst;i++) {
for(int j = 0; j < numFirst; j++) {
if(bookSeat[i].getName().equals(bookSeat[j].getName())) {
sum[i] = z + 1;
}
}
}