test.ca.odell.glazedlists.swing.SimultaneousUpdatesTest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of glazedlists_java15 Show documentation
Show all versions of glazedlists_java15 Show documentation
Event-driven lists for dynamically filtered and sorted tables
/* Glazed Lists (c) 2003-2006 */
/* http://publicobject.com/glazedlists/ publicobject.com,*/
/* O'Dell Engineering Ltd.*/
package ca.odell.glazedlists.swing;
import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.impl.testing.ListConsistencyListener;
import ca.odell.glazedlists.matchers.AbstractMatcherEditor;
import ca.odell.glazedlists.matchers.Matcher;
import junit.framework.TestCase;
import javax.swing.*;
import java.util.Random;
/**
* Make sure we can handle multiple updates from different sources.
*
* @author Jesse Wilson
*/
public class SimultaneousUpdatesTest extends TestCase {
/**
* This test verifies that we can have two threads changing the data and
* everything will still be consistent as long as proper locks are held.
*/
public synchronized void testCompetingWriters() {
// prepare a list with a Swing view
EventList list = new BasicEventList();
EvenOrAllMatcherEditor matcherEditor = new EvenOrAllMatcherEditor();
FilterList filterList = new FilterList(list, matcherEditor);
EventList swingSafe = GlazedListsSwing.swingThreadProxyList(filterList);
// make sure everything's always consistent
ListConsistencyListener.install(swingSafe);
// write using a background thread
Thread backgroundThread = new Thread(new AddThenRemoveOnList(list));
backgroundThread.start();
// also write using a foreground thread
try {
for(int i = 0; i < 500; i++) {
SwingUtilities.invokeLater(new FilterUnfilter(matcherEditor));
wait(10);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
// join the other thread to finish up
try {
backgroundThread.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
private static class FilterUnfilter implements Runnable {
private EvenOrAllMatcherEditor matcherEditor;
public FilterUnfilter(EvenOrAllMatcherEditor matcherEditor) {
this.matcherEditor = matcherEditor;
}
public synchronized void run() {
matcherEditor.setEven();
matcherEditor.setAll();
}
}
/**
* Add five values, then remove them.
*/
private static class AddThenRemoveOnList implements Runnable {
private final Random dice = new Random(15);
private EventList list;
public AddThenRemoveOnList(EventList list) {
this.list = list;
}
public synchronized void run() {
try {
for(int j = 0; j < 500; ) {
list.getReadWriteLock().writeLock().lock();
try {
int i = j;
j += dice.nextInt(3);
for(; i < j; i++) {
list.add(new Integer(i));
}
} finally {
list.getReadWriteLock().writeLock().unlock();
}
wait(10);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
/**
* Match only odd or even values.
*/
private static class EvenOrAllMatcherEditor extends AbstractMatcherEditor {
public void setAll() {
fireMatchAll();
}
public void setEven() {
fireChanged(new EvenMatcherEditor());
}
private static class EvenMatcherEditor implements Matcher {
public boolean matches(Integer item) {
return item.intValue() % 2 == 0;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy