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

📄 dragpipeline.java

📁 定要上载质量高而定要上载质量高而定要上载质量高而定要上载质量高而定要上载质量高而
💻 JAVA
字号:
package org.flexdock.docking.drag;

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.flexdock.docking.DockingConstants;
import org.flexdock.docking.DockingPort;
import org.flexdock.docking.defaults.DefaultDockingPort;
import org.flexdock.docking.drag.effects.EffectsManager;
import org.flexdock.docking.drag.effects.RubberBand;
import org.flexdock.util.RootWindow;
import org.flexdock.util.SwingUtility;
import org.flexdock.util.Utilities;

public class DragPipeline {
    private static Log log = LogFactory.getLog(DragPipeline.class);
    
	private GlassPaneMonitor paneMonitor;
	private RootWindow[] windows;
	private HashMap rootWindowsByBounds;
	private DragGlasspane currentGlasspane;
	private DragGlasspane newGlassPane;
	private Rectangle[] windowBounds;
	private boolean heavyweightDockableSupportted;
	
	private boolean open;
	private DragOperation dragToken;
	private RubberBand rubberBand;
	
	public DragPipeline() {
		paneMonitor = new GlassPaneMonitor();
		rubberBand = EffectsManager.getRubberBand();
	}
	
	public boolean isOpen() {
		return open;
	}
	
	public void open(DragOperation token) {
		if(token==null)
			throw new NullPointerException("'token' parameter cannot be null.");
		
		if(EventQueue.isDispatchThread()) {
			openImpl(token);
			return;
		}

		
		final DragOperation dToken = token;
		try {
		    EventQueue.invokeAndWait(new Runnable() {
		        public void run() {
		            openImpl(dToken);
		        }
		    });
		} catch(Exception e) {
			log.warn(e.getMessage(), e);
		}
	}
	
	private void openImpl(DragOperation operation) {
		// check to see if we're going to support heavyweight dockables for this operation
		heavyweightDockableSupportted = Boolean.getBoolean(DockingConstants.HEAVYWEIGHT_DOCKABLES);
		
		this.dragToken = operation;

		// turn the current drag operation on
		setCurrentDragOperation(operation);
		
		windows = RootWindow.getVisibleWindows();
		
		windowBounds = new Rectangle[windows.length];
		rootWindowsByBounds = new HashMap();
		
		for(int i=0; i<windows.length; i++) {
			applyGlassPane(windows[i], createGlassPane());
			windowBounds[i] = windows[i].getBounds();
			rootWindowsByBounds.put(windowBounds[i], windows[i]);
		}
		
		// kill the rubberband if floating is not allowed
		if(!DragManager.isFloatingAllowed(operation.getDockableReference()))
			rubberBand = null;

		operation.start();
		open = true;
	}

	private DragGlasspane createGlassPane() {
		DragGlasspane pane = new DragGlasspane();
		pane.addMouseListener(paneMonitor);
		return pane;
	}
	
	private void applyGlassPane(RootWindow win, DragGlasspane pane) {
		pane.setRootWindow(win);
		pane.setCachedGlassPane(win.getGlassPane());
		win.setGlassPane(pane);
		pane.setVisible(true);
	}
		
	

	public void close() {
		if(!open)
			return;
		
		clearRubberBand();
		for(int i=0; i<windows.length; i++) {
			Component cmp = windows[i].getGlassPane();
			if(cmp instanceof DragGlasspane) {
				DragGlasspane pane = (DragGlasspane)cmp;
				pane.setVisible(false);
				cmp = pane.getCachedGlassPane();
//				pane.dispose();
				windows[i].setGlassPane(cmp);
				windows[i] = null;
			}
		}
		
		windowBounds = null;
		rootWindowsByBounds.clear();
		// turn the current drag operation off
		setCurrentDragOperation(null);
		open = false;
	}

	public void processDragEvent(MouseEvent me) {
		if(!open)
			return;
		
		if(EventQueue.isDispatchThread()) {
			processDragEventImpl(me);
			return;
		}
		
		final MouseEvent evt = me;
		EventQueue.invokeLater(new Runnable() {
			public void run() {
			    processDragEventImpl(evt);
			}
		});
	}
	
	private void processDragEventImpl(MouseEvent me) {
		dragToken.updateMouse(me);

		if(heavyweightDockableSupportted)
			preprocessHeavyweightDockables();
		
		me.consume();

		// hide the rubber band
		clearRubberBand();
		
		// track whether or not we're currently over a window
		dragToken.setOverWindow(newGlassPane!=null);

		// if the glasspane hasn't changed, then reprocess on the current glasspane
		if(newGlassPane==currentGlasspane) {
			dontSwitchGlassPanes();
			return;
		}
		
		// process transitions from a glasspane to a null area
		if(newGlassPane==null) {
			transitionToNullArea();
			return;
		}
		
		// process transitions from null area to a glasspane
		if(currentGlasspane==null) {
			transitionFromNullArea(newGlassPane);
			return;
		}

		// otherwise, transition from one glasspane to another
		// clear out the old glasspane
		currentGlasspane.clear();
		// reassign to the new glasspane
		currentGlasspane = newGlassPane;
		// now process the new glasspane and redraw the rubberband
		Rectangle screenRect = dragToken.getDragRect(true);
		currentGlasspane.setPostPainter(getPostPainter(screenRect));
		currentGlasspane.processDragEvent(dragToken);
	}

