package net.sourceforge.squirrel_sql.client.gui.builders.dndtabbedpane;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.ActionEvent;
class DndTabbedPaneDropTargetListener implements DropTargetListener
{
private DnDTabbedPaneData _dnDTabbedPaneData;
private GhostGlassPane _glassPane;
private OutwardDndTabbedPaneChanel _outwardDndTabbedPaneChanel;
private Point _glassPt = new Point();
public DndTabbedPaneDropTargetListener(DnDTabbedPaneData dnDTabbedPaneData, GhostGlassPane glassPane, OutwardDndTabbedPaneChanel outwardDndTabbedPaneChanel)
{
_dnDTabbedPaneData = dnDTabbedPaneData;
_glassPane = glassPane;
_outwardDndTabbedPaneChanel = outwardDndTabbedPaneChanel;
}
@Override
public void dragEnter(DropTargetDragEvent e)
{
if (isDragAcceptable(e))
{
e.acceptDrag(e.getDropAction());
}
else
{
e.rejectDrag();
}
}
@Override
public void dragExit(DropTargetEvent e)
{
}
@Override
public void dropActionChanged(DropTargetDragEvent e)
{
}
@Override
public void dragOver(final DropTargetDragEvent e)
{
Point glassPt = e.getLocation();
if (_dnDTabbedPaneData.getTabbedPane().getTabPlacement() == JTabbedPane.TOP || _dnDTabbedPaneData.getTabbedPane().getTabPlacement() == JTabbedPane.BOTTOM)
{
initTargetLeftRightLine(DndTabUtils.getTargetTabIndex(glassPt, _glassPane, _dnDTabbedPaneData.getTabbedPane()));
}
else
{
initTargetTopBottomLine(DndTabUtils.getTargetTabIndex(glassPt, _glassPane, _dnDTabbedPaneData.getTabbedPane()));
}
if (_dnDTabbedPaneData.isHasGhost())
{
_glassPane.setPoint(glassPt);
}
if (!_glassPt.equals(glassPt)) _glassPane.repaint();
_glassPt = glassPt;
autoScrollTest(glassPt);
}
private void autoScrollTest(Point glassPt)
{
Rectangle r = DndTabUtils.getTabAreaBounds(_dnDTabbedPaneData.getTabbedPane());
int tabPlacement = _dnDTabbedPaneData.getTabbedPane().getTabPlacement();
if (tabPlacement == SwingConstants.TOP || tabPlacement == SwingConstants.BOTTOM)
{
_dnDTabbedPaneData.getrBackward().setBounds(r.x, r.y, DndTabUtils.RWH, r.height);
_dnDTabbedPaneData.getrForward().setBounds(r.x + r.width - DndTabUtils.RWH - DndTabUtils.BUTTON_SIZE, r.y, DndTabUtils.RWH + DndTabUtils.BUTTON_SIZE, r.height);
}
else if (tabPlacement == SwingConstants.LEFT || tabPlacement == SwingConstants.RIGHT)
{
_dnDTabbedPaneData.getrBackward().setBounds(r.x, r.y, r.width, DndTabUtils.RWH);
_dnDTabbedPaneData.getrForward().setBounds(r.x, r.y + r.height - DndTabUtils.RWH - DndTabUtils.BUTTON_SIZE, r.width, DndTabUtils.RWH + DndTabUtils.BUTTON_SIZE);
}
_dnDTabbedPaneData.setrBackward(SwingUtilities.convertRectangle(_dnDTabbedPaneData.getTabbedPane().getParent(), _dnDTabbedPaneData.getrBackward(), _glassPane));
_dnDTabbedPaneData.setrForward(SwingUtilities.convertRectangle(_dnDTabbedPaneData.getTabbedPane().getParent(), _dnDTabbedPaneData.getrForward(), _glassPane));
if (_dnDTabbedPaneData.getrBackward().contains(glassPt))
{
//System.out.println(new java.util.Date() + "Backward");
clickArrowButton("scrollTabsBackwardAction");
}
else if (_dnDTabbedPaneData.getrForward().contains(glassPt))
{
//System.out.println(new java.util.Date() + "Forward");
clickArrowButton("scrollTabsForwardAction");
}
}
private void clickArrowButton(String actionKey)
{
ActionMap map = _dnDTabbedPaneData.getTabbedPane().getActionMap();
if (map != null)
{
Action action = map.get(actionKey);
if (action != null && action.isEnabled())
{
action.actionPerformed(new ActionEvent(_dnDTabbedPaneData.getTabbedPane(), ActionEvent.ACTION_PERFORMED, null, 0, 0));
}
}
}
private void initTargetLeftRightLine(int next)
{
// if (next < 0 || _dnDTabbedPaneData.getDragTabIndex() == next || next - _dnDTabbedPaneData.getDragTabIndex() == 1)
if (next < 0 || _dnDTabbedPaneData.getTabbedPane().getTabCount() < next || 0 == _dnDTabbedPaneData.getTabbedPane().getTabCount())
{
_dnDTabbedPaneData.getTargetLineRectBuffer().setRect(0, 0, 0, 0);
}
else if (next == 0)
{
Rectangle r = SwingUtilities.convertRectangle(_dnDTabbedPaneData.getTabbedPane(), _dnDTabbedPaneData.getTabbedPane().getBoundsAt(0), _glassPane);
_dnDTabbedPaneData.getTargetLineRectBuffer().setRect(r.x - DndTabUtils.LINEWIDTH / 2, r.y, DndTabUtils.LINEWIDTH, r.height);
}
else
{
Rectangle r = SwingUtilities.convertRectangle(_dnDTabbedPaneData.getTabbedPane(), _dnDTabbedPaneData.getTabbedPane().getBoundsAt(next - 1), _glassPane);
_dnDTabbedPaneData.getTargetLineRectBuffer().setRect(r.x + r.width - DndTabUtils.LINEWIDTH / 2, r.y, DndTabUtils.LINEWIDTH, r.height);
}
}
private void initTargetTopBottomLine(int next)
{
// if (next < 0 || _dnDTabbedPaneData.getDragTabIndex() == next || next - _dnDTabbedPaneData.getDragTabIndex() == 1)
if (next < 0 || _dnDTabbedPaneData.getTabbedPane().getTabCount() < next)
{
_dnDTabbedPaneData.getTargetLineRectBuffer().setRect(0, 0, 0, 0);
}
else if (next == 0)
{
Rectangle r = SwingUtilities.convertRectangle(_dnDTabbedPaneData.getTabbedPane(), _dnDTabbedPaneData.getTabbedPane().getBoundsAt(0), _glassPane);
_dnDTabbedPaneData.getTargetLineRectBuffer().setRect(r.x, r.y - DndTabUtils.LINEWIDTH / 2, r.width, DndTabUtils.LINEWIDTH);
}
else
{
Rectangle r = SwingUtilities.convertRectangle(_dnDTabbedPaneData.getTabbedPane(), _dnDTabbedPaneData.getTabbedPane().getBoundsAt(next - 1), _glassPane);
_dnDTabbedPaneData.getTargetLineRectBuffer().setRect(r.x, r.y + r.height - DndTabUtils.LINEWIDTH / 2, r.width, DndTabUtils.LINEWIDTH);
}
}
@Override
public void drop(DropTargetDropEvent e)
{
if (isDropAcceptable(e))
{
if (null != _outwardDndTabbedPaneChanel && null != _outwardDndTabbedPaneChanel.getDndTabbedPaneData() && _outwardDndTabbedPaneChanel.getDndTabbedPaneData() != _dnDTabbedPaneData)
{
int targetTabIndex = DndTabUtils.getTargetTabIndex(e.getLocation(), _glassPane, _dnDTabbedPaneData.getTabbedPane());
if(-1 == targetTabIndex)
{
targetTabIndex = _dnDTabbedPaneData.getTabbedPane().getTabCount();
}
_outwardDndTabbedPaneChanel.moveDraggedTabTo(_dnDTabbedPaneData.getTabbedPane(), targetTabIndex);
}
else
{
convertTab(_dnDTabbedPaneData.getDragTabIndex(), DndTabUtils.getTargetTabIndex(e.getLocation(), _glassPane, _dnDTabbedPaneData.getTabbedPane()));
}
e.dropComplete(true);
}
else
{
e.dropComplete(false);
}
_dnDTabbedPaneData.getTabbedPane().repaint();
}
private void convertTab(int prev, int next)
{
if (next < 0 || prev == next)
{
return;
}
Component cmp = _dnDTabbedPaneData.getTabbedPane().getComponentAt(prev);
Component tab = _dnDTabbedPaneData.getTabbedPane().getTabComponentAt(prev);
String str = _dnDTabbedPaneData.getTabbedPane().getTitleAt(prev);
Icon icon = _dnDTabbedPaneData.getTabbedPane().getIconAt(prev);
String tip = _dnDTabbedPaneData.getTabbedPane().getToolTipTextAt(prev);
boolean flg = _dnDTabbedPaneData.getTabbedPane().isEnabledAt(prev);
int tgtindex = prev > next ? next : next - 1;
_dnDTabbedPaneData.getTabbedPane().remove(prev);
_dnDTabbedPaneData.getTabbedPane().insertTab(str, icon, cmp, tip, tgtindex);
_dnDTabbedPaneData.getTabbedPane().setEnabledAt(tgtindex, flg);
//When you drag'n'drop a disabled tab, it finishes enabled and selected.
//pointed out by dlorde
if (flg) _dnDTabbedPaneData.getTabbedPane().setSelectedIndex(tgtindex);
//I have a component in all tabs (jlabel with an X to close the tab) and when i move a tab the component disappear.
//pointed out by Daniel Dario Morales Salas
_dnDTabbedPaneData.getTabbedPane().setTabComponentAt(tgtindex, tab);
}
private boolean isDragAcceptable(DropTargetDragEvent e)
{
return dragAndDropAllowed(e.getTransferable());
}
private boolean isDropAcceptable(DropTargetDropEvent e)
{
return dragAndDropAllowed(e.getTransferable());
}
private boolean dragAndDropAllowed(Transferable transferable)
{
if (transferable == null)
{
return false;
}
DataFlavor[] f = transferable.getTransferDataFlavors();
if(false == transferable.isDataFlavorSupported(f[0]))
{
return false;
}
if (null != _outwardDndTabbedPaneChanel && null != _outwardDndTabbedPaneChanel.getDndTabbedPaneData())
{
return true;
}
if (_dnDTabbedPaneData.getDragTabIndex() >= 0)
{
return true;
}
return false;
}
}