import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.ListCellRenderer;
import javax.swing.TransferHandler;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
public class Gui {
public static void main(String[] args) {
new Gui();
}
public Gui() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLayout(new BorderLayout());
JPanel listPanel = createListPanel();
frame.add(listPanel, BorderLayout.WEST);
JTree tree = createTree();
frame.add(tree, BorderLayout.CENTER);
frame.setPreferredSize(new Dimension(500, 500));
frame.pack();
frame.setVisible(true);
}
private JPanel createListPanel() {
JPanel listPanel = new JPanel();
listPanel.setLayout(new GridLayout(0, 1));
// Fist list
JList listA = new JList();
DefaultListModel modelA = new DefaultListModel();
modelA.addElement(new A("A1"));
modelA.addElement(new A("A2"));
modelA.addElement(new A("A3"));
listA.setModel(modelA);
ListCellRenderer cellRenderer = new ListABCellRenderer();
listA.setCellRenderer(cellRenderer);
listA.setTransferHandler(new TransferHandlerA());
listA.setDragEnabled(true);
listPanel.add(listA);
// Second list
JList listB = new JList();
DefaultListModel modelB = new DefaultListModel();
modelB.addElement(new B("B1"));
modelB.addElement(new B("B2"));
modelB.addElement(new B("B3"));
listB.setModel(modelB);
listB.setCellRenderer(cellRenderer);
listB.setTransferHandler(new TransferHandlerB());
listB.setDragEnabled(true);
listPanel.add(listB);
return listPanel;
}
private JTree createTree() {
JTree tree = new JTree();
TreeModelAB model = new TreeModelAB();
tree.setModel(model);
TreeCellRenderer cellRenderer = new TreeCellRendererAB();
tree.setCellRenderer(cellRenderer);
tree.setTransferHandler(new TransferHandlerTreeAB(model));
return tree;
}
/*
* Wurzeln
*/
private static class A {
String name;
List<B> childs = new ArrayList<B>();
public A(String name) {
this.name = name;
}
}
private static class B {
String name;
public B(String name) {
this.name = name;
}
}
/*
* Renderer for the lists
*/
@SuppressWarnings("serial")
private static class ListABCellRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
if (value instanceof A) {
setText("[A]:" + ((A) value).name);
} else if (value instanceof B) {
setText("[B]:" + ((B) value).name);
}
return this;
}
}
/*
* Renderer für den Tree
*/
@SuppressWarnings("serial")
private static class TreeCellRendererAB extends DefaultTreeCellRenderer {
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean sel, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel, expanded,
leaf, row, hasFocus);
setIcon(null);
if (value instanceof A) {
setBackgroundNonSelectionColor(Color.LIGHT_GRAY);
setText("[A]: " + ((A) value).name);
} else if (value instanceof B) {
setBackgroundNonSelectionColor(Color.GRAY);
setText("[B]: " + ((B) value).name);
} else {
setText("");
setBackgroundNonSelectionColor(Color.GREEN);
}
return this;
}
}
/*
* Model für den Tree
*/
private static class TreeModelAB implements TreeModel {
RootNode root = new RootNode();
List<TreeModelListener> listeners = new ArrayList<TreeModelListener>();
public TreeModelAB() {
// Das sollte später per DnD möglich sein
A a1 = new A("A41");
a1.childs.add(new B("b41"));
root.nodes.add(a1);
A a2 = new A("A42");
a2.childs.add(new B("b42"));
a2.childs.add(new B("b43"));
root.nodes.add(a2);
root.nodes.add(new A("A43"));
}
@Override
public Object getRoot() {
return root;
}
@Override
public Object getChild(Object parent, int index) {
if (parent == root) {
return root.nodes.get(index);
}
if (parent instanceof A) {
return ((A) parent).childs.get(index);
}
return null;
}
@Override
public int getChildCount(Object parent) {
if (parent == root) {
return root.nodes.size();
}
if (parent instanceof A) {
return ((A) parent).childs.size();
}
return 0;
}
@Override
public boolean isLeaf(Object node) {
return getChildCount(node) == 0;
}
@Override
public void valueForPathChanged(TreePath path, Object newValue) {
}
@Override
public int getIndexOfChild(Object parent, Object child) {
if (parent == root) {
return root.nodes.indexOf(child);
}
if (parent instanceof A) {
return ((A) parent).childs.indexOf(child);
}
return -1;
}
@Override
public void addTreeModelListener(TreeModelListener l) {
listeners.add(l);
}
@Override
public void removeTreeModelListener(TreeModelListener l) {
listeners.remove(l);
}
private static class RootNode {
List<A> nodes = new ArrayList<A>();
}
}
/*
*
* Transferhandler für die liste von A
*/
@SuppressWarnings("serial")
private static class TransferHandlerA extends TransferHandler {
public int getSourceActions(JComponent c) {
return TransferHandler.MOVE;
}
protected Transferable createTransferable(JComponent c) {
TransferableA transferable = new TransferableA();
for (Object o : ((JList) c).getSelectedValues()) {
transferable.values.add((A) o);
}
return transferable;
}
protected void exportDone(JComponent c, Transferable t, int action) {
// Nothing to do, lists should not change after export
}
}
/*
* Transferhandler für die liste von B
*/
@SuppressWarnings("serial")
private static class TransferHandlerB extends TransferHandler {
public int getSourceActions(JComponent c) {
return TransferHandler.MOVE;
}
protected Transferable createTransferable(JComponent c) {
TransferableB transferable = new TransferableB();
for (Object o : ((JList) c).getSelectedValues()) {
transferable.values.add((B) o);
}
return transferable;
}
protected void exportDone(JComponent c, Transferable t, int action) {
// Nothing to do, lists should not change after export
}
}
/*
* Transferobjekt für mehrere instanzen von A
*/
private static class TransferableA implements Transferable {
List<A> values = new ArrayList<A>();
@Override
public DataFlavor[] getTransferDataFlavors() {
System.out.println("transferFlavors (TransferableA.class)");
return new DataFlavor[] { new DataFlavor(TransferableA.class,
"A-Klasse") };
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return true;
}
@Override
public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException, IOException {
return this;
}
}
/*
* Transferobjekt für mehrere instanzen von B
*/
private static class TransferableB implements Transferable {
List<B> values = new ArrayList<B>();
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] { new DataFlavor(TransferableB.class,
"B-Klasse") };
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return true;
}
@Override
public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException, IOException {
return this;
}
}
/*
* Transferhandler für den tree
*/
@SuppressWarnings("serial")
private static class TransferHandlerTreeAB extends TransferHandler {
TreeModelAB treeModel;
public TransferHandlerTreeAB(TreeModelAB treeModel) {
this.treeModel = treeModel;
}
public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
System.out.println(transferFlavors[0]
.getDefaultRepresentationClass());
return transferFlavors.length > 0
&& transferFlavors[0].getDefaultRepresentationClass()
.equals(A.class);
}
public boolean importData(JComponent comp, Transferable t) {
System.out.println("importing");
if (t instanceof TransferableA) {
for (A a : ((TransferableA) t).values) {
treeModel.root.nodes.add(a);
}
return true;
}
return false;
}
public int getSourceActions(JComponent c) {
return NONE;
}
}
}