	private void dontSwitchGlassPanes() {
		// just redraw the rubberband if there's no current glasspane
		Rectangle screenRect = dragToken.getDragRect(true);
		if(currentGlasspane==null) {
			drawRubberBand(screenRect);
			return;
		}

		
		// otherwise, process the drag event on the current glasspane
		// and repaint it.
		// TODO: Fix post-painter on unchanged glasspane.
//		currentGlasspane.setPostPainter(getPostPainter(screenRect));
		currentGlasspane.setPostPainter(null);
		currentGlasspane.processDragEvent(dragToken);
	}
	
	private void transitionToNullArea() {
		// set the new glasspane reference
		DragGlasspane pane = currentGlasspane;
		currentGlasspane = null;
		
		// clear out the old glasspane and redraw the rubberband
		Rectangle screenRect = dragToken.getDragRect(true);
		pane.setPostPainter(null);
		pane.clear();
	}
	
	private void transitionFromNullArea(DragGlasspane newGlassPane) {
		// set the new glasspane reference
		currentGlasspane = newGlassPane;
		
		// process the new glasspane
		Rectangle screenRect = dragToken.getDragRect(true);
		currentGlasspane.setPostPainter(null);
		currentGlasspane.processDragEvent(dragToken);
	}

	
	private void setCurrentGlassPane(DragGlasspane gp) {
		newGlassPane = gp;
	}

	
	private Runnable getPostPainter(final Rectangle rect) {
//		if(!ResourceManager.isWindowsPlatform())
//			return null;
		
		return new Runnable() {
			public void run() {
				deferRubberBandDrawing(rect);
//				drawRubberBand(rect);
			}
		};
	}
	private void deferRubberBandDrawing(final Rectangle rect) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
			    drawRubberBand(rect);
			}
		});
	}
	
	private void drawRubberBand(Rectangle rect) {
		paintRubberBand(rect);
	}
	
	
	private class GlassPaneMonitor extends MouseAdapter {
		public void mouseEntered(MouseEvent me) {
			Object obj = me.getSource();
			if(obj instanceof DragGlasspane) {
				setCurrentGlassPane((DragGlasspane)obj);
			}
		}
		
		public void mouseExited(MouseEvent me) {
			setCurrentGlassPane(null);
		}
	}
	
	public DragOperation getDragToken() {
		return dragToken;
	}
	
	private void clearRubberBand() {
		if(rubberBand!=null)
			rubberBand.clear();
	}
	
	private void paintRubberBand(Rectangle rect) {
		if(rubberBand!=null)
			rubberBand.paint(rect);
	}
	
	private void setCurrentDragOperation(DragOperation operation) {
		DragOperation current = DragManager.getCurrentDragOperation();
		if(operation==current)
			return;
		
		DockingPort srcPort = operation==null? current.getSourcePort(): operation.getSourcePort();
		DragManager.setCurrentDragOperation(operation);
		if(srcPort instanceof Component)
			SwingUtility.repaint((Component)srcPort);
		
		// TODO: We want to get rid of this code in the future.  I don't like
		// having a public setDragInProgress() method on the default docking port
		// and having to know to call it at this level.  If the default docking port
		// is interested in whether a drag is currently in progress, it should 
		// register some type of listener and handle its personal business internally
		// with its own code. 
		if(srcPort instanceof DefaultDockingPort) {
			DefaultDockingPort port = (DefaultDockingPort)srcPort;
			port.setDragInProgress(operation!=null);
		}
	}
		
	private void preprocessHeavyweightDockables() {
		RootWindow targetWindow = getTargetWindow();
		
		if(newGlassPane==null && targetWindow!=null) {
			Component gp = targetWindow.getGlassPane();
			if(gp instanceof DragGlasspane) {
				setCurrentGlassPane((DragGlasspane)gp);
			}
		}
	}
	
	private RootWindow getTargetWindow() {
		Point screenLoc = dragToken.getCurrentMouse(true);
		for(int i=0; i<windowBounds.length; i++) {
			if(windowBounds[i].contains(screenLoc))
				return (RootWindow)rootWindowsByBounds.get(windowBounds[i]);
		}
		return null;
	}
	

}

⌨️ 快捷键说明

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