Adding background loading support to our
IssuesBrowser
isn't too tough. Create a
Thread
that loads the issues
XML
from a file or web service and populates the
issues EventList
with the result. The provided
issue XML
parser provides a callback
issueLoaded()
which allows you to show each issue
as it arrives.
import java.io.*; // a simple issues library import ca.odell.issuezilla.*; // glazed lists import ca.odell.glazedlists.*; /** * Loads issues on a background thread. * * @author <a href="mailto:jesse@odel.on.ca">Jesse Wilson</a> */ public class IssuesLoader implements Runnable, IssuezillaXMLParserHandler { /** the issues list */ private EventList issues = new BasicEventList(); /** where issues shall be found */ private String file; /** * Get the list that issues are being loaded into. */ public EventList getIssues() { return issues; } /** * Load the issues from the specified file. */ public void load(String file) { this.file = file; // start a background thread Thread backgroundThread = new Thread(this); backgroundThread.setName("Issues from " + file); backgroundThread.setDaemon(true); backgroundThread.start(); } /** * When run, this fetches the issues from the issues URL and refreshes * the issues list. */ public void run() { // load some issues try { IssuezillaXMLParser parser = new IssuezillaXMLParser(); InputStream issuesInStream = new FileInputStream(file); parser.loadIssues(issuesInStream, this); issuesInStream.close(); } catch(IOException e) { e.printStackTrace(); return; } } /** * Handles a loaded issue. */ public void issueLoaded(Issue issue) { issues.getReadWriteLock().writeLock().lock(); try { issues.add(issue); } finally { issues.getReadWriteLock().writeLock().unlock(); } } }
You'll also need to make IssuesBrowser
threadsafe:
The Swing components should be constructed on the event
dispatch thread. Using
SwingUtilities.invokeLater()
can accomplish
this.
The constructors for SortedList
and our
FilterList
s require that we have acquired the
source EventList
's write lock.
import java.util.*; import javax.swing.*; import java.awt.GridBagLayout; import java.awt.GridBagConstraints; import java.awt.Insets; // a simple issues library import ca.odell.issuezilla.*; // glazed lists import ca.odell.glazedlists.*; import ca.odell.glazedlists.swing.*; /** * An IssueBrowser is a program for finding and viewing issues. * * @author <a href="mailto:jesse@odel.on.ca">Jesse Wilson</a> */ public class IssuesBrowser implements Runnable { /** reads issues from a stream and populates the issues event list */ private IssuesLoader issueLoader = new IssuesLoader(); /** event list that hosts the issues */ private EventList issuesEventList = issueLoader.getIssues(); /** * Create an IssueBrowser for the specified issues. */ public IssuesBrowser(String file) { SwingUtilities.invokeLater(this); issueLoader.load(file); } /** * Display a frame for browsing issues. This should only be run on the Swing * event dispatch thread. */ public void run() { issuesEventList.getReadWriteLock().readLock().lock(); try { // create the transformed models SortedList sortedIssues = new SortedList(issuesEventList, new IssueComparator()); UsersSelect usersSelect = new UsersSelect(sortedIssues); FilterList userFilteredIssues = new FilterList(sortedIssues, usersSelect); JTextField filterEdit = new JTextField(10); FilterList textFilteredIssues = new FilterList(userFilteredIssues, new TextComponentMatcherEditor(...)); // create the issues table EventTableModel issuesTableModel = new EventTableModel(textFilteredIssues, new IssueTableFormat()); JTable issuesJTable = new JTable(issuesTableModel); TableComparatorChooser tableSorter = new TableComparatorChooser(issuesJTable, sortedIssues, true); JScrollPane issuesTableScrollPane = new JScrollPane(issuesJTable); // create the users list JScrollPane usersListScrollPane = new JScrollPane(usersSelect.getJList()); // create the panel JPanel panel = new JPanel(); panel.setLayout(new GridBagLayout()); panel.add(new JLabel("Filter: "), new GridBagConstraints(...)); panel.add(filterEdit, new GridBagConstraints(...)); panel.add(new JLabel("Reported By: "), new GridBagConstraints(...)); panel.add(usersListScrollPane, new GridBagConstraints(...)); panel.add(issuesTableScrollPane, new GridBagConstraints(...)); // create a frame with that panel JFrame frame = new JFrame("Issues"); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setSize(540, 380); frame.getContentPane().add(panel); frame.show(); } finally { issuesEventList.getReadWriteLock().readLock().unlock(); } } /** * Launch the IssuesBrowser from the commandline. */ public static void main(String[] args) { if(args.length != 1) { System.out.println("Usage: IssuesBrowser <file>"); return; } // create the browser IssuesBrowser browser = new IssuesBrowser(args[0]); } }