I am trying to implement a menu based graph – wherein i will represent a vertex by a circle and each circle will have an index provided by the user.The user has to go to File menu and click on Addvertex to create a new node with an index.The Problem though is – The circle is drawn only once – any subsequent clicks to addVertex does not result in drawing of a circle -Can’t understand Why…
Here is my code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.*;
import java.util.*;
public class FileChoose extends JFrame {
public FileChoose() {
JMenuBar l=new JMenuBar();
JMenu file=new JMenu("File");
JMenuItem open=new JMenuItem("Addvertex");
open.addActionListener(new Drawer());
JMenuItem close=new JMenuItem("Exit");
close.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
JMenu tools=new JMenu("Tools");
file.add(open);
file.add(close);
this.setJMenuBar(l);
l.add(tools);
l.add(file);
this.setSize(new Dimension(200, 200));
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
}
void HelloHere(String p) {
Draw d = new Draw(p);
this.add(d);
setExtendedState(MAXIMIZED_BOTH);
}
class Drawer extends JFrame implements ActionListener {
Integer index;
public void actionPerformed(ActionEvent e) {
JPanel pn = new JPanel();
JTextField jt = new JTextField(5);
JTextField jt1 = new JTextField(5);
pn.add(jt);
pn.add(jt1);
int result=JOptionPane.showConfirmDialog(null, pn, "Enter the values", JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
index = Integer.parseInt(jt.getText());
System.out.println(jt1.getText());
}
this.setVisible(true);
this.setSize(500, 500);
this.setLocationRelativeTo(null);
HelloHere(index.toString());
}
}
public static void main(String [] args) {
FileChoose f = new FileChoose();
f.setVisible(true);
}
}
class Draw extends JPanel {
String inp;
public Draw(String gn) {
inp = gn;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Random r = new Random();
int x = r.nextInt(100);
g2.drawOval(x, x * 2, 100, 100);
g2.drawString(inp, x + (x / 2), x + (x / 2));
}
}
Some pointers:
Use EDT for creation and manipulation of Swing Components.
Dont extend
JFrameclass unnecessarily.Use anonymous
Listeners where possible/allowedMake sure
JFrame#setVisible(..)is the last call onJFrameinstance specifically pointing here:Call
pack()onJFrameinstance rather thansetSize(..)Do not use multiple
JFrames see: The Use of Multiple JFrames: Good or Bad Practice?The problem you are having is here:
You are creating a new instance of
DrawJPaneleach time and then overwriting the lastJPaneladded with the new one (this is default the behavior ofBorderLayout). To solve this read below 2 points:Call
revalidate()andrepaint()on instance after adding components to show newly added components.Use an appropriate
LayoutManagerAs I am not sure of you expected results I have done as much fixing of the code as I could hope it helps:
UPDATE:
Declare this globally in your Draw class:
Random r=new Random();as if you iniate a new Random instance each time you callpaintComponent()the distributions will not be significant/random enough