[Share] Graph PP 10-25-2013, 02:44 PM
#1
Few days ago I thought of making a project related to graphs and came up with this so far.. It is still incomplete, so you might find few portions in the code that remain unused. I would like to share the source code here and would love to hear some feedback and suggestions for it too.
Node.java
Edge.java
Graph.java
Screenshots
![[Image: up1.png]](http://s16.postimg.org/tujknlh51/up1.png)
![[Image: up2.png]](http://s24.postimg.org/juzs9zob9/up2.png)
![[Image: up3.png]](http://s24.postimg.org/sq57y92hh/up3.png)
Node.java
Code:
package graphpp;
import java.util.ArrayList;
public class Node {
private String name;
private ArrayList<Edge> destList;
private ArrayList<Edge> srcList;
private ArrayList<Edge> edgeList;
private int dest,src;
private boolean emphasized;
private int x,y;
public Node() {
destList=new ArrayList<Edge>();
srcList=new ArrayList<Edge>();
edgeList=new ArrayList<Edge>();
dest=-1;
src=-1;
}
public void setName(String name) {
this.name=name;
}
public String getName() {
return name;
}
public void setEmphasize(boolean emphasize) {
emphasized=emphasize;
}
public boolean isEmphasized() {
return emphasized;
}
public void setXPos(int x) {
this.x=x;
}
public int getXPos() {
return x;
}
public void setYPos(int y) {
this.y=y;
}
public int getYPos() {
return y;
}
public void addDestEdge(Edge edge) {
destList.add(edge);
edgeList.add(edge);
}
public Edge getNextDestEdge() {
dest=(dest+1)%destList.size();
return destList.get(dest);
}
public int getDestSize() {
return destList.size();
}
public ArrayList<Edge> getDestList() {
return (new ArrayList<Edge>(destList));
}
public void addSrcEdge(Edge edge) {
srcList.add(edge);
edgeList.add(edge);
}
public Edge getNextSrcEdge() {
src=(src+1)%srcList.size();
return destList.get(src);
}
public int getSrcSize() {
return srcList.size();
}
public ArrayList<Edge> getSrcList() {
return (new ArrayList<Edge>(srcList));
}
public ArrayList<Edge> getAllEdgesList() {
return (new ArrayList<Edge>(edgeList));
}
public int getDegree() {
return edgeList.size();
}
}
Edge.java
Code:
package graphpp;
public class Edge {
private Node source,destination;
private int weight;
private boolean emphasize;
public void setSource(Node source) {
this.source=source;
}
public Node getSource() {
return source;
}
public void setDestination(Node destination) {
this.destination=destination;
}
public Node getDestination() {
return destination;
}
public void setWeight(int weight) {
this.weight=weight;
}
public int getWeight() {
return weight;
}
public void setEmphasize(boolean emphasize) {
this.emphasize=emphasize;
}
public boolean isEmphasized() {
return emphasize;
}
}
Graph.java
Code:
package graphpp;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.Timer;
@SuppressWarnings("serial")
public class Graph extends JPanel implements ActionListener{
private JFrame frame;
private JToolBar toolbar;
private JButton newButton;
private JToggleButton joinButton;
private JCheckBox directedCheckBox;
private Color backColor,foreColor,foreColor2,selectedColor,lineColor;
private int borderWidth=2,diameter=40;
private int width,height;
private ArrayList<Node> nodes;
private ArrayList<Edge> edges;
private Node pressedNode;
private boolean pressed,edgeMode,directedGraph;
private int xOffset,yOffset;
private Timer animeTimer;
private int fontSize=20;
private Node selectedNode;
public Graph() {
frame=new JFrame("Graph PP");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
width=Toolkit.getDefaultToolkit().getScreenSize().width;
height=Toolkit.getDefaultToolkit().getScreenSize().height;
frame.setSize(width, height);
backColor=new Color(0x0099cc);
foreColor2=new Color(0x00ee76);
foreColor=new Color(0x1464f4);
selectedColor=new Color(0xadadff);
lineColor=new Color(0xcd661d);
nodes=new ArrayList<Node>();
edges=new ArrayList<Edge>();
pressed=false;
directedGraph=true;
pressedNode=null;
xOffset=0;
yOffset=0;
animeTimer=new Timer(3,this);
selectedNode=null;
newButton=new JButton("New Node");
newButton.addActionListener(this);
joinButton=new JToggleButton("Join Nodes");
joinButton.addActionListener(this);
joinButton.setEnabled(false);
directedCheckBox=new JCheckBox("Directed Graph",true);
directedCheckBox.addActionListener(this);
toolbar=new JToolBar();
toolbar.setFloatable(false);
toolbar.add(newButton);
toolbar.add(joinButton);
toolbar.add(directedCheckBox);
frame.add(toolbar,BorderLayout.NORTH);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
int x=e.getX();
int y=e.getY();
for(int i=0;i<nodes.size();i++) {
Node temp=nodes.get(i);
//if the mouse was pressed on a node
if(x>=temp.getXPos() && x<=temp.getXPos()+diameter
&& y>=temp.getYPos() && y<=temp.getYPos()+diameter) {
//if user has enables join edge toggle button to draw new edges
if(edgeMode) {
if(selectedNode==null) {
selectedNode=temp;
repaint();
}
else {
makeNewEdge(selectedNode,temp);
repaint();
}
return;
}
updatePressedNode(temp,x,y);
return;
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
if(pressed) {
pressed=false;
pressedNode=null;
xOffset=0;
yOffset=0;
removeMouseMotionListener(this);
animeTimer.stop();
}
}
});
frame.add(this);
frame.setVisible(true);
}
private void updatePressedNode(Node a,int x,int y) {
pressedNode=a;
pressed=true;
xOffset=x-a.getXPos();
yOffset=y-a.getYPos();
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
if(pressed) {
pressedNode.setXPos(e.getX()-xOffset);
pressedNode.setYPos(e.getY()-yOffset);
}
}
});
animeTimer.start();
}
private void drawEdges(Graphics2D g2d) {
for(int i=0;i<nodes.size();i++) {
Node temp=nodes.get(i);
Node temp2=null;
g2d.setColor(lineColor);
for(int j=0;j<temp.getDestSize();j++) {
Edge ed=temp.getNextDestEdge();
temp2=ed.getDestination();
if(temp.getXPos()==temp2.getXPos() && temp.getYPos()==temp2.getYPos())
g2d.drawOval(temp.getXPos()+diameter/2, temp.getYPos()+diameter/2, diameter, diameter);
else
g2d.drawLine(temp.getXPos()+diameter/2, temp.getYPos()+diameter/2,
temp2.getXPos()+diameter/2, temp2.getYPos()+diameter/2);
int x=(temp.getXPos()+temp2.getXPos())/2+diameter/2;
int y=(temp.getYPos()+temp2.getYPos())/2+diameter/2;
g2d.drawString(String.valueOf(ed.getWeight()), x,y); //draw the weight of edge
//draw the arrows on edges if the graph is directed
if(directedGraph) {
drawArrow(g2d,x,y,temp,temp2);
}
}
}
}
private void drawArrow(Graphics2D g2d,int x,int y,Node a,Node b) {
double m=0;
if(a.getXPos()-b.getXPos()!=0) {
m=((double)(b.getYPos()-a.getYPos())/(b.getXPos()-a.getXPos()));
}
else {
m=(b.getYPos()-a.getYPos())/0.01;
}
if(b.getXPos()>a.getXPos()) {
g2d.drawLine(x,y,(int)(x-(diameter/3)*Math.cos(Math.atan(m)+Math.toRadians(30))),(int)(y-(diameter/3)*Math.sin(Math.atan(m)+Math.toRadians(30))));
g2d.drawLine(x,y,(int)(x-(diameter/3)*Math.cos(Math.atan(m)-Math.toRadians(30))),(int)(y-(diameter/3)*Math.sin(Math.atan(m)-Math.toRadians(30))));
}
else {
g2d.drawLine(x,y,(int)(x+(diameter/3)*Math.cos(Math.atan(m)-Math.toRadians(30))),(int)(y+(diameter/3)*Math.sin(Math.atan(m)-Math.toRadians(30))));
g2d.drawLine(x,y,(int)(x+(diameter/3)*Math.cos(Math.atan(m)+Math.toRadians(30))),(int)(y+(diameter/3)*Math.sin(Math.atan(m)+Math.toRadians(30))));
}
}
private void drawNodes(Graphics2D g2d) {
for(int i=0;i<nodes.size();i++) {
Node temp=nodes.get(i);
g2d.setColor(foreColor);
g2d.fillOval(temp.getXPos(), temp.getYPos(), diameter, diameter);
if(temp!=selectedNode) {
g2d.setColor(foreColor2);
}
else {
g2d.setColor(selectedColor);
}
g2d.fillOval(temp.getXPos()+borderWidth, temp.getYPos()+borderWidth, diameter-2*borderWidth, diameter-2*borderWidth);
g2d.setColor(foreColor);
g2d.drawString(temp.getName(), temp.getXPos()+(diameter/2)-(temp.getName().length()*fontSize/3), temp.getYPos()+(diameter/2)+(fontSize/3));
}
}
private void makeNewEdge(Node a,Node b) {
Edge ed=new Edge();
ed.setSource(a);
String s=JOptionPane.showInputDialog(this, "Weight","");
if(s!=null) {
int w=Integer.parseInt(s);
ed.setWeight(w);
ed.setDestination(b);
b.addSrcEdge(ed);
a.addDestEdge(ed);
selectedNode=null;
edges.add(ed);
}
}
@Override
public void paint(Graphics g) {
Graphics2D g2d=(Graphics2D)g;
g2d.setStroke(new BasicStroke(2));
g2d.setColor(backColor);
g2d.setFont(new Font(Font.MONOSPACED,Font.BOLD,fontSize));
g2d.fillRect(0, 0, getWidth(), getHeight());
drawEdges(g2d);
drawNodes(g2d);
}
@Override
public void actionPerformed(ActionEvent e) {
Object event=e.getSource();
if(event==newButton) {
String name=JOptionPane.showInputDialog(frame,"A Short Name for the Nodes separated by Single Space", "");
if(name!=null) {
String names[]=name.split(" ");
for(int q=0;q<names.length;q++) {
Node temp=new Node();
int xP=0,yP=0;
for(int i=0;i<nodes.size();i++) {
Node t=nodes.get(i);
if(t.getXPos()>=xP && t.getXPos()<=xP+diameter
&& t.getYPos()>=yP && t.getYPos()<=yP+diameter) {
xP+=diameter+1;
if(xP+diameter>width) {
xP=0;
yP=yP+diameter+1;
}
i=0;
}
}
temp.setXPos(xP);
temp.setYPos(yP);
temp.setName(names[q]);
nodes.add(temp);
joinButton.setEnabled(true);
}
repaint();
}
}
else if(event==joinButton) {
edgeMode=!edgeMode;
if(!edgeMode) {
selectedNode=null;
repaint();
}
}
else if(event==animeTimer) {
repaint();
}
else if(e.getSource()==directedCheckBox) {
directedGraph=directedCheckBox.isSelected();
repaint();
}
}
public int getDegree(Node n) {
return n.getDestSize()+n.getSrcSize();
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Graph();
}
});
}
}
Screenshots
![[Image: up1.png]](http://s16.postimg.org/tujknlh51/up1.png)
![[Image: up2.png]](http://s24.postimg.org/juzs9zob9/up2.png)
![[Image: up3.png]](http://s24.postimg.org/sq57y92hh/up3.png)
![[Image: up4.png]](http://s13.postimg.org/6ngrkdthj/up4.png)
Folow me on My YouTube Channel if you're into art.