0

我需要在我的 java 小程序的边缘添加权重。当他/她在 2 个顶点之间创建边时,我需要用户输入它。

因此,基本上,当我绘制两个顶点然后动态添加边时,那时我应该能够在其上输入权重(文本框或弹出窗口输入值)。我不知道我会怎么做。谁能帮帮我。

要运行以下代码,请将参数“pos”添加为“nodeid:xPos,yPos;nodeid:xPos,yPos”,例如对于 2 个节点,我可以添加:“1:0,1;2:1,0”

编辑:我知道有一个名为“drawString("text",pos1,pos2)"的方法,但我不知道当小程序已经运行时如何动态获取文本。

这是我到目前为止所做的:

import javax.swing.*;
import java.awt.event.*;

import java.awt.geom.AffineTransform;

import java.awt.*;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
Manual usage in Eclipse : 
 Add parameter "pos" as "nodeid:xPos,yPos;nodeid:xPos,yPos:

**/
public class MainGraph extends JApplet {

private static final long serialVersionUID = 1L; // default serial version

public void init() {
    setPreferredSize(new Dimension(1000, 1000));
}

public void start() {
    GraphPanel gp = new GraphPanel(getParameter("pos"));
    getContentPane().add(new JScrollPane(gp.listOfNodes), BorderLayout.EAST);
    getContentPane().add(new JScrollPane(gp), BorderLayout.CENTER);
}

public static void main(String[] args) {
    new MainGraph().init();
}

}


class GraphPanel extends JPanel implements ActionListener {

private static final long serialVersionUID = 1L;


NodeList listOfNodes; // panel on right
JTextArea status; // status box for feedback
JTextField name; // user supplies name to identify graph
JButton submitName; // and submits
JPopupMenu popDelete; // popup asking to confirm edge deletion (upon right-click)
ArrayList<Edge> edgesToDelete = new ArrayList<Edge>(); // list of edges for user to choose which to remove from popup
final Map<Integer, Node> nodes = new HashMap<Integer, Node>(); // maintains all the nodes in the graph
final ArrayList<Edge> edges = new ArrayList<Edge>(); // list of links for processing algorithm
int connectToNode = 0; // for drawing edges -- this specifies other node to which to draw the edge
Point pressed = new Point(0, 0); // for selecting nodes -- this is point at which mouse is pressed
Node lineNode; // for live line drawing -- actively follow cursor with line from this node until other node is selected
Point cursor = new Point(0, 0);     //  -- where cursor is at present time


public GraphPanel(String pos) {

    setBackground(Color.lightGray);
    setBorder(BorderFactory.createLineBorder(Color.black));
    listOfNodes = new NodeList(pos);
    status = new JTextArea();
    JTextArea infoName = new JTextArea("graph Name: ");
    name = new JTextField(11);
    submitName = new JButton("Submit Graph");
    submitName.addActionListener(this);

    popDelete = new JPopupMenu();

    add(infoName);
    add(this.name);
    add(this.submitName);
    add(this.status);

    status.setText("Select a node to add it. Click two nodes to draw an edge. Scroll down to click \"Submit Graph\" when done.");
    status.setDisabledTextColor(Color.black);
    status.setEnabled(false);
    infoName.setDisabledTextColor(Color.black);
    infoName.setEnabled(false);
    addMouseListener(new MouseHandler());
    addMouseMotionListener(new MouseMotionHandler());

}

public void addNode(String label, int selfNodeId, int connectedNodeId, Point location) {
    Node n = new Node(label, selfNodeId, connectedNodeId, location.x, location.y); // construct a new node object
    nodes.put(selfNodeId, n); // and add to map using ID as key
    status.setText("Added node " + selfNodeId + " at (" + location.x + ", " + location.y + ")");
    repaint();
}

public void removeNode(int nodeId) {
    for (Node n : nodes.values()) {
        n.connectedNodeIds.remove((Integer) nodeId); // remove connections to node
    }
    nodes.remove((Integer) nodeId); // remove node
    status.setText("Removed node " + nodeId);
    repaint();
}

@Override
public void paintComponent(Graphics g) {

    super.paintComponent(g);

    if (connectToNode > 0) g.drawLine(lineNode.xc, lineNode.yc, cursor.x, cursor.y);

    for (Node n : nodes.values()) {
        g.setColor(Color.darkGray);
        if (n == lineNode) g.setColor(Color.black);
        else if (n.connectedNodeIds.size() != 0) g.setColor(Color.blue);
        else {
            for (Node o : nodes.values()) {
                if (o.connectedNodeIds.contains((Integer) n.selfNodeId)) {
                    g.setColor(Color.blue);
                    break;
                }
            }
        }
        g.fillOval(n.circle.x, n.circle.y, n.circle.width, n.circle.height);
        g.drawString(n.label, n.circle.x, n.circle.y);
        for (int connectedNode : n.connectedNodeIds) {
            Node n2 = nodes.get(connectedNode);

            // drawing edge
            g.drawLine(n.xc, n.yc, n2.xc, n2.yc);



            // drawing direction
            AffineTransform tx = new AffineTransform();
            Polygon arrow = new Polygon();
            arrow.addPoint(0, 5); // first make arrow shape
            arrow.addPoint(-5, -5);
            arrow.addPoint(5, -5);
            tx.setToIdentity();
            tx.translate(n2.xc / 2, n2.yc / 2); // then translate arrow to midpoint
            tx.translate(n.xc / 2, n.yc / 2);
            double theta = Math.atan2(n2.yc-n.yc, n2.xc-n.xc);
            tx.rotate(theta-Math.PI/2);  
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setTransform(tx); // apply transform
            g2d.fill(arrow);
            g2d.dispose();
        }
    }
}

private class MouseHandler extends MouseAdapter {

