using repaint() method with actionPerformed - java

How to use the repaint() method when a button is pressed and Graphics p has to re-paint everything from scratch?
Thanks.
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class fares extends JPanel{
private static final long serialVersionUID = 1L;
public static int xaxis1,xaxis2,yaxis3,yaxis4;
public ControlsB(square) {
final JButton btn1 = new JButton("Resize");
final Box b = Box.createHorizontalBox();
b.add(new JLabel("Please enter range: "));
Box b0 = Box.createVerticalBox();//create a vertical box to stack the controls
Box b1 = Box.createHorizontalBox(); // create a horizontal box for the x-axis
//x-axis
b1.add(new JLabel("mark "));
b1.add(new JLabel("for"));
f1.setMaximumSize(new Dimension(100,30));
b1.add(f1);
b1.add(new JLabel("till"));
f2.setMaximumSize(new Dimension(100,30));
b1.add(f2);
//y-axis
//this code is not in use at the moment
f4.setMaximumSize(new Dimension(100,30));
b2.add(f4);
b0.add(b1);
add(b);
btn1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
f = Integer.parseInt(f1.getText());
invalidate();
validate();
paint(p);//this is not working...
}
});
b.add(btn1);
}
}
This is the code that has to be called and repainted:
import java.awt.*;
import javax.swing.*;
class Graph extends JPanel {
public static Graphics p;
private static final long serialVersionUID = 1L;
public static int f;
public static int g;
#Override
public Dimension getPreferredSize()
{
return (new Dimension(560,560));
}
public void paintComponent(Graphics p) {
super.paintComponent(p);
Graphics2D graph = (Graphics2D)p;
Dimension appletSize = this.getSize();
int appletHeight = (int)(appletSize.height);
int appletWidth = appletSize.width;
//change -ve num to +ve
int g3 = Math.abs(g);
int a1 = g3 + f;
int b1 = a1;
int d = (appletWidth / a1);
int e = (appletHeight / b1);
//draw y-axis numbers
//(+ve)
while(f != 0){
String s = String.valueOf(f);
m = m + b;
f = f - 1;
}
//(-ve)
m2 = y;
while(f2 != g-1)
m2 = m2 + b;
f2 = f2 - 1;
}
//draw x-axis numbers.
//(-ve)
while(g != 0){
String hy = String.valueOf(g);
n = n + a;
g = g + 1;
}
//(+ve)
n2 = x + a;
while(g2 != g3+1){
String w = String.valueOf(g2);
n2 = n2 + a;
g2 = g2 + 1;
}
BasicStroke aLine2 = new BasicStroke(1.0F,
BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
graph.setStroke(aLine2);
//notch on numbers and grid lines
//left to right, top to bottom notches
int v2 = -5;
int v5 = 0;
while(i <= a1-1){
p.setColor(Color.lightGray);//lightgray line
a = a + d;
b = b + e;
i = i + 1;
}
}
}
At the moment the resize button works, but I need to resize my window in order for the graph to respond to the inputs given. Basically when resizing the graph is being redrawn / repainted... now I need this to be done automatically.

