i am working on a java class representing the GRAPH data structure for my collage , and now i have a problem when i use a graphics2D
component to draw the graph .
Simply i am panting the nodes of my graph on a spacifiec range randomly , just when i press add vertex button , so i have to put my drawing code on the action of add vertex button , that makes me not using paintComponent()
or paint()
method , so when i minimize or just the Joptionepane popped up , the entire graphics that i had drawn disappears !!
and here is my code, Note : Graph and StackX and Queue classes implementations are made by me on the same package
package Graphs;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.border.TitledBorder;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JScrollPane;
import DataStrucutres.Trees.BTNode;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Random;
public class GraphGUI extends JPanel {
private JPanel panel;
private JTextField vetxTxt;
private JButton vertxBtn;
private JTextField ed1Txt;
private JTextField ed2Txt;
private JButton edBtn;
private JPanel panel_1;
private JButton creatBtn;
private JScrollPane scrollPane;
static int j = 1;
static Graph myGraph;
private JButton btnDfs;
private JButton btnBfs;
boolean check;
int[] X = new int[10];
int[] Y = new int[10];
int w, h;
Graphics2D g;
/**
* Create the panel.
*
*/
public GraphGUI() {
setBackground(Color.DARK_GRAY);
setLayout(null);
panel_1 = new JPanel();
panel_1.setBorder(new TitledBorder(null, "Controls",
TitledBorder.LEADING, TitledBorder.TOP, null, new Color(48, 48,
48)));
panel_1.setBounds(12, 117, 248, 188);
add(panel_1);
panel_1.setLayout(null);
vetxTxt = new JTextField();
vetxTxt.setEnabled(false);
vetxTxt.setBounds(7, 23, 124, 31);
panel_1.add(vetxTxt);
vetxTxt.setColumns(10);
vertxBtn = new JButton("Add Vertex");
vertxBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
check = true;
String string = vetxTxt.getText().toUpperCase();
char r = string.charAt(0);
myGraph.addVertex(r);
vetxTxt.setText(null);
int x = (int) ((Math.random() * (700)) % 349 )+300;
int y = (int) ((Math.random() * (780)) % 349);
int width = (int) (Math.random() * (700 / 4));
int height = (int) (Math.random() * (780 / 4));
if (x + width > getWidth()) {
x = getWidth() - width;
}
if (y + height > getHeight()) {
y = getHeight() - height;
}
Color color = new Color((int) (Math.random() * 255),
(int) (Math.random() * 255),
(int) (Math.random() * 255));
Graphics2D g = (Graphics2D) getGraphics();
g.setColor(color);
g.drawOval(x, y, 30, 30);
g.drawString(r + "", x + 10, y + 18);
X[h] = x;
Y[w] = y;
h++;
w++;
j++;
} catch (ArrayIndexOutOfBoundsException e) {
JOptionPane.showMessageDialog(null,
"Graph is full of vertexes", "ERORR",
JOptionPane.ERROR_MESSAGE);
vetxTxt.setText(null);
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Enter data pleas!",
"ERORR", JOptionPane.ERROR_MESSAGE);
vetxTxt.setText(null);
}
}
});
vertxBtn.setEnabled(false);
vertxBtn.setBounds(141, 24, 100, 29);
panel_1.add(vertxBtn);
ed1Txt = new JTextField();
ed1Txt.setEnabled(false);
ed1Txt.setBounds(7, 84, 50, 31);
panel_1.add(ed1Txt);
ed1Txt.setColumns(10);
ed2Txt = new JTextField();
ed2Txt.setEnabled(false);
ed2Txt.setBounds(81, 84, 50, 31);
panel_1.add(ed2Txt);
ed2Txt.setColumns(10);
edBtn = new JButton("Add Edge");
edBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
int m = Integer.parseInt(ed1Txt.getText());
int v = Integer.parseInt(ed2Txt.getText());
ed1Txt.setText(null);
ed2Txt.setText(null);
myGraph.addEdge(m, v);
g.drawLine(X[m] + 8, Y[m] + 8, X[v] + 8, Y[v] + 8);
} catch (Exception e) {
JOptionPane.showMessageDialog(null,
"Entered edges is out of graph !", "ERORR",
JOptionPane.ERROR_MESSAGE);
}
}
});
edBtn.setEnabled(false);
edBtn.setBounds(141, 85, 100, 29);
panel_1.add(edBtn);
btnBfs = new JButton("BFS");
btnBfs.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
myGraph.bfs();
JOptionPane.showMessageDialog(null,
"BFS is : " + myGraph.getS());
} catch (Exception e2) {
JOptionPane.showMessageDialog(null,
"Graph is empty of vertexes", "ERORR",
JOptionPane.ERROR_MESSAGE);
vetxTxt.setText(null);
}
}
});
btnBfs.setEnabled(false);
btnBfs.setBounds(27, 139, 93, 29);
panel_1.add(btnBfs);
btnDfs = new JButton("DFS");
btnDfs.setEnabled(false);
btnDfs.setBounds(129, 139, 93, 29);
panel_1.add(btnDfs);
btnDfs.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
myGraph.dfs();
Graphics2D g = (Graphics2D) getGraphics();
JOptionPane.showMessageDialog(null,
"DFS is : " + myGraph.getS());
} catch (Exception e2) {
JOptionPane.showMessageDialog(null,
"Graph is empty of vertexes", "ERORR",
JOptionPane.ERROR_MESSAGE);
vetxTxt.setText(null);
}
}
});
creatBtn = new JButton("Creat Graph");
creatBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
g = (Graphics2D) getGraphics();
myGraph = new Graph();
vertxBtn.setEnabled(true);
vetxTxt.setEnabled(true);
ed1Txt.setEnabled(true);
ed2Txt.setEnabled(true);
edBtn.setEnabled(true);
btnBfs.setEnabled(true);
btnDfs.setEnabled(true);
creatBtn.setVisible(false);
JOptionPane
.showMessageDialog(
null,
"A graph is a structure consisting of a set of arrays (also called dimensions) and a set of edges . An edge is a pair of vertices . The two vertices are called the edge endpoints.",
"Graph", JOptionPane.PLAIN_MESSAGE);
}
});
creatBtn.setBounds(6, 395, 125, 21);
add(creatBtn);
}
}
Don't use getGraphics() to do custom painting. This painting is temporary as you have noticed.
No, the action should invoke a method on your custom painting panel to add a vertex. So your class need to keep a List of vertex's to paint and then your custom code in the
paintComponent()
method will iterate through the List and paint all the vertex's.Or, the other option is to have the action paint on a BufferedImage. Then you can paint the BufferedImage in your paintComponent() method (or just add the BufferedImage to a JLabel using an ImageIcon).
See Custom Painting Approaches for working examples of doing custom painting with either a List or a BufferedImage.