package com.drawbridge.vl; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; import com.drawbridge.utils.AnalyticUtils; import com.drawbridge.utils.Utils; import com.drawbridge.vl.blocks.Block; /** * Provides a wrapper for any palette object so we can control their drag * and drop actions * * @author Alistair Stead * */ public class BlockWrapper extends JComponent { private static final long serialVersionUID = -2431363841598980896L; private JComponent mSourceComponent; // Do we want a new instance to be produced? private boolean mNewInstance; public BlockWrapper(JComponent innerComponent, boolean newInstance) { mNewInstance = newInstance; mSourceComponent = innerComponent; setPreferredSize(innerComponent.getPreferredSize()); addMouseListener(mMouseAdapter); addMouseMotionListener(mMouseAdapter); } MouseAdapter mMouseAdapter = new MouseAdapter() { private Point mouseDown = null; private JComponent newInstance = null; private VLPanel mParent = VLPanel.getInstance(); @Override public void mousePressed(MouseEvent me) { if(me.getClickCount() < 2) Utils.playClick(); mouseDown = new Point(me.getX(), me.getY()); if(mNewInstance){ try { newInstance = mSourceComponent.getClass().getConstructor(mSourceComponent.getClass()).newInstance(mSourceComponent); } catch (Exception e) { Utils.out.println("Block Wrapper Exception: " + e.getMessage()); e.printStackTrace(); } if (newInstance == null) throw new RuntimeException("Could not instantiate component in BlockWrapper:" + mSourceComponent.getClass().getName()); } else{ newInstance = mSourceComponent; } newInstance.setLocation(getDragLocation(me)); // SIZE TEST newInstance.setSize(newInstance.getPreferredSize()); mParent.add(newInstance); mParent.setComponentZOrder(newInstance, 0); newInstance.validate(); mParent.repaint(); AnalyticUtils.recordNewVLBlock(); } @Override public void mouseDragged(MouseEvent me) { if (mouseDown != null && newInstance != null) { newInstance.setLocation(getDragLocation(me)); newInstance.validate(); //Notify VisualDocument of dragging MouseEvent vdMouseEvent = SwingUtilities.convertMouseEvent(me.getComponent(), me, VLPanel.getInstance().mCanvas); VLPanel.getInstance().mCanvas.notifyOfDragPosition(vdMouseEvent.getX(), vdMouseEvent.getY()); } } public Point getDragLocation(MouseEvent me) { int xOnScreen = me.getXOnScreen() - mParent.getLocationOnScreen().x - mouseDown.x; int yOnScreen = me.getYOnScreen() - mParent.getLocationOnScreen().y - mouseDown.y; return new Point(xOnScreen, yOnScreen); } @Override public void mouseReleased(MouseEvent me) { Utils.playClick(); Component [] parentComponents = mParent.getComponents(); boolean containedInSiblings = false; for(Component sibling : parentComponents){ MouseEvent meSibling = SwingUtilities.convertMouseEvent(me.getComponent(), me, sibling); if(sibling.contains(meSibling.getX(), meSibling.getY())){ if(sibling instanceof JScrollPane || sibling.getClass().isAssignableFrom(Block.class)){ containedInSiblings = true; meSibling = SwingUtilities.convertMouseEvent(me.getComponent(), me, VLPanel.getInstance().mCanvas); newInstance.removeMouseListener(this); newInstance.removeMouseMotionListener(this); newInstance.validate(); VLPanel.getInstance().mCanvas.addBlockToCanvasAndGrid((Block)newInstance, meSibling.getX(), meSibling.getY()); break; } } } if(!containedInSiblings){ mParent.remove(newInstance); newInstance = null; } mParent.repaint(); VLPanel.getInstance().mCanvas.resetDragPosition(); } }; @Override public void paint(Graphics g) { if (mSourceComponent instanceof JPanel) { for (Component comp : mSourceComponent.getComponents()) { Graphics gnew = g.create(); Point location = comp.getLocation(); gnew.translate((int) location.getX(), (int) location.getY()); comp.paint(gnew); } } else mSourceComponent.paint(g); } @Override public void paintComponents(Graphics g) { mSourceComponent.paintComponents(g); } @Override public void setMaximumSize(Dimension maximumSize) { super.setMaximumSize(maximumSize); mSourceComponent.setMaximumSize(maximumSize); mSourceComponent.doLayout(); } @Override public void setMinimumSize(Dimension minimumSize) { super.setMinimumSize(minimumSize); mSourceComponent.setMinimumSize(minimumSize); mSourceComponent.doLayout(); } @Override public void setPreferredSize(Dimension preferredSize) { super.setPreferredSize(preferredSize); mSourceComponent.setPreferredSize(preferredSize); mSourceComponent.doLayout(); } @Override public void setBounds(Rectangle r) { super.setBounds(r); mSourceComponent.setBounds(r); mSourceComponent.doLayout(); } @Override public void setBounds(int x, int y, int width, int height) { super.setBounds(x, y, width, height); mSourceComponent.setBounds(x, y, width, height); mSourceComponent.doLayout(); } @Override public void setSize(int width, int height) { super.setSize(width, height); mSourceComponent.setSize(width, height); mSourceComponent.doLayout(); } }