⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listview.java

📁 这是一个基于java编写的torrent的P2P源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/**
 * Copyright (C) 2006 Aelitis, All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * This program 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 General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * AELITIS, SAS au capital de 63.529,40 euros
 * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
 *
 */
package com.aelitis.azureus.ui.swt.views.list;

import java.util.*;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.*;

import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.config.ParameterListener;
import org.gudy.azureus2.core3.config.impl.ConfigurationManager;
import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.ui.swt.Utils;
import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
import org.gudy.azureus2.ui.swt.views.TableView.GroupTableRowRunner;
import org.gudy.azureus2.ui.swt.views.table.*;
import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnManager;
import org.gudy.azureus2.ui.swt.views.table.utils.TableStructureEventDispatcher;

import com.aelitis.azureus.ui.swt.skin.SWTSkinProperties;
import com.aelitis.azureus.ui.swt.utils.*;
import com.aelitis.azureus.ui.swt.utils.ImageLoader;

import org.gudy.azureus2.plugins.ui.tables.TableCellMouseEvent;
import org.gudy.azureus2.plugins.ui.tables.TableColumn;

/**
 * @author TuxPaper
 * @created Jun 12, 2006
 *
 */
public abstract class ListView implements UIUpdatable, Listener,
		ITableStructureModificationListener
{
	private static final boolean DEBUGADDREMOVE = false;

	// Shorter name for ConfigManager, easier to read code
	private static final ConfigurationManager configMan = ConfigurationManager.getInstance();

	private static final String CFG_SORTDIRECTION = "config.style.table.defaultSortOrder";

	private static final boolean DEBUG_SORTER = false;

	private Composite listComposite;

	private ScrolledComposite sc;

	private final SWTSkinProperties skinProperties;

	private TableColumnCore[] visibleColumns;

	/** ArrayList of ListRow */
	private ArrayList selectedRows = new ArrayList();

	private AEMonitor selectedRows_mon = new AEMonitor("ListView:SR");

	private ArrayList rows = new ArrayList();

	private Map mapDataSourceToRow = new HashMap();

	/** Monitor for both rows and mapDataSourceToRow since these two are linked */
	private AEMonitor row_mon = new AEMonitor("ListView:OTSI");

	private ListRow rowFocused = null;

	private final String sTableID;

	/** Queue added datasources and add them on refresh */
	private List dataSourcesToAdd = new ArrayList(4);

	/** Queue removed datasources and add them on refresh */
	private List dataSourcesToRemove = new ArrayList(4);

	private long lCancelSelectionTriggeredOn = -1;

	private List listenersSelection = new ArrayList();

	private List listenersCountChange = new ArrayList();

	private boolean bMouseClickIsDefaultSelection = false;

	private int iGraphicRefresh;

	protected int graphicsUpdate;

	/** Sorting functions */
	private TableColumnCore sortColumn;

	/** TimeStamp of when last sorted all the rows was */
	private long lLastSortedOn;

	private Composite headerArea;

	private TableColumnCore[] allColumns;

	public ListView(String sTableID, SWTSkinProperties skinProperties,
			Composite parent) {
		this.skinProperties = skinProperties;
		this.sTableID = sTableID;

		FormData formData;

		COConfigurationManager.addAndFireParameterListener("Graphics Update",
				new ParameterListener() {
					public void parameterChanged(String parameterName) {
						graphicsUpdate = COConfigurationManager.getIntParameter("Graphics Update");
					}
				});

		parent.setBackgroundMode(SWT.INHERIT_FORCE);
		sc = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);

		formData = new FormData();
		formData.left = new FormAttachment(0);
		formData.top = new FormAttachment(0);
		formData.right = new FormAttachment(100);
		formData.bottom = new FormAttachment(100);
		sc.setLayoutData(formData);

		//listComposite = new Composite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
		listComposite = new Composite(sc, SWT.NONE);
		listComposite.setLayout(new FormLayout());

		formData = new FormData();
		formData.left = new FormAttachment(0);
		formData.top = new FormAttachment(0);
		formData.right = new FormAttachment(100);
		formData.bottom = new FormAttachment(100);
		listComposite.setLayoutData(formData);

		sc.setContent(listComposite);
		sc.setExpandHorizontal(true);
		sc.setExpandVertical(true);

		sc.getVerticalBar().setIncrement(30);

		listComposite.addListener(SWT.MouseDoubleClick, this);
		listComposite.addListener(SWT.FocusIn, this);
		listComposite.addListener(SWT.FocusOut, this);
		listComposite.addListener(SWT.Traverse, this);
		listComposite.addListener(SWT.DefaultSelection, this);
		listComposite.addListener(SWT.KeyDown, this); // so we are a tab focus

		UIUpdaterFactory.getInstance().addUpdater(this);
		TableStructureEventDispatcher.getInstance(sTableID).addListener(this);
	}

	/**
	 * @param headerArea
	 */
	protected void setupHeader(final Composite headerArea) {
		this.headerArea = headerArea;
		FormData formData;

		Label lblCenterer = new Label(headerArea, SWT.WRAP);
		formData = new FormData(0, 0);
		formData.top = new FormAttachment(0, 0);
		formData.bottom = new FormAttachment(100, 0);
		lblCenterer.setLayoutData(formData);

		ImageLoader imgLoader = ImageLoaderFactory.getInstance();
		final Image imgSortAsc = imgLoader.getImage("image.sort.asc");
		final Image imgSortDesc = imgLoader.getImage("image.sort.desc");

		int sortWidth = Math.max(imgSortAsc.getBounds().width,
				imgSortDesc.getBounds().width) + 2;

		// set min column width to width of header
		GC gc = new GC(headerArea);
		try {
			TableColumnCore[] columns = getVisibleColumns();
			for (int i = 0; i < columns.length; i++) {
				TableColumnCore column = columns[i];
				String title = MessageText.getString(column.getTitleLanguageKey(), "");
				int oldWidth = column.getWidth();
				int minWidth = gc.textExtent(title).x + sortWidth;
				if (minWidth > oldWidth) {
					column.setWidth(minWidth);
				}
			}
		} finally {
			if (gc != null) {
				gc.dispose();
			}
		}

		headerArea.addMouseListener(new MouseListener() {

			public void mouseDoubleClick(MouseEvent e) {
			}

			public void mouseDown(MouseEvent e) {
			}

			public void mouseUp(MouseEvent e) {
				TableColumnCore[] columns = getVisibleColumns();
				int inColumn = -1;
				for (int i = 0; i < columns.length; i++) {
					Rectangle bounds = (Rectangle) headerArea.getData("Column" + i
							+ "Bounds");
					if (bounds != null && bounds.contains(e.x, e.y)) {
						inColumn = i;
						break;
					}
				}
				if (inColumn != -1) {
					setSortColumn(columns[inColumn]);
					System.out.println("sorting on " + columns[inColumn].getName());
				}
			}

		});

		headerArea.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				TableColumnCore[] columns = getVisibleColumns();

				e.gc.setForeground(skinProperties.getColor("color.list.header.fg"));

				Rectangle clientArea = headerArea.getClientArea();
				int pos = clientArea.x + ListRow.MARGIN_WIDTH;
				for (int i = 0; i < columns.length; i++) {
					int width = columns[i].getWidth();
					String key = columns[i].getTitleLanguageKey();
					String text = MessageText.getString(key, "");
					int align = columns[i].getSWTAlign();

					int drawWidth = width;

					if (columns[i].equals(sortColumn)) {
						Image img = sortColumn.isSortAscending() ? imgSortAsc : imgSortDesc;
						Rectangle bounds = img.getBounds();

						if (align == SWT.RIGHT) {
							e.gc.drawImage(img, pos + width - bounds.width, clientArea.height
									- bounds.height);
							drawWidth -= bounds.width + 2;
						} else {
							e.gc.drawImage(img, pos, clientArea.height - bounds.height);

							if (align == SWT.CENTER) {
								int adj = bounds.width / 2 + 1;
								pos += adj;
								width -= adj;
							} else {
								pos += bounds.width + 2;
								width -= bounds.width + 2;
							}
							drawWidth = width;
						}
					}

					if (text.length() > 0) {
						//Point size = e.gc.textExtent(text);

						Rectangle bounds = new Rectangle(pos, clientArea.y, drawWidth,
								clientArea.height);
						headerArea.setData("Column" + i + "Bounds", bounds);
						GCStringPrinter.printString(e.gc, text, bounds, false, false, align);
					}

					//e.gc.drawLine(pos, bounds.y, pos, bounds.y + bounds.height);
					pos += width + (ListRow.MARGIN_WIDTH * 2);
				}
			}
		});
	}

	/**
	 * @param i
	 */
	protected void moveFocus(int relative, boolean moveall) {
		int index;

		if (moveall) {
			System.err.println("moveall not supported "
					+ Debug.getCompressedStackTrace());
		}

		selectedRows_mon.enter();
		try {
			if (selectedRows.size() == 0) {
				return;
			}

			ListRow focusedRow = getRowFocused();
			ListRow firstRow = (ListRow) selectedRows.get(0);

			index = indexOf(firstRow) + relative;
			if (index < 0) {
				index = 0;
			}

			if (index >= rows.size()) {
				if (index == 0) {
					return;
				}
				index = rows.size() - 1;
			}

			ListRow newRow = (ListRow) rows.get(index);
			setSelectedRows(new ListRow[] { newRow
			});

			if (firstRow.equals(focusedRow)) {
				newRow.setFocused(true);
			}
		} finally {
			selectedRows_mon.exit();
		}
	}

	public void refreshAll(final boolean doGraphics) {
		Utils.execSWTThread(new AERunnable() {
			public void runSupport() {
				//				String s = "";
				for (int i = 0; i < rows.size(); i++) {
					ListRow row = (ListRow) rows.get(i);
					//					if (row.isVisible()) {
					//						s += i + ";";
					//					}
					row.refresh(doGraphics);
				}
				//System.out.println(sTableID + "; vis=" + s);
			}
		});
	}

	/**
	 * Process the queue of datasources to be added and removed
	 *
	 */
	public void processDataSourceQueue() {
		Object[] dataSourcesAdd = null;
		Object[] dataSourcesRemove = null;

		try {
			row_mon.enter();
			if (dataSourcesToAdd.size() > 0) {
				dataSourcesAdd = dataSourcesToAdd.toArray();
				dataSourcesToAdd.clear();

				// remove the ones we are going to add then delete
				if (dataSourcesToRemove != null && dataSourcesToRemove.size() > 0) {
					for (int i = 0; i < dataSourcesAdd.length; i++) {
						if (dataSourcesToRemove.contains(dataSourcesAdd[i])) {
							dataSourcesToRemove.remove(dataSourcesAdd[i]);
							dataSourcesAdd[i] = null;
							if (DEBUGADDREMOVE) {
								System.out.println(sTableID
										+ ": Saved time by not adding a row that was removed");
							}
						}
					}
				}
			}

			if (dataSourcesToRemove != null && dataSourcesToRemove.size() > 0) {
				dataSourcesRemove = dataSourcesToRemove.toArray();
				if (DEBUGADDREMOVE && dataSourcesRemove.length > 1) {
					System.out.println(sTableID + ": Streamlining removing "
							+ dataSourcesRemove.length + " rows");
				}
				dataSourcesToRemove.clear();
			}
		} finally {
			row_mon.exit();
		}

		if (dataSourcesAdd != null) {
			addDataSources(dataSourcesAdd, true, -1);
			if (DEBUGADDREMOVE && dataSourcesAdd.length > 1) {
				System.out.println(sTableID + ": Streamlined adding "
						+ dataSourcesAdd.length + " rows");
			}
		}

		if (dataSourcesRemove != null) {
			// for now, remove one at a time
			// TODO: all at once
			for (int i = 0; i < dataSourcesRemove.length; i++) {
				Object ds = dataSourcesRemove[i];
				removeDataSource(ds, true);
			}
		}
	}

	public void addDataSource(final Object datasource, boolean bImmediate) {
		addDataSources(new Object[] { datasource
		}, bImmediate, -1);
	}

	public void addDataSource(final Object datasource, boolean bImmediate, int pos) {
		addDataSources(new Object[] { datasource
		}, bImmediate, pos);
	}

	public void addDataSources(final Object[] dataSources, boolean bImmediate) {
		addDataSources(dataSources, bImmediate, -1);
	}

	public void addDataSources(final Object[] dataSources, boolean bImmediate,
			final int pos) {
		if (dataSources == null) {
			return;
		}

		// In order to save time, we cache entries to be added and process them
		// in a refresh cycle.  This is a huge benefit to tables that have
		// many rows being added and removed in rapid succession
		if (!bImmediate) {
			int count;
			if (DEBUGADDREMOVE) {
				count = 0;
			}

			try {
				row_mon.enter();

				if (dataSourcesToAdd == null) {
					dataSourcesToAdd = new ArrayList(4);
				}
				for (int i = 0; i < dataSources.length; i++) {
					if (!mapDataSourceToRow.containsKey(dataSources[i])) {
						dataSourcesToAdd.add(dataSources[i]);
						if (DEBUGADDREMOVE) {
							count++;
						}
					}
				}

				if (DEBUGADDREMOVE && count > 0) {
					System.out.println(sTableID + ": Queueing " + count
							+ " dataSources to add");
				}
				return;

			} finally {
				row_mon.exit();
			}
		}

		Utils.execSWTThread(new Runnable() {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -