loadtask.java
来自「java实现浏览器等本地桌面的功能」· Java 代码 · 共 246 行
JAVA
246 行
/* * $Id: LoadTask.java,v 1.5 2005/10/10 17:01:18 rbair Exp $ * * Copyright 2005 Sun Microsystems, Inc., 4150 Network Circle, * Santa Clara, California 95054, U.S.A. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */package org.jdesktop.dataset.provider;import java.util.LinkedList;import javax.swing.Icon;import javax.swing.SwingUtilities;import org.jdesktop.dataset.DataTable;/** * * @author rbair */public abstract class LoadTask extends AbstractTask { /** * This linked list contains "LoadItem" objects. As a specific unit of data * is loaded (for instance, all of the data needed for a specific * DataTable), a new LoadItem is created and placed at the tail of the * loadQueue. The scheduleLoad method then executes and the current items in * the queue are removed and passed to the loadData method. This queue is * accessed from multiple threads (many threads put data into the queue, one * thread removes items from the queue). Synchronization occurs on the * loadQueue. */ private LinkedList loadQueue = new LinkedList(); /** * Object used for collescing multiple calls to scheduleLoad into one call * to loadData. */ private LoadNotifier loadNotifier = new LoadNotifier(); /** * The DataTables that are being loaded. */ private DataTable[] tables; private boolean loadOnEDT = true; public void setLoadOnEDT(boolean val) { loadOnEDT = val; } /** * Creates a new LoadTask. The param is the array of DataTables to be * loaded on this thread */ public LoadTask(DataTable[] tables) { this.tables = tables == null ? new DataTable[0] : tables; } /** * @inheritDoc */ public void run() { setIndeterminate(true); try { //TODO If meta-data of any kind needs to be loaded, this is the place to do it readData(tables); scheduleLoad(); setProgress(getMaximum()); } catch (Exception e) { final Throwable error = e; e.printStackTrace(); setProgress(getMaximum()); } } /** * Subclasses must implement this * method to read the data from the data store and place it in a data * structure which is <b>disconnected </b> from the DataTable. When * increments of data are ready to be loaded into the model, this method * should invoke <code>scheduleLoad</code>, which will cause * <code>loadData</code> to be called on the event dispatch thread, where * the model may be safely updated. Progress events may be fired from this * method. * <p> * A final <code>scheduleLoad</code> will be called automatically at the * conclusion of the loading process, so it is not technically necessary * for this method to call <code>scheduleLoad</code> at all unless you * want to support partial loads. * * @see #scheduleLoad * @throws Exception * if errors occur while reading data */ protected abstract void readData(final DataTable[] tables) throws Exception; /** * Invoked internally once the <code>readData</code> method calls * <code>scheduleLoad</code> to schedule the loading of an increment of * data to the DataTable. This method is called on the event dispatch thread, * therefore it is safe to mutate the model from this method. Subclasses * must implement this method to load the current contents of the * disconnected data structure into the DataTable. Note that because there * is an unpredictable delay between the time <code>scheduleLoad</code> is * called from the "reader" thread and <code>loadData</code> * executes on the event dispatch thread, there may be more data available * for loading than was available when <code>scheduleLoad</code> was * invoked. All available data should be loaded from this method. * <p> * This method should fire an appropriate progress event to notify progress * listeners when: * <ul> * <li>incremental load occurs(for determinate load operations)</li> * <li>load completes</li> * <li>exception occurs</li> * </ul> * </p> * */ protected abstract void loadData(LoadItem[] items); /** * Invoked by the <code>readData</code> method from the "reader" * thread to schedule a subsequent call to <code>loadData</code> on the * event dispatch thread. If <code>readData</code> invokes * <code>scheduleLoad</code> multiple times before <code>loadData</code> * has the opportunity to execute on the event dispatch thread, those * requests will be collapsed, resulting in only a single call to * <code>loadData</code>. * * @see #readData * @see #loadData */ protected void scheduleLoad(LoadItem item) { synchronized (loadQueue) { if (item != null) { loadQueue.addLast(item); } if (!loadNotifier.isPending()) { loadNotifier.setPending(true); if (loadOnEDT) { SwingUtilities.invokeLater(loadNotifier); } else { loadNotifier.run(); } } } } /** * Same as <code>scheduleLoad(LoadItem)</code>, except that this method * will simply schedule a load operation for any remaining items in the * queue, but will not add any items to the queue. */ protected void scheduleLoad() { scheduleLoad(null); } /** * @inheritDoc */ public String getDescription() { return "<html><h3>Loading data</h3></html>"; } /** * @inheritDoc */ public Icon getIcon() { return null; } /** * @inheritDoc */ public String getMessage() { return "Loading item " + (getProgress() + 1) + " of " + getMaximum(); } /** * @inheritDoc */ public boolean cancel() throws Exception { return false; } /** * Represents a Unit of data, ready to be loaded. */ public static final class LoadItem<E> { public DataTable table; public E data; public LoadItem(DataTable table, E data) { this.table = table; this.data = data; } } /** * */ private class LoadNotifier implements Runnable { private boolean pending = false; LoadNotifier() { } public synchronized void setPending(boolean pending) { this.pending = pending; } public synchronized boolean isPending() { return pending; } public void run() { synchronized (loadQueue) { if (loadQueue.size() > 0) { LoadItem[] items = (LoadItem[]) loadQueue .toArray(new LoadItem[loadQueue.size()]); loadQueue.clear(); loadData(items); } setPending(false); } } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?