Hi,

for the last week I've been tying to implement the following task with JUNG library:

A graph should be created. Each vertex should be either JPanel(preferrably) or JFrame. These vertexes will contain random GUI items(buttons, textfields, dropdown menus, etc) and these should be fully functional.

So far I succeded in creating the graph with the JPanels and JFrames as vertexes, but they are none functional. My investigation shows that the vertexes are out of Focus. I tried to execute functions like setFocusable(true); requestfocus(); and added a focus listener, but it showed that the focus is always on the Visualization Viewer instance.


So my questions:
1. How can I set the focus on the GUI vertexes?
2. If focus is not the solution to my problem, what should I do make the vertex GUIs active?
3. A bit off-topic: currently my vertexes can be picked and moved only if they are selected at the upper left corner of the JPanel/JFrame. How can I make the whole area of the JPanel/JFrame pickable?

Here is my code:

Java Code:
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.geom.Point2D;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

import edu.uci.ics.jung.algorithms.layout.CircleLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.DirectedSparseGraph;
import edu.uci.ics.jung.visualization.RenderContext;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.picking.PickedState;
import edu.uci.ics.jung.visualization.renderers.Renderer;
import edu.uci.ics.jung.visualization.transform.shape.GraphicsDecorator;


class MyFocusListener implements FocusListener
{
	@Override
	public void focusGained(FocusEvent fe) {
		// TODO Auto-generated method stub
		Object obj = fe.getSource();
		System.out.println(obj.getClass() + " gained focus");
	}
	@Override
	public void focusLost(FocusEvent fe) {
		// TODO Auto-generated method stub
		Object obj = fe.getSource();
		System.out.println(obj.getClass() + " lost focus");
	}
};

public class GraphPanel extends Container
{
	static final long serialVersionUID = 420001L;
	DirectedSparseGraph<Number, Number> graph = null;
	VisualizationViewer<Number, Number> vv = null;
	PickedState<Number> pickedState = null;

	public GraphPanel(Number[][] nodes_list)
	{
		try
		{
			graph = new DirectedSparseGraph<Number, Number>();
			construct_graph(nodes_list);

			vv = new VisualizationViewer<Number, Number>
						(new CircleLayout<Number, Number>(graph), new Dimension(400, 400));
			vv.getRenderer().setVertexRenderer(new MyRenderer());

			vv.addFocusListener(new MyFocusListener());
			
			// The vertex pick listener
			pickedState = vv.getPickedVertexState();
			pickedState.addItemListener(new ItemListener()
			{
			    @Override
			    public void itemStateChanged(ItemEvent e)
			    {
			        Object subject = e.getItem();
			        if (subject instanceof Number)
			        {
			        	Number vertex = (Number) subject;
			            if (pickedState.isPicked(vertex))
			            {
			                System.out.println("Vertex " + vertex + " is now selected");
			            }
			            else
			            {
			                System.out.println("Vertex " + vertex + " no longer selected");
			            }
			            
		                if(e.getStateChange() == ItemEvent.SELECTED) 
		                {
		                	System.out.println("Vertex " + vertex + " state is:" + e.getStateChange());
		                } 
		                else 
		                {
		                	System.out.println("Vertex " + vertex + " state is:" + e.getStateChange());
		                }
			            
			        }
			    }
			});

			// The following code adds capability for mouse picking of
			// vertices/edges. Vertices can even be moved!
			final DefaultModalGraphMouse<Number, Number> graphMouse = new DefaultModalGraphMouse<Number, Number>();
			vv.setGraphMouse(graphMouse);
			graphMouse.setMode(ModalGraphMouse.Mode.PICKING);
		}
		catch (Exception e)
		{
			System.err.println("Failed to construct graph!\n");
			System.err.println("Caught Exception: " + e.getMessage());
		}
	}

	public void attach_to_frame(JFrame frame)
	{
		frame.setContentPane(vv);
	}

	private void construct_graph(Number[][] nodes_list)
	{
		int i = 0;
		for(i=0; i<nodes_list.length; i++)
		{
			graph.addVertex(i);
			graph.addEdge(nodes_list[i][0], nodes_list[i][1], nodes_list[i][2]);
		}
	}

	static class MyRenderer extends JPanel implements Renderer.Vertex<Number, Number>
	{
		static final long serialVersionUID = 420000L;
		@Override
		public void paintVertex(RenderContext<Number, Number> rc,
								Layout<Number, Number> layout, Number vertex)
		{
			System.out.printf("%d: Running paintVertex()\n", System.currentTimeMillis());
			try
			{
				GraphicsDecorator graphicsContext = rc.getGraphicsContext();
				Point2D center = layout.transform(vertex);
				Dimension size = new Dimension(100, 80);
				
				System.out.printf("(int)center.getX() = %d (int)center.getY() = %d: Running paintVertex()\n", (int)center.getX(), (int)center.getY());
				
				JPanel sv = new JPanel();
				sv.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				sv.setBackground(Color.GREEN);
				sv.setPreferredSize(size);
				JButton b = new JButton("Button1");
				b.addActionListener(new ActionListener()
				{
					@Override
					public void actionPerformed(ActionEvent arg0) 
					{
						// TODO Auto-generated method stub
						 System.out.println("Fucking button!");
					}
				});
				b.setFocusable(true);
				b.requestFocus();
				sv.add(b);
				sv.grabFocus();
				sv.addFocusListener(new MyFocusListener());

				graphicsContext.draw(sv, rc.getRendererPane(), (int)center.getX(), 
			             			 (int)center.getY(), size.width, size.height, true);	
			}
			catch (Exception e)
			{
				System.err.println("Failed to render images!\n");
				System.err.println("Caught Exception: " + e.getMessage());
			}
		}
	}

	public static void main(String[] args)
	{
		JFrame frame = new JFrame("BLABLA");
		Number[][] list = {{0, 1, 3}, {1, 3, 1}, {2, 2, 3}, {3, 2, 0}};
		GraphPanel g = new GraphPanel(list);
		g.attach_to_frame(frame);
		frame.getContentPane().setPreferredSize(new Dimension(640, 480));
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
		frame.setVisible(true);
	}
}