G
gegel_als_Gast
Gast
Hallo zusammen,
ich versuche mich gerade zum ersten mal in Drag & Drop und habe dazu das Tutorial java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html#complex zur Hilfe genommen.
Mein Ziel ist, auf meinem GUI verschiedene Views (JPanels bzw. Tabs) in einen beliebigen ViewContainer (JTabbedPane) verschieben zu können, und dies mittels DnD. (wie z.B. in eclipse...).
Der Code sieht wie folgt aus:
View:
View Container:
ViewTransferHandler:
Der Drag wird sogar gestartet, ich kriege dann jedoch eine Exception bei diesem Aufruf:
(siehe Codezeile 113 von ViewContainer.java)
Die Exception sieht wie folgt aus:
Hier bin ich leider am Ende meines Lateins, da ich die übergebenden parameter auf null überprüft habe...
Hat jemand eine Idee?
Bin um jede Hilfe sehr dankbar!!
Grüsse gegel
ich versuche mich gerade zum ersten mal in Drag & Drop und habe dazu das Tutorial java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html#complex zur Hilfe genommen.
Mein Ziel ist, auf meinem GUI verschiedene Views (JPanels bzw. Tabs) in einen beliebigen ViewContainer (JTabbedPane) verschieben zu können, und dies mittels DnD. (wie z.B. in eclipse...).
Der Code sieht wie folgt aus:
View:
Code:
package com.styleskill.saf.gui.view;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import javax.swing.JLabel;
import javax.swing.JPanel;
import com.styleskill.saf.Log;
public abstract class View extends JPanel implements Transferable {
private ViewDecoration decoration;
private JPanel titlePanel;
private JLabel titleLabel;
public View(ViewDecoration _decoration) {
super();
decoration = _decoration;
}
public void doInit() {
try {
init();
} catch(Exception e) {
Log.exc(getClass(), e);
}
}
private void init() throws Exception {
setLayout(new BorderLayout());
titlePanel = new JPanel(new BorderLayout());
titleLabel = new JLabel(decoration.getCaption());
Font titleLabelFont = titleLabel.getFont();
titleLabelFont = titleLabelFont.deriveFont(Font.TRUETYPE_FONT, (float)12.0);
titleLabel.setFont(titleLabelFont);
titlePanel.add(titleLabel, BorderLayout.WEST);
add(titlePanel, BorderLayout.NORTH);
initView();
validate();
repaint();
}
public abstract void initView() throws Exception ;
public ViewDecoration getDecoration() {
return decoration;
}
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
Object result = null;
if(flavor.equals(ViewTransferHandler.viewFlavor)) {
result = this;
} else {
throw new UnsupportedFlavorException(flavor);
}
return result;
}
public DataFlavor[] getTransferDataFlavors() {
DataFlavor[] flavors = new DataFlavor[1];
flavors[0] = ViewTransferHandler.viewFlavor;
return flavors;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(ViewTransferHandler.viewFlavor);
}
}
View Container:
Code:
package com.styleskill.saf.gui.view;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import com.styleskill.saf.Log;
public class ViewContainer extends JPanel implements DropTargetListener {
private JTabbedPane tabbedPane;
private ViewTransferHandler handler;
public ViewContainer() {
try {
init();
} catch(Exception e) {
Log.exc(getClass(), e);
}
}
private void init() throws Exception {
tabbedPane = new JTabbedPane(JTabbedPane.BOTTOM, JTabbedPane.SCROLL_TAB_LAYOUT);
handler = new ViewTransferHandler();
tabbedPane.setTransferHandler(handler);
setPreferredSize(new Dimension(150, 150));
setLayout(new BorderLayout());
add(tabbedPane, BorderLayout.CENTER);
}
public void insertView(View _view) {
ViewContainerDragAdapter adapter = new ViewContainerDragAdapter();
_view.addMouseMotionListener(adapter);
_view.addMouseListener(adapter);
tabbedPane.insertTab(_view.getDecoration().getCaption(), _view.getDecoration().getIcon(),
_view, _view.getDecoration().getDescription(), tabbedPane.getTabCount());
Component tab = tabbedPane.getComponent(tabbedPane.getTabCount()-1);
Log.deb(getClass(), "Adding Listener to "+tab.getClass());
tabbedPane.validate();
tabbedPane.repaint();
validate();
repaint();
}
public View getCurrentView() {
return (View)tabbedPane.getSelectedComponent();
}
public void removeView(View _view) {
tabbedPane.removeTabAt(tabbedPane.indexOfComponent(_view));
tabbedPane.validate();
validate();
repaint();
}
public void dragEnter(DropTargetDragEvent dtde) {
Log.deb(getClass(), "Enter :"+dtde.getTransferable());
}
public void dragExit(DropTargetEvent dte) {
Log.deb(getClass(), "Exit:"+dte.toString());
}
public void dragOver(DropTargetDragEvent dtde) {
Log.deb(getClass(), "Over :"+dtde.getTransferable());
}
public void drop(DropTargetDropEvent dtde) {
Log.deb(getClass(), "Drop :"+dtde.getTransferable());
}
public void dropActionChanged(DropTargetDragEvent dtde) {
Log.deb(getClass(), "DropActionChanged :"+dtde.getTransferable());
}
class ViewContainerDragAdapter extends MouseAdapter implements MouseListener, MouseMotionListener {
private MouseEvent firstMouseEvent = null;
public void mouseReleased(MouseEvent e) {
firstMouseEvent = null;
}
public void mouseDragged(MouseEvent _e) {
if (firstMouseEvent != null) {
_e.consume();
int dx = Math.abs(_e.getX() - firstMouseEvent.getX());
int dy = Math.abs(_e.getY() - firstMouseEvent.getY());
//Arbitrarily define a 5-pixel shift as the
//official beginning of a drag.
if (dx > 5 || dy > 5) {
Log.deb(getClass(), "Mouse dragged! Source:"+_e.getSource());
handler.exportAsDrag((View)_e.getSource(), _e, ViewTransferHandler.MOVE);
firstMouseEvent = null;
}
}
}
public void mousePressed(MouseEvent e) {
firstMouseEvent = e;
e.consume();
}
public void mouseMoved(MouseEvent e) {
}
}
}
ViewTransferHandler:
Code:
package com.styleskill.saf.gui.view;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import javax.swing.JComponent;
import javax.swing.TransferHandler;
import com.styleskill.saf.Log;
public class ViewTransferHandler extends TransferHandler {
public static DataFlavor viewFlavor;
public ViewTransferHandler() {
try {
ViewTransferHandler.viewFlavor = new DataFlavor(View.class, "View");
} catch(Exception e) {
Log.exc(getClass(), e);
}
}
public int getSourceActions(JComponent c) {
return TransferHandler.MOVE;
}
public void importView(JComponent c, View _view) {
ViewContainer container = (ViewContainer)c;
Log.deb(getClass(), "imported view");
container.insertView(_view);
}
public View exportView(JComponent c) {
ViewContainer container = (ViewContainer)c;
Log.deb(getClass(), "exported view");
return container.getCurrentView();
}
public void cleanup(JComponent c, Transferable data, boolean remove) {
if(remove) {
ViewContainer container = (ViewContainer)c;
View view = (View)data;
container.removeView(view);
Log.deb(getClass(), "cleaned up");
}
}
protected Transferable createTransferable(JComponent c) {
ViewContainer container = (ViewContainer)c;
Log.deb(getClass(), "created transferable");
return container.getCurrentView();
}
public boolean importData(JComponent c, Transferable t) {
if (canImport(c, t.getTransferDataFlavors())) {
try {
View view = (View)t.getTransferData(ViewTransferHandler.viewFlavor);
Log.deb(getClass(), "Importing data");
importView(c, view);
return true;
} catch (Exception e) {
Log.exc(getClass(), e);
}
}
return false;
}
protected void exportDone(JComponent c, Transferable data, int action) {
Log.deb(getClass(), "export is done");
cleanup(c, data, action == MOVE);
}
public boolean canImport(JComponent c, DataFlavor[] flavors) {
Log.deb(getClass(), "Checking importability for "+c);
for (int i = 0; i < flavors.length; i++) {
if (ViewTransferHandler.viewFlavor.equals(flavors[i])) {
return true;
}
}
return false;
}
}
Der Drag wird sogar gestartet, ich kriege dann jedoch eine Exception bei diesem Aufruf:
(siehe Codezeile 113 von ViewContainer.java)
Code:
handler.exportAsDrag((View)_e.getSource(), _e, ViewTransferHandler.MOVE);
Die Exception sieht wie folgt aus:
Code:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.TransferHandler$DragHandler.dragGestureRecognized(Unknown Source)
at java.awt.dnd.DragGestureRecognizer.fireDragGestureRecognized(Unknown Source)
at javax.swing.TransferHandler$SwingDragGestureRecognizer.gestured(Unknown Source)
at javax.swing.TransferHandler.exportAsDrag(Unknown Source)
at com.styleskill.saf.gui.view.ViewContainer$ViewContainerDragAdapter.mouseDragged(ViewContainer.java:111)
at java.awt.Component.processMouseMotionEvent(Unknown Source)
at javax.swing.JComponent.processMouseMotionEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Hier bin ich leider am Ende meines Lateins, da ich die übergebenden parameter auf null überprüft habe...
Hat jemand eine Idee?
Bin um jede Hilfe sehr dankbar!!
Grüsse gegel