The issue here is that after asking a user for the settings of a neural network through a settings JFrame, the new JFrame meant to visualise the network learning only seems to display something after the network is done looping through all the data.
I believe this is because I use a SwingWorker and the loop doesn't wait for it to finish doing the calculations and displaying the result before going onto the next cycle.
Step 1: I ask the user for parameters with a JFrame
public class Settings {
private int width = 1920 / 4;
private int height = 1080 / 4;
private JFrame settings;
private JButton startButton;
public static void main(String[] args) {
Settings settings = new Settings();
settings.start();
}
private void start() {
settings = new JFrame();
settings.setTitle("Settings");
settings.setSize(width, height);
settings.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
startButton = new JButton("start");
startButton.addActionListener(new FieldListener());
settings.getContentPane().add(startButton);
settings.pack();
settings.setVisible(true);
}
class FieldListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == startButton) {
prepare();
}
}
}
public void prepare() {
Control control = new Control();
control.start(amountOfNeurons);
}
Step 2: A control class creates the neural network with the specified parameters, and then feeds it the data
public class Control {
public void start(int amountOfNeurons) {
Network net = new Network(amountOfNeurons);
int[][] data = getData();
net.startLearning(data);
}
Step 3: The network iterates through the data given to learn
public class Network {
int amountOfNeurons;
Visualiser vis;
public Network(int amountOfNeurons) {
this.amountOfNeurons = amountOfNeurons;
}
public void startLearning(int[][] data) {
vis = new Visualiser();
JFrame graph = new JFrame();
graph.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
graph.setSize(1920, 1080);
graph.setTitle("Graph");
graph.getContentPane().add(vis);
graph.setResizable(false);
graph.pack();
graph.setVisible(true);
for(int i = 0; i < data.length; i++) {
new TrainTask(data[i]);
}
}
class TrainTask extends SwingWorker<Void,Void> {
int[] data;
public TrainTask(int[] data) {
this.data = data;
}
@Override
public Void doInBackground() {
for(int i = 0; i < data.length; i++) {
calculate(data);
vis.result = calculate(data);
vis.repaint();
System.out.println(i);
}
return null;
}
}
As @c0der and @Frakcool suggested I use a SwingWorker to do the heavy load, i.e. loop through the data and update the visualiser
But the program continues without waiting on the response of the SwingWorker... I would like to try invokeAndWait() so that the program waits, but the network itself is run on the EDT, so it causes the program to crash.
What should I do differently?
P.S. I would like to point out that when I don't create the settings class, and create the network from a main method in the control class, everything seems to work fine...