Poprzerabiałem trochę, dodałem bloki synchronized. Wątki są już teoretycznie zsynchronizowane (w konsoli wywołują się odpowiednio), jednak do komponentu dalej litery wpadają losowo. Gdzie jeszcze powinienem to synchronizować? A może w ogóle zmienić podejście?
public class Mainwindow extends JFrame {
private class Controler {
private Character LastCharacter;
public boolean CheckAvalability (Character c){
if (LastCharacter==c) {
return false;
} else {
LastCharacter = c;
return true;
}
}
}
private class LetterWriter extends SwingWorker<Void, Character> {
Character Letter;
public LetterWriter(Character let){
Letter = let;
}
@Override
protected Void doInBackground() throws Exception {
while(!this.isCancelled()){
synchronized (Kontrolka) {
if (Kontrolka.CheckAvalability(Letter)) {
System.out.println(Letter.toString() + " Printing");
publish(Letter);
try {
Kontrolka.notifyAll();
} catch (Exception e) {
System.out.println(e);
}
} else {
System.out.println(Letter.toString() + " Waiting...");
try {
Kontrolka.wait();
} catch (Exception e) {
System.out.println(e);
}
}
}
}
return null;
}
protected void process(List<Character> chunks){
synchronized (OutputTextArea) {
for (Character let : chunks) {
OutputTextArea.append(let.toString());
}
}
}
@Override
protected void done() {
try {
get();
} catch (InterruptedException ex) {
System.out.println(ex);
} catch (ExecutionException ex) {
System.out.println(ex);
}
System.out.println("Done.");
}
}
private static final long serialVersionUID = 1L;
private JDesktopPane jDesktopPane = null;
private JButton StartButton = null;
private JButton StopButton = null;
private JTextArea OutputTextArea = null;
private Controler Kontrolka = null;
private LetterWriter ThreadA = null;
private LetterWriter ThreadB = null;
private JDesktopPane getJDesktopPane() {
if (jDesktopPane == null) {
jDesktopPane = new JDesktopPane();
jDesktopPane.setBackground(SystemColor.control);
jDesktopPane.add(getStartButton(), null);
jDesktopPane.add(getStopButton(), null);
jDesktopPane.add(getOutputTextArea(), null);
}
return jDesktopPane;
}
private JButton getStartButton() {
if (StartButton == null) {
StartButton = new JButton();
StartButton.setBounds(new Rectangle(202, 47, 63, 23));
StartButton.setText("Start");
StartButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
ThreadA.execute();
ThreadB.execute();
System.out.println("actionPerformed()"); // TODO Auto-generated Event stub actionPerformed()
}
});
}
return StartButton;
}
private JButton getStopButton() {
if (StopButton == null) {
StopButton = new JButton();
StopButton.setBounds(new Rectangle(202, 98, 62, 26));
StopButton.setText("Stop");
StopButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
ThreadA.cancel(true);
ThreadB.cancel(true);
System.out.println("actionPerformed()"); // TODO Auto-generated Event stub actionPerformed()
}
});
}
return StopButton;
}
private JTextArea getOutputTextArea() {
if (OutputTextArea == null) {
OutputTextArea = new JTextArea();
OutputTextArea.setBounds(new Rectangle(26, 23, 154, 295));
OutputTextArea.setLineWrap(true);
OutputTextArea.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
OutputTextArea.setEditable(true);
OutputTextArea.setEnabled(false);
OutputTextArea.setBorder(BorderFactory.createLineBorder(Color.black));
}
return OutputTextArea;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Mainwindow thisClass = new Mainwindow();
thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thisClass.setVisible(true);
}
});
}
public Mainwindow() {
super();
initialize();
ThreadA = new LetterWriter('A');
ThreadB = new LetterWriter('B');
Kontrolka = new Controler();
}
private void initialize() {
this.setSize(301, 382);
this.setName("Main Window");
this.setContentPane(getJDesktopPane());
this.setTitle("Lab 3");
}
}