Jung,用gui / jframe作为节点的图形

时间:2013-02-06 14:50:51

标签: java user-interface jung

我正在玩JUNG库,我想创建一个图表,其节点是一些gui(大概是jframe)项目。

我希望每个节点都有几个按钮,一个文本字段,菜单等。

我的问题是:这可能吗?

如果是,我还有两个问题: 1.我应该如何处理它(我是Java新手,我不熟悉最佳实践) 2.我应该使用什么界面(我正在查看.visualisation.decorators。* currenlty)。

提前谢谢。

2 个答案:

答案 0 :(得分:1)

好的,最终我成功创建了JPanels和JFrames的图表。我将继续使用JPanels。这是结果:

enter image description here

但现在我还面临一些其他问题:

  1. 可以移动帧,但只有在左上角拾取帧时才能移动。如何使整个JPanel区域可以选择?

  2. 我需要可以访问JPanel,例如我应该能够按下按钮,在文本框中写入一些文本(这尚未实现),并可能调整JPanel的大小。目前,JPanels"不活跃/没有焦点"由于某些原因。我尝试了启用方法,没有成功。试过一些"焦点"方法,再次失败。

  3. 对上述两个问题的任何建议?

    以下是我的代码的样子:

    import java.awt.Color;
    import java.awt.Container;
    import java.awt.Dimension;
    import java.awt.event.ItemEvent;
    import java.awt.event.ItemListener;
    import java.awt.geom.Point2D;
    
    import javax.swing.BorderFactory;
    import javax.swing.CellRendererPane;
    import javax.swing.JButton;
    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;
    
    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());
    
                // 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");
                            }
                        }
                    }
                });
    
                // 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());
            }
        }
    
        /*Attach the graph panel/container to a specified frame*/
        public void attach_to_frame(JFrame frame)
        {
            frame.setContentPane(vv);
        }
    
        /*This one should be reimplemented*/
        private void construct_graph(Number[][] nodes_list)
        {
            int i = 0;
            /*add the nodes*/
            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]);
            }
        }
    
        /*re-implement the render functionality to work with internal frames(JInternalFrame)*/
        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)
            {
                try
                {
                    GraphicsDecorator graphicsContext = rc.getGraphicsContext();
                    Point2D center = layout.transform(vertex);
                    Dimension size = new Dimension(100, 80);
    
                    System.out.printf("Vertex[%d] X = %d Y = %d: Running paintVertex()\n", vertex, (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);
                    sv.add(new JButton("Button1"));
                    //OK
                    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)
        {
            /*Create the window*/
            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);
        }
    }/*2*/
    

答案 1 :(得分:0)

是的,有可能(我认为)。我建议你将VertexLabeler改为你自己实现的。有些东西......

VisualizationImageServer<V, E> vv = new ...;
vv.getRenderContext().setVertexLabelRenderer(new MyVertexRenderer());

class MyVertexRenderer extends JFrame implements VertexLabelRenderer {}

但是我不确定它在以后的定位方面会起作用。您可能需要更改VertexShapeTransofrmer以及vv.getRenderContext().setVertexShapeTransformer()

我必须说,我花了很多时间试图让Jung像graphviz那样很好地渲染图形,但收效甚微。

相关问题