It's hard to tell what's wrong based on snippets of code, but it appears that your graph is drawn on the Graph object, called graph (please correct me if I'm wrong), and you appear to be trying to repaint (or paint -- never call that directly!) your ControlsB panel. If so, then you may be calling methods on the wrong object. Perhaps you need to do something like:
// graph is final so it may be used in an inner class
public ControlsB(Box box2, final Graph graph) {
// .....
btn1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
f = Integer.parseInt(f1.getText());
g = Integer.parseInt(f2.getText());
System.out.println(f + " " + g);
// invalidate();
// validate();
// paint(p); ***** NEVER do this
graph.repaint();
}
});
}
Also:
Never call paint(...) directly on a component except in very special circumstances (this isn't it).
Never try to hold on to a components Graphics object and draw with it as this will often lead to a NullPointerException occurring, and it surely won't work.
Do read up on how to do drawing in Swing in the standard Swing tutorials. You would likely learn much from doing this.
Again, if you don't get a decent answer soon, consider creating and posting an sscce.

Changes made :
- Inside the GraphApplet class, these two lines have been changed
Box box2 = new Box(BoxLayout.Y_AXIS); // Changed
// Added one more argument, while making Object.
ControlsB b = new ControlsB(box2, graph);//horizontal
Inside Graph Class, setValues(...) method has been added.
-
public void setValues(int x, int y)
{
xstart = x;
ystart = y;
repaint();
}
Inside Graph class, scope of variables xstart and ystart has
been changed to Instance/Class
- Inside ControlB Class
refineButton = new JButton("Refine");
buttonBox.add(refineButton);
refineButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
int x = Integer.parseInt(f1.getText());
int y = Integer.parseInt(f3.getText());
/*
* Calling a method of Graph Class (setValues)
* and passing the values that we had got from
* the respective JTextFields.
*/
graph.setValues(x, y); }
});
}
Here watch this code example, modified your previous example a bit to give you one idea how to make this work. Have a look at the image attached, only use these three thingies, enter some integer values in the pointed JTextFields and then click on Refine JButton, you will see how to repaint. Since I really don't know how the logic works, hence won't be able to say how you can optimize your code, though to give you one idea, here it is :
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
public class GraphApplet extends JApplet
{
private static final long serialVersionUID = 1L;
public void init(){
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Container conn = getContentPane();
conn.setLayout(new BorderLayout());
Graph graph = new Graph();//graph
conn.add(graph,BorderLayout.CENTER);
Box box1 = new Box(BoxLayout.X_AXIS);
ControlsA a = new ControlsA(box1);//vertical
conn.add(a,BorderLayout.EAST);
Box box2 = new Box(BoxLayout.Y_AXIS); // Changed
// Added one more argument, while making Object.
ControlsB b = new ControlsB(box2, graph);//horizontal
conn.add(b,BorderLayout.SOUTH);
}
});
}
}
class Graph extends JPanel {
private static final long serialVersionUID = 1L;
private int xstart;
private int ystart;
public Graph(){
this.setBackground(Color.yellow);
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(460,560));
}
/*
* Added this method, which will call
* repaint(), everytime it is been
* called from anywhere. Moreover
* the variables used inside
* paintComponent(...) method xstart
* and ystart, have been changed to
* instance variables of the Graph Class.
*/
public void setValues(int x, int y)
{
xstart = x;
ystart = y;
repaint();
}
#Override
public void paintComponent(Graphics p)
{
super.paintComponent(p);
Graphics2D graph = (Graphics2D)p;
Dimension appletSize = this.getSize();
int appletHeight = (int)(appletSize.height);
int appletWidth = appletSize.width;
this.setBackground(Color.yellow);//set background color.
int x,y,y1,x1,a,b,p1x,p1y,p2x,p2y;
//line co-ordinates
//the numbers represent the number of boxes on the graph
// Made these two variables as Instance Variables
//int xstart = 10;
//int ystart = 5;
int xfinish = 2;
int yfinish = 8;
//other variables
int i = 0;
int i2 = 0;
int m = 0;
int n = 0;
int m2 = 0;
int n2 = 0;
int f2 = 0;
int g2 = 1;
//ranges
int f = 5;
int g = -5;
//change -ve num to +ve
int g3 = Math.abs(g);
int a1 = g3 + f;
int b1 = a1;
y1 = (appletHeight);
x1 = (appletWidth);
y = (appletHeight / 2);
x = (appletWidth / 2);
a = (appletWidth / a1);
b = (appletHeight / b1);
int d = (appletWidth / a1);
int e = (appletHeight / b1);
/**
to determine the
ammount of pixles there
is in each box of the
graph, both y-axis and
x-axis
*/
int xbox = x1 / 10;
int ybox = y1 / 10;
//line variables
//the xstart, ystart, etc represent the number of boxes
//top point of the line on the graph
p1x = xbox * xstart;//start x
p1y = ybox * ystart;//start y
//lowwer point of the line on the graph
p2x = xbox * xfinish;//finish x
p2y = ybox * yfinish;//finish y
//draw y-axis numbers
//(+ve)
while(f != 0){
String s = String.valueOf(f);
p.drawString(s,(x + 5),m + 13);
m = m + b;
f = f - 1;
}
//(-ve)
m2 = y;
while(f2 != g-1){
String u = String.valueOf(f2);
p.drawString(u,(x + 5),m2 - 3);
m2 = m2 + b;
f2 = f2 - 1;
}
//draw x-axis numbers.
//(-ve)
while(g != 0){
String t = String.valueOf(g);
p.drawString(t,n,y - 5);
n = n + a;
g = g + 1;
}
//(+ve)
n2 = x + a;
while(g2 != g3+1){
String vw = String.valueOf(g2);
p.drawString(vw,n2 -10,y - 5);
n2 = n2 + a;
g2 = g2 + 1;
}
BasicStroke aLine2 = new BasicStroke(1.0F,
BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
graph.setStroke(aLine2);
//notch on numbers and grid lines
//left to right, top to bottom notches
int v2 = -5;
int v5 = 0;
while(i <= a1-1){
p.setColor(Color.lightGray);//lightgray line
p.drawLine(a,0,a,y1);//vertical lightgray
p.drawLine(0,b,x1,b);//horizontal lightgray
a = a + d;
b = b + e;
i = i + 1;
}
//notches
while(i2 <= a1){
p.setColor(Color.blue);//notch color
p.drawString("x",v2+2,y+3);//xaxis
p.drawString("x",x-4,v5+4);//yaxis
v5 = v5 + e;
v2 = v2 + d;
i2 = i2 + 1;
}
//draws the border of the graph
p.setColor(Color.black);
Rectangle2D.Float rect = new Rectangle2D.Float(0,0,x1,y1);
BasicStroke aLine = new BasicStroke(2.5F,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
graph.setStroke(aLine);
graph.draw(rect);
//draw cross
BasicStroke aLine3 = new BasicStroke(2.5F,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
graph.setStroke(aLine3);
p.drawLine(x,0,x,y1); //vertical line
p.drawLine(0,y,x1,y); //horizontal line
//display the value of graph width and graph height
String aw = String.valueOf(x1);
p.drawString("Graph Width = ", 50,90);
p.drawString(aw,150,90);
p.drawString("Graph Height = ", 50,110);
String ah = String.valueOf(y1);
p.drawString(ah,156,110);
//draw line on graph
BasicStroke aLine4 = new BasicStroke(1.5F,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
graph.setStroke(aLine4);
p.setColor(Color.red);
if(p1x <= x1 && p2x <= x1 && p1y <= y1 && p2y <= y1){
p.drawLine(p1x,p1y,p2x,p2y);
Color c = new Color(0,0,0);
p.setColor(c);
p.drawString("X", p1x-4,p1y+4);
p.drawString("X", p2x-4,p2y+4);
}
else{
p.setColor(Color.black);
p.drawRect(48,34,223,35);
p.setColor(Color.white);
p.fillRect(49,35,222,34);
p.setColor(Color.red);
p.drawString("Wrong co-ordinates!!!", 50,50);
p.drawString("Values exceede applet dimensions.", 50,65);
}
}
}
class ControlsA extends JPanel
{
private static final long serialVersionUID = 1L;
public ControlsA (Box a)
{
a = Box.createVerticalBox();
a.add(new JLabel("Please enter the values below:"));
a.add(new JLabel("a"));
JTextField g1 = new JTextField("0.0");
g1.setMaximumSize(new Dimension(100,30));
a.add(g1);
a.add(new JLabel("b"));
JTextField g2 = new JTextField("0.0");
g2.setMaximumSize(new Dimension(100,30));
a.add(g2);
a.add(new JLabel("c"));
JTextField g3 = new JTextField("0.0");
g3.setMaximumSize(new Dimension(100,30));
a.add(g3);
a.add(new JLabel("d"));
JTextField g4 = new JTextField("0.0");
g4.setMaximumSize(new Dimension(100,30));
a.add(g4);
a.add(new JButton("Plot"));
a.add(new JButton("Refine"));
add(a);
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(200,100));
}
}
class ControlsB extends JPanel
{
private static final long serialVersionUID = 1L;
private Graph graph;
private JButton refineButton;
public ControlsB (Box b, Graph g) {
graph = g;
b = Box.createVerticalBox();
Box boxUpper = new Box(BoxLayout.X_AXIS);
boxUpper.add(new JLabel("Please enter range: "));
b.add(boxUpper);
Box boxX = new Box(BoxLayout.X_AXIS);
boxX.add(new JLabel(" x-axis "));
boxX.add(new JLabel("from"));
// Added final keyword.
final JTextField f1 = new JTextField("-5");
f1.setMaximumSize(new Dimension(100,30));
boxX.add(f1);
boxX.add(new JLabel(" to "));
JTextField f2 = new JTextField("5");
f2.setMaximumSize(new Dimension(100,30));
boxX.add(f2);
b.add(boxX);
//b.add(new JLabel(". "));
Box boxY = new Box(BoxLayout.X_AXIS);
boxY.add(new JLabel("y-axis "));
boxY.add(new JLabel("from"));
// Added final keyword.
final JTextField f3 = new JTextField("5");
f3.setMaximumSize(new Dimension(100,30));
boxY.add(f3);
boxY.add(new JLabel("to"));
JTextField f4 = new JTextField("-5");
f4.setMaximumSize(new Dimension(100,30));
boxY.add(f4);
b.add(boxY);
Box buttonBox = new Box(BoxLayout.X_AXIS);
buttonBox.add(new JButton("Plot"));
/*
* Made this an instance variable,
* and added ActionListener to it.
*/
refineButton = new JButton("Refine");
buttonBox.add(refineButton);
refineButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
int x = Integer.parseInt(f1.getText());
int y = Integer.parseInt(f3.getText());
/*
* Calling a method of Graph Class (setValues)
* and passing the values that we had got from
* the respective JTextFields.
*/
graph.setValues(x, y);
}
});
b.add(buttonBox);
add(b);
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(200,100));
}
}

