I simplified my code to share it with you guys. Right now it has 3 classes. JFrame, JInternalFrame and a Thread. JFrame creates the JInternalFrame and the JInternalFrame creates the Thread. The constructor in my thread needs an instance of the JInternalFrame to mess around with the buttons of it. So after I create the interface of my InternalFrame I create and start my Thread. Unluckily the whole JFrame freezes and the code will completely remain in the thread. I already tried to get rid of the while(true) loop in my thread. Then the JFrame freezes only for the amount of time that my sleep function needs.
Long story short: How can I let my thread actually run paralell? Without my main code waiting for any sleep times in the thread or stuff like that.
Here are my 3 classes. Sorry in advance for any stupid noob mistakes. I am still learning.
package nachgestellt;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
public class Langtons extends JFrame implements ActionListener {
private JDesktopPane desk;
private JPanel panelButtons;
JMenuBar jmb;
JMenu file;
JMenuItem open, exit;
JSlider slider;
int xInt, yInt;
Random randomGenerator = new Random();
JLabel xLabel, yLabel, speed, test;
JButton start, stop, addAnt;
JTextField xField, yField;
public Langtons() {
//Desktop
desk = new JDesktopPane();
getContentPane().add(desk, BorderLayout.CENTER);
xField = new JTextField();
yField = new JTextField();
start = new JButton("Fenster erstellen");
panelButtons = new JPanel();
panelButtons.setLayout(new GridLayout());
;
panelButtons.add(start);
panelButtons.add(xField);
panelButtons.add(yField);
start.addActionListener(this);
add(panelButtons, BorderLayout.NORTH);
setSize(new Dimension(1100, 900));
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Fenster erstellen")) {
xInt = Integer.parseInt(xField.getText());
yInt = Integer.parseInt(yField.getText());
addChild(new kind(this, xInt, yInt), this.getSize().width, this.getSize().height);
}
}
public void addChild(JInternalFrame kind, int x, int y) {
kind.setSize(370, 370);
kind.setLocation(randomGenerator.nextInt(x - kind.getSize().height), randomGenerator.nextInt(y - kind.getSize().height - 100));
kind.setDefaultCloseOperation(JInternalFrame.DISPOSE_ON_CLOSE);
desk.add(kind);
kind.setBackground(Color.blue);
kind.setVisible(true);
}
public static void main(String[] args) {
new Langtons();
}
}
package nachgestellt;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.util.ArrayList;
import javax.swing.*;
public class kind extends JInternalFrame {
Langtons hFenster;
static int nr = 0;
JPanel panelButtonsKind;
ArrayList<JButton> jbArray = new ArrayList<JButton>();
JPanel panelSpielfeld;
int posAmeise, aktuellesIcon;
public kind(Langtons la, int x, int y) {
super("Kind " + (++nr), true, true, true, true);
hFenster = la;
panelSpielfeld = new JPanel();
panelSpielfeld.setLayout(new GridLayout(y, x));
jbArray.add(new JButton());
for (int i = 1; i <= (x * y); i++) {
jbArray.add(new JButton(Integer.toString(i)));
panelSpielfeld.add(jbArray.get(i));
jbArray.get(i).setBackground(Color.WHITE);
}
jbArray.get(((x / 2) * y) - y / 2).setBackground(Color.GREEN);
posAmeise = (((x / 2) * y) - y / 2);
setLayout(new BorderLayout());
panelButtonsKind = new JPanel();
panelButtonsKind.setLayout(new GridLayout(1, 3));
add(panelButtonsKind, BorderLayout.NORTH);
add(panelSpielfeld, BorderLayout.CENTER);
setVisible(true);
this.repaint();
thread a = new thread(this);
a.start();
System.out.println("Test Message After Creation and Start of Thread");
}
public void changeColor() {
if (jbArray.get(posAmeise).getBackground().equals(Color.GREEN))
jbArray.get(posAmeise).setBackground(Color.WHITE);
else
jbArray.get(posAmeise).setBackground(Color.GREEN);
}
}
package nachgestellt;
import java.awt.Color;
public class thread extends Thread {
kind k;
public thread(kind kk) {
this.k = kk;
run();
}
public void run() {
super.run();
while (true) {
if (k.jbArray.get(k.posAmeise).getBackground().equals(Color.GREEN)) {
try {
sleep(1000);
k.changeColor();
System.out.println("Test Message Thread!");
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (k.jbArray.get(k.posAmeise).getBackground()
.equals(Color.WHITE)) {
try {
sleep(1000);
k.changeColor();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
The most immediate issues in your code are:
public thread(kind kk) {
this.k = kk;
run();
}
run()
method directly. You want to call start()
on a thread.Also, within your run method, you have:
public void run() {
super.run();
}
The super invocation is unnecessary, and you should add an @Override
annotation to improve the clarity of your code:
@Override
public void run() {
//your code
}