    @Override
    public void mousePressed(MouseEvent e) {

        pressed = e.getPoint();
        status.setText("Clicked: " + pressed.x + ", " + pressed.y);

        if (e.getButton() == MouseEvent.BUTTON3) { // if right-click
            edgesToDelete.clear();
            popDelete.removeAll();
            int i = 0;
            for (Node n : nodes.values()) {
                for (int connectedNode : n.connectedNodeIds) {
                    Node n2 = nodes.get(connectedNode);
                    if (pressed.x <= Math.max(n2.xc, n.xc) + 5 && pressed.x > Math.min(n2.xc, n.xc) - 5 && pressed.y <= Math.max(n2.yc, n.yc) + 5 && pressed.y > Math.min(n2.yc, n.yc) - 5) {
                        // if the click is near an edge
                        JMenuItem deleteEdge = new JMenuItem();
                        deleteEdge.setText(i + ": Delete edge " + n.selfNodeId + " to " + connectedNode + "?");
                        i++;
                        deleteEdge.addActionListener(GraphPanel.this);
                        popDelete.add(deleteEdge);
                        edgesToDelete.add(new Edge(n, nodes.get(connectedNode), 1));
                    }
                }
            }
            popDelete.show(e.getComponent(), pressed.x, pressed.y);
            popDelete.validate();
        }

        boolean nodeSelected = false;
        for (Node n : nodes.values()) {
            if (n.contains(pressed)) {
                nodeSelected = true;
                status.setText("Node " + n.selfNodeId + " selected");
                if (connectToNode != 0 && connectToNode != n.selfNodeId) { // verify another node is being connected to this one
                    if (!lineNode.connectedNodeIds.contains(n.selfNodeId)) lineNode.connectedNodeIds.add(n.selfNodeId);
                    status.setText("Connecting node " + connectToNode + " to " + n.selfNodeId);
                    connectToNode = 0;
                    lineNode = null;
                } else if (connectToNode == 0) { // or start the connection with this node
                    status.setText("Now select node to connect.");
                    connectToNode = n.selfNodeId;
                    lineNode = nodes.get(connectToNode);
                } else {
                    connectToNode = 0; // user clicked self node, so cancel edge drawing
                    lineNode = null;
                }
                break;
            }
        }
        if (!nodeSelected) {
            connectToNode = 0; // user clicked away from nodes, so cancel edge drawing
            lineNode = null;
        }
        e.getComponent().repaint();
    }

}

private class MouseMotionHandler extends MouseMotionAdapter {