Congrats, you just stumbled upon the subtleties of repaint :) There is a quite nice explanation at http://www.oracle.com/technetwork/java/painting-140037.html#paint_process . Here is the summary:
If you call repaint() on a heavyweight component like JFrame or JApplet, it will repaint immediately.
If you call repaint() on a JComponent, it will "schedule" the repainting to occur at some point in the future as decided by the Repaint Manager (which means, you have no control over it).
So, call the repaint() method in JApplet and you should see the changes as soon as you click the button.

Have you tried instead of paint(p) to use p.repaint() or p.update(p.getGraphics())?
I have not done Swing for ages and I can't remember exactly how it's behaving. One sure thing is that you have to be aware of when it is the good time to call paint, update or validate and how to use correctly the EventDispatcherThread (EDT). Otherwise your application will look like a lot of java swing applications : a crap filled of UI bugs...
I don't say Swing is crap, I say that if you don't know how it works, your UI will be a crap.

Related

Graphing one function at a time

I have 3 different functions superimposed on each other and I'm trying to add radio buttons so that when button1 is selected, the function associated with it will draw, and the others will be invisible.
If there is a better way to do this, I'll do that.
import java.awt.*;
import java.awt.geom.Path2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.*;
public class DrawingStuff extends JComponent {
DrawingStuff(){
JRadioButton line1 = new JRadioButton("F(x)");
JRadioButton line2 = new JRadioButton("G(x)");
JRadioButton line3 = new JRadioButton("Cos(2x)");
ButtonGroup bG = new ButtonGroup();
bG.add(line1);
bG.add(line2);
bG.add(line3);
this.setLayout( new FlowLayout());
this.add(line1);
this.add(line2);
this.add(line3);
line1.setSelected(true);
this.setVisible(true);
}
public void paintComponent(Graphics g)
{
//w is x, and h is y (as in x/y values in a graph)
int w = this.getWidth()/2;
int h = this.getHeight()/2;
Graphics2D g1 = (Graphics2D) g;
g1.setStroke(new BasicStroke(2));
g1.setColor(Color.black);
g1.drawLine(0,h,w*2,h);
g1.drawLine(w,0,w,h*2);
g1.drawString("0", w - 7, h + 13);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(2));
g2.setColor(Color.red);
int scale = 4;
//Path2D path1 = new Path2D.Double();
//path1.moveTo(w, h);
Polygon p = new Polygon();
for (int x = 0; x <= 4; x++) {
//path1.lineTo(w+scale*x, h - scale*((x*x*x) + x - 3));
p.addPoint(w+scale*x, h - scale*((x*x*x) + x - 3));
}
//g2.draw(path1);
g2.drawPolyline(p.xpoints, p.ypoints, p.npoints);
Polygon p1 = new Polygon();
//Path2D path2 = new Path2D.Double();
//path2.moveTo(w, h);
for (int x = -10; x <= 10; x++) {
//path2.lineTo(w+scale*x, h - scale * ((x*x*x)/100) - x + 10);
p1.addPoint(w + scale * x, h - scale * ((x*x*x)/100) - x + 10);
}
//g2.draw(path2);
g2.drawPolyline(p1.xpoints, p1.ypoints, p1.npoints);
Path2D path = new Path2D.Double();
for (int i = 0; i < 100; i++) {
double theta = i * 2 * Math.PI / 100;
double r = Math.cos(2 * theta);
double dX = w * r * Math.cos(theta) + w;
double dY = h * r * Math.sin(theta) + h;
if (i == 0) {
path.moveTo(dX, dY);
} else {
path.lineTo(dX, dY);
}
}
path.closePath();
g2.draw(path);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(800, 600);
frame.setTitle("Graphs");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
DrawingStuff draw = new DrawingStuff();
frame.add(draw);
frame.setVisible(true);
}
}
I'm not sure how to call the buttons from the constructor, and when I attempted to set a function aside for the buttons, they would replicate whenever I would maximize or restore down the window.
I also don't know how to erase a a line once plotted.
Thanks.
I also don't know how to erase a a line once plotted.
The secret is to draw only visible lines in your paintComponent() implementation. To do this, wrap your function in a class that maintains a notional visible field and give that class methods to get and set the attribute.
public void paintComponent(Graphics g) {
…
if (x. getFunctionVisible()) {
g2.drawPolyline(…);
}
}
In this example, VisibleAction uses getSeriesVisible() and setSeriesVisible() to effect a change; you implementation might declare getSeriesVisible() and setSeriesVisible() to effect a change; in contrast, your implementation might define getFunctionVisible() and set getFunctionVisible sVisible().
A relate example is seen here.

