Skip to content

Commit

Permalink
Fix GUI threadsafety errors (#541)
Browse files Browse the repository at this point in the history
Fix weird behavior due to missing thread safety, especially on Windows 10 with Java 11.
  • Loading branch information
mgmax committed Dec 8, 2019
1 parent b442fe0 commit b498e3a
Show file tree
Hide file tree
Showing 6 changed files with 260 additions and 118 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
# Temporary files:
/distribute/wintmp/
*~
*.orig

# Maven stuff:
/lib/nbproject/private/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class RefreshCameraThread extends Thread
// Constructor
public RefreshCameraThread()
{
super();
super("RefreshCameraThread");
}

// Compute update timer, ensure valid data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class QRCodeScannerThread extends Thread
// Constructor, needs QRCodeScanner
public QRCodeScannerThread(QRCodeScanner scanner)
{
super();
super("QRCodeScannerThread");
this.scanner = scanner;
active = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package de.thomas_oster.uicomponents.warnings;

import de.thomas_oster.visicut.gui.MainView;
import de.thomas_oster.visicut.gui.ThreadUtils;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
Expand All @@ -40,11 +41,13 @@ public class WarningPanel extends javax.swing.JPanel

public void removeAllWarnings()
{
// removeMessage calls messages.remove(), so we can't use foreach here!
while (messages.size() > 0)
{
removeMessage(messages.get(0));
}
ThreadUtils.runInGUIThread(()->{
// removeMessage calls messages.remove(), so we can't use foreach here!
while (messages.size() > 0)
{
removeMessage(messages.get(0));
}
});
}

/**
Expand All @@ -53,51 +56,59 @@ public void removeAllWarnings()
* @param messageId unique message identifier like 'camera error'. If null, no old message will be removed.
*/
public void addMessageOnce(final Message newMessage, String messageId) {
addMessage(newMessage);
if (messageId != null) {
removeMessageWithId(messageId, false);
messagesById.put(messageId, newMessage);
}
ThreadUtils.runInGUIThread(()->{
addMessage(newMessage);
if (messageId != null) {
removeMessageWithId(messageId, false);
messagesById.put(messageId, newMessage);
}
});
}

public void addMessage(final Message m)
{
messages.add(m);
m.setCloseListener(new ActionListener(){
public void actionPerformed(ActionEvent ae)
{
removeMessage(m);
}
ThreadUtils.runInGUIThread(()->{
messages.add(m);
m.setCloseListener(new ActionListener(){
public void actionPerformed(ActionEvent ae)
{
removeMessage(m);
}
});
this.warningContainer.add(m);
revalidate();
repaint();
setVisible(true);
});
this.warningContainer.add(m);
revalidate();
repaint();
setVisible(true);
}

public void removeMessage(final Message m) {
removeMessage(m, true);
}

public void removeMessage(final Message m, boolean hidePanelIfEmpty) {
messagesById.values().remove(m);
messages.remove(m);
warningContainer.remove(m);
m.setCloseListener(null);

revalidate();
repaint();
ThreadUtils.runInGUIThread(()->{
messagesById.values().remove(m);
messages.remove(m);
warningContainer.remove(m);
m.setCloseListener(null);

revalidate();
repaint();

if (messages.isEmpty() && hidePanelIfEmpty)
{
setVisible(false);
}
if (messages.isEmpty() && hidePanelIfEmpty)
{
setVisible(false);
}
});
}

public void removeMessageWithId(String messageId, boolean hidePanelIfEmpty) {
if (messagesById.containsKey(messageId)) {
removeMessage(messagesById.get(messageId), hidePanelIfEmpty);
}
ThreadUtils.runInGUIThread(()->{
if (messagesById.containsKey(messageId)) {
removeMessage(messagesById.get(messageId), hidePanelIfEmpty);
}
});
}

public void removeMessageWithId(String messageId) {
Expand All @@ -109,6 +120,7 @@ public void removeMessageWithId(String messageId) {
*/
public WarningPanel()
{
ThreadUtils.assertInGUIThread();
initComponents();
}

Expand Down
Loading

0 comments on commit b498e3a

Please sign in to comment.