    @Override
    public void mouseMoved(MouseEvent e) {
        cursor = e.getPoint();
        e.getComponent().repaint();
    }

}

@Override
public void actionPerformed(ActionEvent e) {
    String action = e.getActionCommand();
    if (action.equals("Submit Graph")) {
        status.setText("Processing...");
        ArrayList<Node> nodesToProcess = new ArrayList<Node>();
        ArrayList<Edge> edgesToProcess = new ArrayList<Edge>();
        for (Node n : nodes.values()) {
            nodesToProcess.add(n);
            for (int n2 : n.connectedNodeIds) {
                edgesToProcess.add(new Edge(n, nodes.get(n2), 1));
            }
        }

    } else {
        int edgeIndex = Integer.parseInt(e.getActionCommand().split(":")[0]);
        Edge edgeToDelete = edgesToDelete.get(edgeIndex);
        nodes.get(edgeToDelete.node1).connectedNodeIds.remove(edgeToDelete.node2.selfNodeId); // delete connected node from node information (corresponding to edge)
        status.setText("Edge " + edgeToDelete.node1 + " to " + edgeToDelete.node2 + " deleted.");
    }
}

class NodeList extends JPanel implements ActionListener {

    private static final long serialVersionUID = 1L;

    String[] positions;

    //JButton btnSubmit = new JButton("Submit Graph");

    NodeList(String pos) {
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        setBackground(Color.darkGray);
        positions = pos.split(";");

        for (String idPosPair : positions) { // idPosPair has form id:x,y
            String id = idPosPair.split(":")[0];
            Point xy = whereIsNode(Integer.parseInt(id));
            JButton addNode = new JButton();
            addNode.setLayout(new BorderLayout());
            addNode.add(BorderLayout.NORTH, new JLabel("Node" + id));
            addNode.add(BorderLayout.SOUTH, new JLabel("(" + (xy.x-30)/50 + ", " + (xy.y-30)/50 + ")"));
            addNode.setActionCommand(id);
            addButton(addNode);

        }

        //addButton(btnSubmit);
    }

    public void addButton(JButton button) {
        button.setAlignmentX(CENTER_ALIGNMENT);
        button.addActionListener(this);
        add(button);
    }


    private Point whereIsNode(int nodeId) {

        for (String idPosPair : positions) {
            if (idPosPair.startsWith(nodeId + ":")) {
                String[] xy = idPosPair.split(":")[1].split(",");
                int x = 50*Integer.parseInt(xy[0])+30;
                int y = 50*Integer.parseInt(xy[1])+30;
                return new Point(x, y);
            }
        }

        return new Point(0, 0);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String action = e.getActionCommand();
        int nodeId = Integer.parseInt(action);
        if (nodes.containsKey(nodeId)) {
                removeNode(nodeId);
                status.setText("Removing node...");
            } else {
                addNode("Node" + action, nodeId, 0, whereIsNode(nodeId));
                status.setText("Adding node...");
            }
        }
    }

  }


 class Node {

public Rectangle circle; // nodes are drawn as filled circles on invisible rectangular areas
public String label; // string displayed on circle
public int selfNodeId; // keep track of self
public ArrayList<Integer> connectedNodeIds = new ArrayList<Integer>(); // transmitting to these nodes
public int r = 15; // radius
public int xc; // center
public int yc;



public Node(String label, int selfNodeId, int connectedNodeId, int x, int y) {
    circle = new Rectangle();
    this.label = label;
    this.selfNodeId = selfNodeId;
    if (connectedNodeId != 0) connectedNodeIds.add(connectedNodeId);
    circle.setLocation(x, y);
    circle.setBounds(x - r, y - r, 2*r, 2*r);
    xc = x + r/2;
    yc = y + r/2;
}

public boolean contains(Point xy) {
    return circle.contains(xy);
}

public void updateLocation(int dx, int dy) {
    circle.x += dx;
    circle.y += dy;
    xc = circle.x + r/2;
    yc = circle.y + r/2;
}


 }


class Edge { // keeps track of edges (nodes and link quality between them) for processing algorithm

public Node node1;
public Node node2;
public float link;

public Edge(Node node1, Node node2, float link) {
    this.node1 = node1;
    this.node2 = node2;
    this.link = link;
}

public String toString() {
    return "(" + node1.selfNodeId + ", " + node2.selfNodeId + ", " + link + ")";
}

}
4

0 回答 0