tableview.java

来自「Azureus is a powerful, full-featured, cr」· Java 代码 · 共 1,316 行 · 第 1/3 页

JAVA
1,316
字号
  				  TableCellCore cell = (TableCellCore)shell.getData("TableCellCore");
            cell.invokeToolTipListeners(TableCellCore.TOOLTIPLISTENER_HOVERCOMPLETE);
  					shell.dispose();
  					break;
  			}
  		}
  	};
  
  	Listener tableListener = new Listener () {
  		Shell shell = null;
  		Label label = null;
  		public void handleEvent (Event event) {
  			switch (event.type) {
  				case SWT.Dispose:
  				case SWT.KeyDown:
  				case SWT.MouseMove: {
  					if (shell == null) break;
  					shell.dispose ();
  					shell = null;
  					label = null;
  					break;
  				}
  				case SWT.MouseHover: {
						if (shell != null  && !shell.isDisposed())
						  shell.dispose();

  					TableItem item = table.getItem (new Point (event.x, event.y));
  					if (item == null)
  					  return;
            TableRowCore row = (TableRowCore)item.getData("TableRow");
            if (row == null)
              return;
            int iColumn = getColumnNo(event.x);
            if (iColumn < 0)
              return;
            TableColumn tcColumn = table.getColumn(iColumn);
            String sCellName = (String)tcColumn.getData("Name");
            if (sCellName == null)
              return;
            
            TableCellCore cell = row.getTableCellCore(sCellName);
            if (cell == null)
              return;
            cell.invokeToolTipListeners(TableCellCore.TOOLTIPLISTENER_HOVER);
            Object oToolTip = cell.getToolTip();
            
            // TODO: support composite, image, etc
            if (oToolTip == null || !(oToolTip instanceof String))
              return;
            String sToolTip = (String)oToolTip;

						Display d = table.getDisplay();
						if (d == null)
						  return;

            // We don't get mouse down notifications on trim or borders..
						shell = new Shell (table.getShell(), SWT.ON_TOP);
            FillLayout f = new FillLayout();
            try {
              f.marginWidth = 3;
              f.marginHeight = 1;
            } catch (NoSuchFieldError e) {
              /* Ignore for Pre 3.0 SWT.. */
            }
						shell.setLayout(f);
						shell.setBackground(d.getSystemColor(SWT.COLOR_INFO_BACKGROUND));

						label = new Label(shell, SWT.WRAP);
						label.setForeground(d.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
						label.setBackground(d.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
						shell.setData("_TABLEITEM", item);
						shell.setData("TableCellCore", cell);
						label.setText(sToolTip);
						label.addListener(SWT.MouseMove, labelListener);
						label.addListener(SWT.MouseDown, labelListener);
						label.addListener(SWT.MouseExit, labelListener);
						shell.addListener(SWT.MouseMove, labelListener);
						shell.addListener(SWT.MouseDown, labelListener);
						shell.addListener(SWT.MouseExit, labelListener);
						shell.addListener(SWT.MouseDoubleClick, labelListener);
						// compute size on label instead of shell because label
						// calculates wrap, while shell doesn't
						Point size = label.computeSize (SWT.DEFAULT, SWT.DEFAULT);
						if (size.x > 600) {
  						size = label.computeSize (600, SWT.DEFAULT, true);
						}
						size.x += shell.getBorderWidth() * 2;
						size.y += shell.getBorderWidth() * 2;
            try {
              size.x += shell.getBorderWidth() * 2 + (f.marginWidth * 2);
              size.y += shell.getBorderWidth() * 2 + (f.marginHeight * 2);
            } catch (NoSuchFieldError e) {
              /* Ignore for Pre 3.0 SWT.. */
            }
						Point pt = table.toDisplay (event.x - 1, event.y - size.y + 2);
            Rectangle displayRect;
            try {
            	displayRect = shell.getMonitor().getClientArea();
            } catch (NoSuchMethodError e) {
              displayRect = shell.getDisplay().getClientArea();
            }
            if (pt.x + size.x > displayRect.x + displayRect.width) {
              pt.x = displayRect.x + displayRect.width - size.x;
            }

						shell.setBounds(pt.x, (pt.y < 0) ? 0 : pt.y, size.x, size.y);
						shell.setVisible(true);
					}
				}
  		}
  	};
  	table.addListener (SWT.Dispose, tableListener);
  	table.addListener (SWT.KeyDown, tableListener);
  	table.addListener (SWT.MouseMove, tableListener);
  	table.addListener (SWT.MouseHover, tableListener);

    table.setHeaderVisible(true);
  }

  /** Creates the Context Menu.
   *
   * @return a new Menu object
   */
  public Menu createMenu() {
    return new Menu(panel.getShell(), SWT.POP_UP);
  }

  /** Fill the Context Menu with items.  Only called at TableView initialization
   * and when Table Structure changes.
   *
   * By default, a "Edit Columns" menu and a Column specific menu is set up.
   *
   * @param menu Menu to fill
   */
  public void fillMenu(Menu menu) {
    menuThisColumn = new Menu(panel.getShell(), SWT.DROP_DOWN);
    final MenuItem itemThisColumn = new MenuItem(menu, SWT.CASCADE);
    itemThisColumn.setMenu(menuThisColumn);

    final MenuItem itemChangeTable = new MenuItem(menu, SWT.PUSH);
    Messages.setLanguageText(itemChangeTable, "MyTorrentsView.menu.editTableColumns");
    itemChangeTable.setImage(ImageRepository.getImage("columns"));
    
    menu.addListener(SWT.Show, new Listener() {
      public void handleEvent(Event e) {
        addThisColumnSubMenu(getColumnNo(iMouseX));
      }
    });

    itemChangeTable.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event e) {
        new TableColumnEditorWindow(table.getDisplay(), tableColumns,
                                    TableStructureEventDispatcher.getInstance(sTableID));
      }
    });
    
    // Add Plugin Context menus..
    TableContextMenuItem[] items = TableContextMenuManager.getInstance().getAllAsArray(sTableID);
    if (items.length > 0) {
      new MenuItem(menu, SWT.SEPARATOR);

      for (int i = 0; i < items.length; i++) {
        final TableContextMenuItemImpl contextMenuItem = (TableContextMenuItemImpl)items[i];
        final MenuItem menuItem = new MenuItem(menu, SWT.PUSH);

        Messages.setLanguageText(menuItem, contextMenuItem.getResourceKey());
        menuItem.addListener(SWT.Selection, new SelectedTableRowsListener() {
          public void run(TableRowCore row) {
            contextMenuItem.invokeListeners(row);
          }
        });
      }
    }
  }

  /* SubMenu for column specific tasks. 
   *
   * @param iColumn Column # that tasks apply to.
   */
  private void addThisColumnSubMenu(int iColumn) {
    MenuItem item;

    // Dispose of the old items
    MenuItem[] oldItems = menuThisColumn.getItems();
    for (int i = 0; i < oldItems.length; i++) {
      oldItems[i].dispose();
    }

    item = menuThisColumn.getParentItem();
    if (iColumn == -1) {
      item.setEnabled(false);
      item.setText(MessageText.getString("GenericText.column"));
      return;
    }

    item.setEnabled(true);

    menu.setData("ColumnNo", new Long(iColumn));

    TableColumn tcColumn = table.getColumn(iColumn);
    item.setText("'" + tcColumn.getText() + "' " + 
                 MessageText.getString("GenericText.column"));

    String sColumnName = (String)tcColumn.getData("Name");
    if (sColumnName != null) {
      addThisColumnSubMenu(sColumnName, menuThisColumn);
    }

    if (menuThisColumn.getItemCount() > 0) {
      new MenuItem(menuThisColumn, SWT.SEPARATOR);
    }

    item = new MenuItem(menuThisColumn, SWT.PUSH);
    Messages.setLanguageText(item, "MyTorrentsView.menu.thisColumn.sort");
    item.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event e) {
        int iColumn = ((Long)menu.getData("ColumnNo")).intValue();
        table.getColumn(iColumn).notifyListeners(SWT.Selection, new Event());
      }
    });

    item = new MenuItem(menuThisColumn, SWT.PUSH);
    Messages.setLanguageText(item, "MyTorrentsView.menu.thisColumn.remove");
    item.setEnabled(false);

    item = new MenuItem(menuThisColumn, SWT.PUSH);
    Messages.setLanguageText(item, "MyTorrentsView.menu.thisColumn.toClipboard");
    item.addListener(SWT.Selection, new Listener() {
      public void handleEvent(Event e) {
        String sToClipboard = "";
        int iColumn = ((Long)menu.getData("ColumnNo")).intValue();
        TableItem[] tis = table.getSelection();
        for (int i = 0; i < tis.length; i++) {
          if (i != 0) sToClipboard += "\n";
          sToClipboard += tis[i].getText(iColumn);
        }
        new Clipboard(panel.getDisplay()).setContents(new Object[] { sToClipboard }, 
                                                      new Transfer[] {TextTransfer.getInstance()});
      }
    });

    // Add Plugin Context menus..
    TableColumnCore tc = (TableColumnCore)tcColumn.getData("TableColumnCore");
    TableContextMenuItem[] items = tc.getContextMenuItems();
    if (items.length > 0) {
      new MenuItem(menuThisColumn, SWT.SEPARATOR);

      for (int i = 0; i < items.length; i++) {
        final TableContextMenuItemImpl contextMenuItem = (TableContextMenuItemImpl)items[i];
        final MenuItem menuItem = new MenuItem(menuThisColumn, SWT.PUSH);

        Messages.setLanguageText(menuItem, contextMenuItem.getResourceKey());
        menuItem.addListener(SWT.Selection, new SelectedTableRowsListener() {
          public void run(TableRowCore row) {
            contextMenuItem.invokeListeners(row);
          }
        });
      }
    }
  }
  
  /** Create a SubMenu for column specific tasks.  Everytime the user opens
   * the context menu, the "This Column" submenu is cleared, and this function
   * is called to refill it.
   *
   * @param sColumnName The name of the column the user clicked on
   * @param menuThisColumn the menu to fill with MenuItems
   */
  public void addThisColumnSubMenu(String sColumnName, Menu menuThisColumn) {
/*  // Template code
    if (sColumnName.equals("xxx")) {
      item = new MenuItem(menuThisColumn, SWT.PUSH);
      Messages.setLanguageText(item, "xxx.menu.xxx");
      item.setImage(ImageRepository.getImage("xxx"));
      item.addListener(SWT.Selection, new Listener() {
        public void handleEvent(Event e) {
          // Code here
        }
      });
*/
  }

  /** IView.getComposite()
   * @return the composite for this TableView
   */
  public Composite getComposite() {
    return panel;
  }

  /** IView.refresh(), called when the GUI needs an update */
  public void refresh() {
  	try{
  		this_mon.enter();
  
	    if(getComposite() == null || getComposite().isDisposed())
	      return;
	
	    if (checkColumnWidthsEvery != 0 && 
	        (loopFactor % checkColumnWidthsEvery) == 0) {
	      TableColumn[] tableColumnsSWT = table.getColumns();
	      for (int i = 0; i < tableColumnsSWT.length; i++) {
	        TableColumnCore tc = (TableColumnCore)tableColumnsSWT[i].getData("TableColumnCore");
	        if (tc != null && tc.getWidth() != tableColumnsSWT[i].getWidth()) {
	          tc.setWidth(tableColumnsSWT[i].getWidth());
	
	          int columnNumber = table.indexOf(tableColumnsSWT[i]);
	          locationChanged(columnNumber);
	        }
	      }
	    }
	
	    if (bSortScheduled) {
	      bSortScheduled = false;
	      sorter.sortColumn();
	    } else {
	      sorter.reOrder(false);
	    }
	
	    final int topIndex = table.getTopIndex();
	    final int bottomIndex = topIndex + (table.getClientArea().height / table.getItemHeight());
	    
	    //Refresh all items in table...
	    runForAllRows(new GroupTableRowRunner() {
	      public void run(TableRowCore row) {
	        int index = row.getIndex();
	        // If the row is being shown, update it.  Otherwise, just update
	        // the cell being sorted.
	        if (index >= topIndex && index <= bottomIndex) {
	          // Every N GUI updates we refresh graphics
	          row.refresh((loopFactor % graphicsUpdate) == 0);
	        } else {
	          TableCellCore cell = row.getTableCellCore(sorter.getLastField());
	          if (cell != null)
	            cell.refresh();
	        }
	      }
	    });
	
	    Utils.alternateTableBackground(table);
	    loopFactor++;
  	}finally{
  		
  		this_mon.exit();
  	}
  }

  private void locationChanged(final int iStartColumn) {
    if (getComposite() == null || getComposite().isDisposed())
      return;    
    
    runForAllRows(new GroupTableRowRunner() {
      public void run(TableRowCore row) {
        row.locationChanged(iStartColumn);
      }
    });
  }

  private void doPaint(final GC gc) {
    if (getComposite() == null || getComposite().isDisposed())
      return;    
    
    runForAllRows(new GroupTableRowRunner() {
      public void run(TableRowCore row) {
        row.doPaint(gc);
      }
    });
  }

  /** IView.delete: This method is caled when the view is destroyed.
   * Each color instanciated, images and such things should be disposed.
   * The caller is the GUI thread.
   */
  public void delete() {
    TableStructureEventDispatcher.getInstance(sTableID).removeListener(this);
    for (int i = 0; i < tableColumns.length; i++)
      tableColumns[i].saveSettings();

    removeAllTableRows();
    if (table != null && !table.isDisposed())
      table.dispose();
    COConfigurationManager.removeParameterListener("ReOrder Delay", sorter);
    COConfigurationManager.removeParameterListener("Graphics Update", this);
    Colors.getInstance().removeColorsChangedListener(this);
  }

  /** IView.getData: Data 'could' store a key to a language file, in order to 
   * support multi-language titles
   *
   * @return a String which is the key of this view title.
   */
  public String getData() {
    return sPropertiesPrefix + ".title.short";
  }

  /** IView.getFullTitle:Called in order to set / update the title of this View
   * @return the full title for the view
   */
  public String getFullTitle() {
    return MessageText.getString(sPropertiesPrefix + ".title.full");
  }

  /** Adds a dataSource to the table as a new row.  If the data source is
   * already added, a new row will not be added.  This function runs 
   * asynchronously, so the rows creation is not guaranteed directly after
   * calling this function.
   *
   * @param dataSource data source to add to the table
   */
  public void addDataSource(final Object dataSource) {
  	try{
  		this_mon.enter();
 
	    try {
	      if ( 	objectToSortableItem.containsKey(dataSource) || 
	      		panel.isDisposed() ||
				table.isDisposed()){
	      
	        return;
	      }
	      
	      try{
	      	objectToSortableItem_mon.enter();
	        // Since adding to objectToSortableItem is async, there's a chance
	        // the item will not be stored in objectToSortableItem before another
	        // call here.  So, add it now and null it
	        objectToSortableItem.put(dataSource, null);
	      }finally{
	      	
	      	objectToSortableItem_mon.exit();
	      }
	      
	      final Display display = panel.getDisplay();
	      // syncExec is evil because we eventually end up in a sync lock.
	      // So, use async, then wait for it to finish
	      display.asyncExec(new AERunnable() {
	        public void runSupport() {
	          TableRowImpl row = new TableRowImpl(TableView.this, dataSource, 
	                                              bSkipFirstColumn);
	

⌨️ 快捷键说明

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