Number Line using Java Graphics API

I am trying to create a number line with labelled x-axis.Two problems:
Everything works fine for 0-9. But anything after that, the numbers get squashed together and not properly oriented on the scale.
My main axis line tends to disappear every time I try maximizing my window or at times it just wouldn't appear at all.Every time any of these happen, I have to re-compile my code and it works just fine.
Any help with the above problems will be greatly appreciated.
import java.awt.Graphics;
import javax.swing.JFrame;
/**
* #author Emil Shirima
*
*/
public class Drawing extends JFrame {
/**
* #param args
*/
int width = 300, height = 300, spacing = 10;
int x1 = 0, y1 = 150, x2 = 300, y2 = 150;
public Drawing() {
setTitle("Trial");
setSize(width, height);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
#Override
public void paint(Graphics brush) {
brush.drawLine(x1, y1, x2, y2);
x1 = 10;
y1 = 150;
x2 = 10;
y2 = 130;
// brush.drawLine(x1, y1, x2, y2);
for (int i = 0; i < 12; ++i) {
String ID = Integer.toString(i);
x1 = x2 += spacing;
brush.drawLine(x1, y1, x2, y2);
if (i < 10) {
brush.drawString(ID, x1 - 3, y2 + 40);
} else {
// With the below implementation, the numbers overlap each other
// and are not properly oriented on the axis
brush.drawString(ID, x1 - 3, y2 + 40);
// TODO: I need to resize the numbers after 10 so as they fit
// properly on the scale
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Drawing draw_object = new Drawing();
}
Current implementation:
Maximized GUI:
Your main problem:
You change x1, x2 within your paint method, and these changes will persist on the next painting. In other words, you're changing the state of the object within a rendering method, something that you must avoid doing.
You're using "magic" numbers making your program difficult to debug.
Other associated problems:
You're drawing directly in a JFrame, something that the Swing painting tutorials tell you exactly not to do since there are risks of significant side effects.
Instead draw in a JPanel's paintComponent method method.
You're not calling any super painting method, thus breaking the painting chain.
If you want the number line to extend through the component, get the component's size in the painting method (again, paintComponent) and use that to help determine the placement of the line.
Also consider sprinkling in a little FontMetrics to help place your numeric text. For example the following code creates a realizable number line:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import javax.swing.*;
#SuppressWarnings("serial")
public class SimpleNumberLinePanel extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = 300;
private static final int GAP = 10;
private static final int START = 0;
private static final int END = 12;
private static final int VERT_LINE_HEIGHT = 20;
private static final Font FONT = new Font(Font.MONOSPACED, Font.BOLD, 14);
private static final int TEXT_GAP = 2;
#Override
protected void paintComponent(Graphics g) {
// call super method
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
// initialize these guys each time paintComponent is called
int x1 = GAP;
int y1 = height / 2;
int x2 = width - 2 * GAP;
int y2 = y1;
g.drawLine(x1, y1, x2, y2);
for (int i = START; i <= END; i++) {
int x = (i * (x2 - x1)) / (END - START) + GAP;
drawNumberAndLine(g, i, x, y1, VERT_LINE_HEIGHT);
}
}
private void drawNumberAndLine(Graphics g, int number, int x, int y,
int vertLineHeight) {
int x1 = x;
int y1 = y;
int x2 = x;
int y2 = y - vertLineHeight;
g.drawLine(x1, y1, x2, y2);
String text = String.valueOf(number);
g.setFont(FONT);
FontMetrics fontMetrics = g.getFontMetrics();
int textX = x - fontMetrics.stringWidth(text) / 2;
int textY = y + fontMetrics.getHeight() + TEXT_GAP;
g.drawString(text, textX, textY);
}
#Override // make GUI bigger
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Number Line");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SimpleNumberLinePanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

How can i put delay in displaying the final result of my maze

i am creating a maze generation application. what i want to happen is that, when i run my program, it will show the animation on how the maze was created (it will show how it knocks the wall to create a path).
i tried to put delay on some of its parts but it won't run.thank you for the HUGE HELP!
here's the code:
public class Maze extends JPanel {
private Room[][] rooms;// m x n matrix of rooms
private ArrayList<Wall> walls; // List of walls
private Random rand;// for random wall
private int height;// height of matrix
private int width;// width of matrix
private int num;// incrementor
private JoinRoom ds;// union paths
// paint methods //
private int x_cord; // x-axis rep
private int y_cord;// y-axis rep
private int roomSize;
private int randomWall;
private int create;
int mazectr;
public static int m;// these are variables for the size of maze (m x n)
public static int n;
public Maze(int m, int n) {
JPanel j = new JPanel();
final JFrame f = new JFrame();
this.height = m;
this.width = n;
rooms = new Room[m][n];
walls = new ArrayList<Wall>((m - 1) * (n - 1));
long startTime = System.currentTimeMillis();
generateRandomMaze();
long endTime = System.currentTimeMillis();
final JLabel jl = new JLabel("Time Taken: " + (endTime-startTime) + "ms");
final JButton y = new JButton("OK");
j.add(jl);
j.add(y);
f.add(j);
y.addActionListener(new ActionListener(){
public void actionPerformed (ActionEvent e)
{
f.setVisible(false);
}
});
f.setVisible(true);
f.setSize(100, 100);
//jl.setLocation(1000, 1500);
//jl.setBounds(0, 0, 110, 130);
setPreferredSize(new Dimension(800, 700));
}
private void generateRandomMaze() {
generateInitialRooms();// see next method
ds = new JoinRoom(width * height);
rand = new Random(); // here is the random room generator
num = width * height;
while (num > 1) {
// when we pick a random wall we want to avoid the borders getting eliminated
randomWall = rand.nextInt(walls.size());
Wall temp = walls.get(randomWall);
// we will pick two rooms randomly
int roomA = temp.currentRoom.y + temp.currentRoom.x * width;
int roomB = temp.nextRoom.y + temp.nextRoom.x * width;
// check roomA and roomB to see if they are already members
if (ds.find(roomA) != ds.find(roomB)) {
walls.remove(randomWall);
ds.unionRooms(ds.find(roomA), ds.find(roomB));
temp.isGone = true;
temp.currentRoom.adj.add(temp.nextRoom);
temp.nextRoom.adj.add(temp.currentRoom);
num--;
}// end of if
}// end of while
}
// name the room to display
private int roomNumber = 0;
private static Label input;
private static Label input2;
/**
* Sets the grid of rooms to be initially boxes
* This is self explanitory, we are only creating an reverse L for all
* The rooms and there is an L for the border
*/
private void generateInitialRooms() {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
// create north walls
rooms[i][j] = new Room(i, j);
if (i == 0) {
rooms[i][j].north = new Wall(rooms[i][j]);
} else {
rooms[i][j].north = new Wall(rooms[i - 1][j], rooms[i][j]);
walls.add(rooms[i][j].north);
}
if (i == height - 1) {
rooms[i][j].south = new Wall(rooms[i][j]);
}
if (j == 0) {
rooms[i][j].west = new Wall(rooms[i][j]);
} else {
rooms[i][j].west = new Wall(rooms[i][j - 1], rooms[i][j]);
walls.add(rooms[i][j].west);
}
if (j == width - 1) {
rooms[i][j].east = new Wall(rooms[i][j]);
}
rooms[i][j].roomName = roomNumber++;// we will name the rooms
}
}
// initalize entrance and exit
rooms[0][0].west.isGone = true;// you can replace .west.isGone with .north.isGone
// this is just saying the roomName for top left is 0
rooms[0][0].roomName = 0;
// we will remove the south wall of the last room
rooms[height - 1][width - 1].south.isGone = true;
// this is just saying the roomName for bottom right is the last element in the mxn room matrix
rooms[height - 1][width - 1].roomName = (height * width);
}
public void paintComponent(Graphics g) {
x_cord = 40;
y_cord = 40;
Thread t = new Thread();
// could have taken height as well as width
// just need something to base the roomsize
roomSize = (width - x_cord) / width + 20;
// temp variables used for painting
int x = x_cord;
int y = y_cord;
for (int i = 0; i <= height - 1; i++) {
for (int j = 0; j <= width - 1; j++) {
if (!(rooms[i][j].north.isGone)) {
g.drawLine(x, y, x + roomSize, y);
}//end of north if
// west wall not there draw the line
if (rooms[i][j].west.isGone == false) {
g.drawLine(x, y, x, y + roomSize);
}// end of west if
if ((i == height - 1) && rooms[i][j].south.isGone == false) {
g.drawLine(x, y + roomSize, x + roomSize,
y + roomSize);
}// end of south if
if ((j == width - 1) && rooms[i][j].east.isGone == false) {
g.drawLine(x + roomSize, y, x + roomSize,
y + roomSize);
}// end of east if
x += roomSize;// change the horizontal
try
{
Thread.sleep(50);
} catch (Exception e) {};
t.start();
}// end of inner for loop
x = x_cord;
y += roomSize;
}// end of outer for loop
}
public static void main(String[] args) throws IOException {
// use JFrame to put the created panel on
String path = "E:\\Iskul\\trys\\tryy\\bin\\GUI.jpg";
File file = new File("E:\\Iskul\\trys\\tryy\\bin\\GUI.jpg");
BufferedImage image = ImageIO.read(file);
File fileRec = new File("E:\\Iskul\\trys\\tryy\\bin\\re.jpg");
BufferedImage imageRec = ImageIO.read(fileRec);
File fileHex = new File("E:\\Iskul\\trys\\tryy\\bin\\hexx.jpg");
BufferedImage imageHex = ImageIO.read(fileHex);
final JFrame frame = new JFrame("Prim's Algorithm");
final JPanel jp = new JPanel();
final JTextField input = new JTextField(10);
final JTextField input2 = new JTextField(10);
final JButton jb = new JButton(new ImageIcon(imageRec));
jb.setBorder(BorderFactory.createEmptyBorder());
final JButton jb1 = new JButton(new ImageIcon(imageHex));
jb1.setBorder(BorderFactory.createEmptyBorder());
final JLabel label = new JLabel(new ImageIcon(image));
jb.setLocation(100, 10);
frame.getContentPane().add(label);
frame.pack();
frame.setVisible(true);
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(795, 501));
jp.add(input);
jp.add(input2);
frame.add(jp);
jp.add(jb);
jp.add(jb1);
//jb.setImage(image);
jb.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
//int mazectr = 1;
int m = Integer.valueOf(input.getText());
int n = Integer.valueOf(input2.getText());
frame.remove(label);
frame.remove(jp);
//frame.add(new Maze(m,n));
frame.getContentPane().add(new Maze(m, n));
frame.pack();
}});
jb1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
//int m = Integer.valueOf(input.getText());
//int n = Integer.valueOf(input2.getText());
Hexa1 hexa = new Hexa1();
hexa.main();
//hexa.run();
}
});
}}// end of main
Your code wont work, you cant do an sleep in the Paint method, because if you do so, he wont draw, he just waits and at the end he'll draw your whole image.
If you want to do a nice effect, you should draw one step after the other but you should be aware that this is a lot of work to realize...

plotting a graph [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Hi there I am quite new to java, however I need to plot a graph in JApplet. I have managed to declare all variables and classes, the equation is working (when compiled on it's own). but all I get is a strait line! can anyone tell me what am I doing wrong please?!
in this applet the user will be asked to insert the values for abcd and the min and max values for the x axes
here is my code.......any help will be gratefully appreciated :)
package CubicEquationSolver;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.*;
public class graphApplet extends JApplet implements ActionListener {
private static class g {
public g() {
}
}
int a;
int b;
int c;
int d;
int minimumX;
int maximumX;
int minimumY;
int maximumY;
int xCoOrdinates[];
int yCoOrdinates[];
int y;
// Setting labels
JLabel labelA = new JLabel("Enter value of A");
JLabel labelB = new JLabel("Enter value of B");
JLabel labelC = new JLabel("Enter value of C");
JLabel labelD = new JLabel("Enter value of D");
JLabel labelMinX = new JLabel("Minimum X value");
JLabel labelMaxX = new JLabel("Maximum X value");
JLabel message = new JLabel("Please insert your values");
// Values will be entered here using JTextField
JTextField textA = new JTextField();
JTextField textB = new JTextField();
JTextField textC = new JTextField();
JTextField textD = new JTextField();
JTextField minX = new JTextField();
JTextField maxX = new JTextField();
JTextField ref = new JTextField("Enter value 0-1");
// declaring the layout for layout manager
JPanel north = new JPanel();
JPanel south = new JPanel();
JPanel west = new JPanel();
JPanel east = new JPanel();
JPanel center = new JPanel();
// declaring buttons using JButtons
JButton calculate = new JButton("Calculate");
JButton delete = new JButton("Delete");
JButton refine = new JButton("Refine");
// Calling from equation class
// equation eq = new equation();
private JPanel panel;
private int width = center.getWidth();
private int height = center.getHeight();
#Override
public void init() {
// setDefaultCloseOperation(EXIT_ON_CLOSE);
Container c = this.getContentPane();
this.setSize(900, 480);
this.setVisible(true);
// listener to buttons
calculate.addActionListener(this);
delete.addActionListener(this);
refine.addActionListener(this);
// listeer to user's input
textA.addActionListener(this);
textB.addActionListener(this);
textC.addActionListener(this);
textD.addActionListener(this);
minX.addActionListener(this);
maxX.addActionListener(this);
ref.addActionListener(this);
// assigning colours to panels to be distinguished
north.setBackground(Color.LIGHT_GRAY);
south.setBackground(Color.LIGHT_GRAY);
west.setBackground(Color.YELLOW);
east.setBackground(Color.GREEN);
center.setBackground(Color.GRAY);
// Declaring border
BorderLayout layoutBorder = new BorderLayout();
// setting up the grid (x rows, y clumns, space, space)
GridLayout layoutGrid = new GridLayout(2, 8, 4, 4);
// layout grid
north.setLayout(layoutGrid);
// set labels
north.add(labelA);
north.add(labelB);
north.add(labelC);
north.add(labelD);
north.add(labelMinX);
north.add(labelMaxX);
north.add(ref);
// calculate button
north.add(calculate);
// text boxes
north.add(textA);
north.add(textB);
north.add(textC);
north.add(textD);
north.add(minX);
north.add(maxX);
north.add(refine);
// delete button
north.add(delete);
south.add(message);
// border layout
c.add(north, BorderLayout.NORTH);
c.add(south, BorderLayout.SOUTH);
c.add(center, BorderLayout.CENTER);
// c .add(west, BorderLayout.WEST);
// c .add(east, BorderLayout.EAST);
// panel = new JPanel();
// panel.setPreferredSize(new Dimension(width, height));
// panel.setBackground(Color.GRAY);
// center.add(panel);
}
#Override
public void actionPerformed(ActionEvent e) // throws NumberFormatException
{
// dafault message will be <message> -- "Please insert values"
message.setText(e.getActionCommand());
// when button "Delete" is pressed all values in text firlds will turn
// null
if (e.getActionCommand().equals("Delete")) {
message.setForeground(Color.DARK_GRAY);
textA.setText(null);
textB.setText(null);
textC.setText(null);
textD.setText(null);
minX.setText(null);
maxX.setText(null);
repaint();
} else if (e.getActionCommand().equals("Calculate"))
// when "Calculate" button is pressed, values will be attached to
// equation
try {
message.setForeground(Color.DARK_GRAY);
// -------------------------------------------------
a = Integer.parseInt(textA.getText());
b = Integer.parseInt(textB.getText());
c = Integer.parseInt(textC.getText());
d = Integer.parseInt(textD.getText());
minimumX = Integer.parseInt(minX.getText());
maximumX = Integer.parseInt(maxX.getText());
System.out.println("center.getWidth() " + center.getWidth());
System.out.println("center.getHeight() " + center.getHeight());
System.out.println("minimum " + minX.getText());
System.out.println("maximum " + maxX.getText());
System.out.println("a " + textA.getText());
System.out.println("b " + textB.getText());
System.out.println("c " + textC.getText());
System.out.println("d " + textD.getText());
// ------------------------------------------------------
message.setText("This is the result for " + "A "
+ textA.getText() + ", B " + textB.getText() + ", C "
+ textC.getText() + ", D " + textD.getText());
draw();
}
catch (NumberFormatException ex)
// if user inputs other than numbers, a warning message in the south
// panel will show
{
message.setText("Please insert numerical value in "
+ ex.getMessage());
message.setForeground(Color.red);
message.setFont(new Font("Tahoma", Font.BOLD, 12));
}
else if (e.getActionCommand().equals("Refine")) {
// for refine
}
}
// ===================================================================================
private void calculation() {
xCoOrdinates = new int[(maximumX - minimumX) + 1];
yCoOrdinates = new int[(maximumX - minimumX) + 1];
for (int i = 0; i < xCoOrdinates.length; i++)
// for(int j = 0; j < yCoOrdinates.length; j++)
{
// generating the x co-ordinates and storing them in arrays
xCoOrdinates[i] = minimumX + i;
// generating the y co-ordinates using the formula given
y = ((a * (int) Math.pow(i, 3)) + (b * (int) Math.pow(i, 2))
+ (c * i) + (d));
// storing y co-ordinates
yCoOrdinates[i] = y;
// displaying results
// System.out.println("X = " + i + " Y = " + getY());
System.out.println("These are the values of X = " + i);
}
// printing the y axes values
for (int i = 0; i < yCoOrdinates.length; i++) {
System.out.println("this is the extracted Y " + yCoOrdinates[i]);
}
maximumX = xCoOrdinates[0];
maximumX = xCoOrdinates[0];
for (int i = 1; i < yCoOrdinates.length; i++) {
if (yCoOrdinates[i] > maximumX)
maximumX = xCoOrdinates[i];
else if (yCoOrdinates[i] < minimumX)
minimumX = xCoOrdinates[i];
}
System.out.println("MAXX is " + maximumX);
System.out.println("MINX is " + minimumX);
maximumY = yCoOrdinates[0];
minimumY = yCoOrdinates[0];
for (int i = 1; i < yCoOrdinates.length; i++) {
if (yCoOrdinates[i] > maximumY)
maximumY = yCoOrdinates[i];
else if (yCoOrdinates[i] < minimumY)
minimumY = yCoOrdinates[i];
}
System.out.println("MAXY is " + maximumY);
System.out.println("MINY is " + minimumY);
}
// =================================================================================================
public void draw() {
Graphics g = center.getGraphics();
g.setColor(Color.GRAY);
g.fillRect(0, 0, center.getWidth(), center.getHeight());
// g.fillRect(25,25, center.getWidth()-50, center.getHeight()-50);
double x, y, nextX, nextY;
int xPoint; // = 0;
int yPoint; // = 0;
int nextXpoint; // = 0;
int nextYpoint; // = 0;
g.setColor(Color.BLUE);
for (xPoint = 0; xPoint <= (double) center.getWidth(); xPoint++) {
x = scaleX(xPoint);
y = equation(x);
yPoint = scaleY(y);
nextXpoint = xPoint + 1;
nextX = scaleX(nextXpoint);
nextY = equation(nextX);
nextYpoint = scaleY(nextY);
g.drawLine(xPoint, yPoint, nextXpoint, nextYpoint);
// System.out.println("equation --->" + eq.getY());
}
}
private double equation(double x) {
return y;
// return a*x*x*x + b*x*x + c*x + d;
}
private double scaleX(int xPoint) {
int minXstart = minimumX;
int maxXend = maximumX;
double xScale = (double) center.getWidth() / (maxXend - minXstart);
return (xPoint - (center.getWidth() / 2)) / xScale;
}
private int scaleY(double y) {
int minYstart = minimumY;
int maxYend = maximumY;
int yCoord;
double yScale = (double) center.getHeight() / (maxYend - minYstart);
yCoord = (int) (-y * yScale) + (int) (center.getHeight() / 2);
return yCoord;
}
}
There are 3rd party libraries out there to do this type of work for you. Check out:
JFreeChart
Charts4J
Short term help: Check your output, do the values of x and y vary as expected? are they actually used during plotting? Use a debugger to step through your code. Then come back with a more focused questions.
Mid term (within the next two days): Please buy and read the following two books:
http://www.amazon.com/Pragmatic-Programmer-Andrew-Hunt/dp/020161622X
http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=sr_1_1?s=books&ie=UTF8&qid=1342369060&sr=1-1&keywords=clean+code
Classes as long as the one you posted are not acceptable, and make it next to impossible to understand the revlevant part. This is the reason why you received the down votes I'd guess.
I'm a JFreeChart fan, but you can also plot graphs using Cartesian coordinates in Java 2D, as suggested here.

Graph Plotting Issue

I am creating line graph using outputs from a thread, the threads are simulations of incoming and outgoing bill that run over a course of 52 seconds and this will be dipicted on a line graph as shown below to show the bank balance over the 52 seconds!
Currently the program runs fine, when I click start the point gets updated but every a new point is placed on the graph the previous one disappears. How i can i keep all the points on the graph.
I would assume i would have to create 2 new int variable... prevX & prevY.
import java.awt.*;
import javax.swing.*;
public class DrawPanel extends JPanel {
private static final int X_AXIS_LENGTH = 700;
private static final int Y_AXIS_LENGTH = 230; // could be changed
private static final int X_AXIS_OFFSET = 200;
private static final int Y_AXIS_OFFSET = 85;
private static final int PanelHeight = 365;
private static final int PanelWidth = 1000;
public DrawPanel() {
this.setBackground(Color.white);
this.setPreferredSize(new Dimension(PanelWidth, PanelHeight));
}
public void paintComponent(Graphics g) {
int y = ControlPanel.bk1.getBalance(); // balance
int x = ControlPanel.bk1.getWeek(); // weeks //
int prevX, prevY;
int maxX = ContentPanel.controlPanel.getDuration();
int maxY = 100000;
int Xleft = 200;
int Xright = 900;
int Ytop = 50;
int Ybottom = 330;// defining axis
while (ControlPanel.bk1.getBalance() > maxY) {
int i = maxY / 4;
maxY = maxY + i;
}
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g2);
g2.setColor(Color.BLUE);
BasicStroke pen = new BasicStroke(4F);
g2.setStroke(pen);
g2.drawLine(Xleft, Ytop, Xleft, Ybottom); // set axis
g2.drawLine(Xleft, 280, Xright, 280);
int i = X_AXIS_OFFSET + (X_AXIS_LENGTH / 2);
int ii = X_AXIS_OFFSET + (X_AXIS_LENGTH / 4);
int iii = ((X_AXIS_LENGTH / 4)) * 3 + X_AXIS_OFFSET;
BasicStroke spaces = new BasicStroke(1F);
g2.setStroke(spaces);
g2.drawLine(i, 280, i, 300);
g2.drawLine(ii, 280, ii, 300);
g2.drawLine(iii, 280, iii, 300);
g2.setStroke(pen);
Font f = new Font("Serif", Font.BOLD, 14);
g2.setFont(f);
g2.drawString("Account Balance (£)", 35, 200);
g2.drawString("Elapsed Time (Weeks)", 475, 340);
g2.setColor(Color.BLACK);
String maxXDisplay = Integer.toString(maxX);
String maxYDisplay = Integer.toString(maxY);
g2.drawString(maxYDisplay, 160, 45);
g2.drawString(maxXDisplay, 900, 300);
// retrieve values from your model for the declared variables
// calculate the coords line on the canvas
double balance = PanelHeight
- ((((double) y / maxY) * Y_AXIS_LENGTH) + Y_AXIS_OFFSET);
double weeks = (((double) x / maxX) * X_AXIS_LENGTH) + X_AXIS_OFFSET;
int xPos = (int) Math.round(weeks);
int yPos = (int) Math.round(balance); // changing back to int to be used
// in drawing oval
g2.setColor(Color.RED);
g.drawOval(xPos, yPos, 2, 2);
}
public void reDraw() {
repaint();
}
}
You appear to be only trying to plot one point in your paintComponent method:
g.drawOval(xPos, yPos, 2, 2);
Usually you'll loop through a for loop drawing all the points in this method. For example something like:
for (int j = 0; j < maxPointCount; j++) {
x = someMethodToGetX(j);
y = someMethodToGetY(j);
double balance = PanelHeight - ((((double) y / maxY) *
Y_AXIS_LENGTH) + Y_AXIS_OFFSET);
double weeks = (((double) x / maxX) * X_AXIS_LENGTH) +
X_AXIS_OFFSET;
int xPos = (int) Math.round(weeks);
int yPos = (int) Math.round(balance);
g2.setColor(Color.RED);
g.drawOval(xPos, yPos, 2, 2);
}
Edit 1
Regarding your recent comment:
Tryed that for loop and it makes no difference to the program
My code above is certainly not code that can be cut and pasted into your program and be expected to work, but rather is only to be seen as an example of a concept. A for loop will work if implemented correctly as it's worked for me many times, but yours is not working, so we have to fix your implementation, and in order to do that, we need more information:
How are you generating your data points?
Are you using a Swing Timer to imitate real-time collection of data?
You will need to store your data points as you collect them so your paintComponent can iterate over them. How are you storing your data points? Is it in an ArrayList? Can we see that code?
Once we see all this, can we see the code where you try to implement a for loop to draw all the data points?
You will need to make an edit to your question to show this new information. If you do this, please notify me by commenting in this answer.
Edit 2
This is a more complete example of what I'm describing, one with a functioning for loop that draws all scaled data points. Of course none of this code can be copied and pasted into your app, but hopefully the concepts contained can be transferred. Please ask if anything looks confusing:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.*;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class TestShowGraph {
private static final int MAX_POINTS = 30;
private static final int TIMER_DELAY = 800;
private static void createAndShowGui() {
ShowGraph showGraphPanel = new ShowGraph(MAX_POINTS);
TimerListener timerListener = new TimerListener(MAX_POINTS, showGraphPanel);
JFrame frame = new JFrame("TestShowGraph");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(showGraphPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
new Timer(TIMER_DELAY, timerListener).start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class TimerListener implements ActionListener {
private static final double EXP_MULTIPLIER = 0.2;
// array of points created in constructor to hold data that
// will eventually be displayed in real time.
// A Swing Timer will copy a point into the pointsList above.
private Point2D[] initPoints;
private int maxPoints;
private int count = 0;
private ShowGraph showGraph;
public TimerListener(int maxPoints, ShowGraph showGraph) {
initPoints = new Point2D[maxPoints];
this.maxPoints = maxPoints;
this.showGraph = showGraph;
// create all data points that will eventually be
// graphed. This is to simulate real-time data collection
for (int i = 0; i < initPoints.length; i++) {
double x = (double) i / initPoints.length;
double y = 1.0 - Math.exp(-1.0 * i * EXP_MULTIPLIER);
initPoints[i] = new Point2D.Double(x, y);
}
}
public void actionPerformed(ActionEvent e) {
if (count < maxPoints) {
// simply push data from initPoints into the list that will
// be used to draw the graph
showGraph.addPoint(initPoints[count]);
count++;
} else {
// unless we've run out of points. Then simply start over
count = 0;
showGraph.clearPointsList();
}
// repaint so that the GUI will show the points
showGraph.repaint();
}
}
#SuppressWarnings("serial")
class ShowGraph extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = 600;
private static final int BORDER_GAP = 50;
private static final Color AXIS_COLOR = Color.blue;
private static final Color POINTS_COLOR = Color.red;
private static final Color BACKGRND_COLOR = Color.white;
private static final Stroke AXIS_STROKE = new BasicStroke(3f);
private static final Stroke POINTS_STROKE = new BasicStroke(2f);
private static final double X_SCALE = PREF_W - 2 * BORDER_GAP;
private static final double Y_SCALE = PREF_H - 2 * BORDER_GAP;
private static final int POINT_RADIUS = 3;
// list that the paintComponent method loops through to
// draw points
private List<Point2D> pointsList = new ArrayList<Point2D>();
public ShowGraph(int maxPoints) {
setBackground(BACKGRND_COLOR);
}
public void addPoint(Point2D point2d) {
pointsList.add(point2d);
}
public void clearPointsList() {
pointsList.clear();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
drawAxises(g2);
drawPoints(g2);
}
private void drawAxises(Graphics g2) {
// derive a Graphics2D object from the one provided by the
// JVM so we can change settings on it without effecting
// the Graphics object provided by the JVM
Graphics2D g2Axises = (Graphics2D) g2.create();
g2Axises.setStroke(AXIS_STROKE);
g2Axises.setColor(AXIS_COLOR);
int x1XAxis = BORDER_GAP;
int y1XAxis = PREF_H - BORDER_GAP;
int x2XAxis = PREF_W - BORDER_GAP;
int y2XAxis = PREF_H - BORDER_GAP;
g2Axises.drawLine(x1XAxis, y1XAxis, x2XAxis, y2XAxis);
int x1YAxis = BORDER_GAP;
int y1YAxis = BORDER_GAP;
int x2YAxis = BORDER_GAP;
int y2YAxis = PREF_H - BORDER_GAP;
g2Axises.drawLine(x1YAxis, y1YAxis, x2YAxis, y2YAxis);
g2Axises.dispose(); // because we derived this we must dispose it
}
private void drawPoints(Graphics2D g2) {
Graphics2D g2Points = (Graphics2D) g2.create();
g2Points.setStroke(POINTS_STROKE);
g2Points.setColor(POINTS_COLOR);
for (Point2D p : pointsList) {
// p points hold data between 0 and 1
// we must scale our points to fit the display
// before displaying them
int pX = (int)(X_SCALE * p.getX()) + BORDER_GAP;
int pY = PREF_H - (int)(Y_SCALE * p.getY()) - BORDER_GAP;
// displayed the scaled points
int radius = POINT_RADIUS;
g2Points.drawOval(pX - radius, pY - radius, 2 * radius, 2 * radius);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
}
Luck.

Categories