Graphics paint component and loop trouble - java

I can not seem to figure out why my concentric circles are not lining up. My loops seem correct to me and the measurements are correct but for some reason the last few circles are off-centered. That's the first issue I'm having. The second issue is, i can't seem to get the concentric circles to print in each square. Once again, i can't seem to find any issue in my logic, but obviously there is an issue. Any help on this at all would be great.
This should be the end product
*Now this is my source code- ExampleGUI.java *
import javax.swing.*;
public class ExampleGUI {
public static void main(String args []) {
JFrame frame = new JFrame("Example Graphics");
ExamplePanel panel = new ExamplePanel();
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(3);
frame.pack();
frame.setVisible(true);
}
}
* ExamplePanel.java *
import java.awt.*;
import javax.swing.*;
public class ExamplePanel extends JPanel{
public ExamplePanel() {
setPreferredSize(new Dimension (600, 600));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
int x = 0;
int x2 = 5;
int y = 500;
int y2 = 505;
int w = 100;
int w2 = 90;
int h = 100;
int h2 = 90;
int i, j, k;
for(j = 1; j < 7; j++) {
x = 0;
x2 = x + 5;
for(i = 1; i < 7; i++) {
if ((i + j) % 2 == 0) {
g.setColor(Color.white);
} else {
g.setColor(Color.yellow);
}
g.fillRect(x, y, w, h);
g.setColor(Color.black);
g.drawRect(x, y, w, h);
g.setColor(Color.green);
g.fillOval(x2, y2, w2, h2);
for(k = 1; k < 7; k++) {
g.setColor(Color.black);
g.drawOval(x2, y2, w2, h2);
x2 = x2 + 5;
y2 = y2 + 5;
w2 = w2 - 10;
h2 = h2 - 10;
}
x = x + w;
x2 = x2 + w2 + 10;
}
x = x + w;
y = y - h;
y2 = (y2 - h2) - 10;
}
}
}
* This is what my program looks like when i run it. It doesn't look like the other picture for some reason *

Basically, you "spiral" loop is modifying the state of variables that are required elsewhere
What I would do, is create a new series of variables, initialized to the current state and modify those instead...
int ix = x2;
int iy = y2;
int ih = h2;
int iw = w2;
for (k = 1; k < 7; k++) {
g.setColor(Color.black);
g.drawOval(ix, iy, iw, ih);
ix = ix + 5;
iy = iy + 5;
iw = iw - 10;
ih = ih - 10;
}

Related

Java Graphic problem with getting correct generation on my graphic lines

I am trying to finish a project that I have been working on for fun on Java, and I'm genuinely trying to figure this out. Here is the code. I put a comment where the problem starts.
// Lab04vst.java
//
import java.awt.*;
import java.applet.*;
public class Lab04vsthome extends Applet
{
public void paint(Graphics g)
{
int width = 980;
int height = 630;
int x1 = 10;
int y1 = 640;
int x2 = 990;
int y2 = 640;
g.drawRect(10,10,width,height);
int hdiv = height/50;
int wdiv = width/50;
//bottom right
for(int k = 0; k <= 50; k++)
{
g.drawLine(x1,y1,x2,y2);
y2 -= hdiv;
x1 += wdiv;
}
x1 = 10;
y1 = 640;
x2 = 990;
y2 = 640;
//bottom left
for(int k = 0; k <= 50; k++)
{
g.drawLine(x1,y1,x2,y2);
y1 -= hdiv;
x2 -= wdiv;
}
x1 = 10;
y1 = 10;
x2 = 990;
y2 = 10;
//top right
for(int k = 0; k <= 50; k++)
{
g.drawLine(x1,y1,x2,y2);
y2 += hdiv;
x1 += wdiv;
}
x1 = 10;
y1 = 10;
x2 = 990;
y2 = 10;
//top left
for(int k = 0; k <= 50; k++)
{
g.drawLine(x1,y1,x2,y2);
y1 += hdiv;
x2 -= wdiv;
}
x1 = 10;
y1 = 640;
x2 = 990;
y2 = 640;
//problem starts here
int width2 = 500;
int height2 = 312;
g.drawRect(250, 170, width2, height2);
int x3 = 250;
int y3 = 322;
int x4 = 510;
int y4 = 322;
int w2div = width2 / 50;
int h2div = height2 / 50;
for (int k = 0; k <= 50; k++)
{
g.drawLine(x3,y3,x4,y4);
y4 -= w2div;
x3 += h2div;
}
}
}
It is supposed to generate the shapes on the outside of the box in the center, in the inside box. When I tried to make this happen with one of them, I can't figure out a way to move it and to stop it from going out, and I'm genuinely stumped at this point. The solution is probably obvious, but I'm newer to doing graphs and loops in Java so I'm stumped at this point. If it matters at all, I'm using BlueJ. Can anyone help?

How to display coordinates as Strings with Graphics2D in Java?

I have a Voronoi diagram being displayed thanks to the Graphics2D class. I would like to know how to display a String in one of black dots located within the patterns. I've tried things such as labels, etc., and can't manage to output a String anywhere in the diagram.
Here's how the code looks:
public Voronoi() {
super("Voronoi Diagram");
setBounds(0, 0, size, size);
setDefaultCloseOperation(EXIT_ON_CLOSE);
int n = 0;
Random rand = new Random();
I = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
px = new int[cells];
py = new int[cells];
color = new int[cells];
for (int i = 0; i < cells; i++) {
px[i] = rand.nextInt(size);
py[i] = rand.nextInt(size);
color[i] = rand.nextInt(16777215);
}
for (int x = 0; x < size; x++) {
for (int y = 0; y < size; y++) {
n = 0;
for (byte i = 0; i < cells; i++) {
if (distance(px[i], x, py[i], y) < distance(px[n], x, py[n], y)) {
n = i;
}
}
I.setRGB(x, y, color[n]);
}
}
Graphics2D g = I.createGraphics();
g.setColor(Color.BLACK);
for (int i = 0; i < cells; i++) {
g.fill(new Ellipse2D .Double(px[i] - 2.5, py[i] - 2.5, 5, 5));
}
try {
ImageIO.write(I, "png", new File("voronoi.png"));
} catch (IOException e) {
}
}
public void paint(Graphics g) {
g.drawImage(I, 0, 0, this);
}
static double distance(int x1, int x2, int y1, int y2) {
double d;
// d = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); // Euclidian
d = Math.abs(x1 - x2) + Math.abs(y1 - y2); // Manhattan
// d = Math.pow(Math.pow(Math.abs(x1 - x2), p) + Math.pow(Math.abs(y1 - y2), p), (1 / p)); // Minkovski
return d;
}
public static void main(String[] args) {
new Voronoi().setVisible(true);
}
}

Draw Line Graph2D with data [duplicate]

In my program I want to draw a simple score line graph. I have a text file and on each line is an integer score, which I read in and want to pass as argument to my graph class. I'm having some trouble implementing the graph class and all the examples I've seen have their methods in the same class as their main, which I won't have.
I want to be able to pass my array to the object and generate a graph, but when calling my paint method it is asking me for a Graphics g... This is what I have so far:
public class Graph extends JPanel {
public void paintGraph (Graphics g){
ArrayList<Integer> scores = new ArrayList<Integer>(10);
Random r = new Random();
for (int i : scores){
i = r.nextInt(20);
System.out.println(r);
}
int y1;
int y2;
for (int i = 0; i < scores.size(); i++){
y1 = scores.get(i);
y2 = scores.get(i+1);
g.drawLine(i, y1, i+1, y2);
}
}
}
For now I have inserted a simple random number generator to fill up my array.
I have an existing frame and basically want to instantiate the Graph class and mount the panel onto my frame. I'm really sorry that this question seems so jumbled by the way, but I've had little sleep...
The code in my main statement is:
testFrame = new JFrame();
testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Graph graph = new Graph();
testFrame.add(graph);
I'm not sure exactly what an SSCE is but this is my attempt at one:
public class Test {
JFrame testFrame;
public Test() {
testFrame = new JFrame();
testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Graph graph = new Graph();
testFrame.add(graph);
testFrame.setBounds(100, 100, 764, 470);
testFrame.setVisible(true);
}
Graph.java
public class Graph extends JPanel {
public Graph() {
setSize(500, 500);
}
#Override
public void paintComponent(Graphics g) {
Graphics2D gr = (Graphics2D) g; // This is if you want to use Graphics2D
// Now do the drawing here
ArrayList<Integer> scores = new ArrayList<Integer>(10);
Random r = new Random();
for (int i : scores) {
i = r.nextInt(20);
System.out.println(r);
}
int y1;
int y2;
for (int i = 0; i < scores.size() - 1; i++) {
y1 = (scores.get(i)) * 10;
y2 = (scores.get(i + 1)) * 10;
gr.drawLine(i * 10, y1, (i + 1) * 10, y2);
}
}
}
Problems with your code and suggestions:
Again you need to change the preferredSize of the component (here the Graph JPanel), not the size
Don't set the JFrame's bounds.
Call pack() on your JFrame after adding components to it and before calling setVisible(true)
Your foreach loop won't work since the size of your ArrayList is 0 (test it to see that this is correct). Instead use a for loop going from 0 to 10.
You should not have program logic inside of your paintComponent(...) method but only painting code. So I would make the ArrayList a class variable and fill it inside of the class's constructor.
For example:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
#SuppressWarnings("serial")
public class DrawGraph extends JPanel {
private static final int MAX_SCORE = 20;
private static final int PREF_W = 800;
private static final int PREF_H = 650;
private static final int BORDER_GAP = 30;
private static final Color GRAPH_COLOR = Color.green;
private static final Color GRAPH_POINT_COLOR = new Color(150, 50, 50, 180);
private static final Stroke GRAPH_STROKE = new BasicStroke(3f);
private static final int GRAPH_POINT_WIDTH = 12;
private static final int Y_HATCH_CNT = 10;
private List<Integer> scores;
public DrawGraph(List<Integer> scores) {
this.scores = scores;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
double xScale = ((double) getWidth() - 2 * BORDER_GAP) / (scores.size() - 1);
double yScale = ((double) getHeight() - 2 * BORDER_GAP) / (MAX_SCORE - 1);
List<Point> graphPoints = new ArrayList<Point>();
for (int i = 0; i < scores.size(); i++) {
int x1 = (int) (i * xScale + BORDER_GAP);
int y1 = (int) ((MAX_SCORE - scores.get(i)) * yScale + BORDER_GAP);
graphPoints.add(new Point(x1, y1));
}
// create x and y axes
g2.drawLine(BORDER_GAP, getHeight() - BORDER_GAP, BORDER_GAP, BORDER_GAP);
g2.drawLine(BORDER_GAP, getHeight() - BORDER_GAP, getWidth() - BORDER_GAP, getHeight() - BORDER_GAP);
// create hatch marks for y axis.
for (int i = 0; i < Y_HATCH_CNT; i++) {
int x0 = BORDER_GAP;
int x1 = GRAPH_POINT_WIDTH + BORDER_GAP;
int y0 = getHeight() - (((i + 1) * (getHeight() - BORDER_GAP * 2)) / Y_HATCH_CNT + BORDER_GAP);
int y1 = y0;
g2.drawLine(x0, y0, x1, y1);
}
// and for x axis
for (int i = 0; i < scores.size() - 1; i++) {
int x0 = (i + 1) * (getWidth() - BORDER_GAP * 2) / (scores.size() - 1) + BORDER_GAP;
int x1 = x0;
int y0 = getHeight() - BORDER_GAP;
int y1 = y0 - GRAPH_POINT_WIDTH;
g2.drawLine(x0, y0, x1, y1);
}
Stroke oldStroke = g2.getStroke();
g2.setColor(GRAPH_COLOR);
g2.setStroke(GRAPH_STROKE);
for (int i = 0; i < graphPoints.size() - 1; i++) {
int x1 = graphPoints.get(i).x;
int y1 = graphPoints.get(i).y;
int x2 = graphPoints.get(i + 1).x;
int y2 = graphPoints.get(i + 1).y;
g2.drawLine(x1, y1, x2, y2);
}
g2.setStroke(oldStroke);
g2.setColor(GRAPH_POINT_COLOR);
for (int i = 0; i < graphPoints.size(); i++) {
int x = graphPoints.get(i).x - GRAPH_POINT_WIDTH / 2;
int y = graphPoints.get(i).y - GRAPH_POINT_WIDTH / 2;;
int ovalW = GRAPH_POINT_WIDTH;
int ovalH = GRAPH_POINT_WIDTH;
g2.fillOval(x, y, ovalW, ovalH);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
List<Integer> scores = new ArrayList<Integer>();
Random random = new Random();
int maxDataPoints = 16;
int maxScore = 20;
for (int i = 0; i < maxDataPoints ; i++) {
scores.add(random.nextInt(maxScore));
}
DrawGraph mainPanel = new DrawGraph(scores);
JFrame frame = new JFrame("DrawGraph");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Which will create a graph that looks like so:
Just complementing Hovercraft Full Of Eels's solution:
I reworked his code, tweaked it a bit, adding a grid, axis labels and now the Y-axis goes from the minimum value present up to the maximum value. I planned on adding a couple of getters/setters but I didn't need them, you can add them if you want.
Here is the Gist link, I'll also paste the code below: GraphPanel on Gist
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GraphPanel extends JPanel {
private int width = 800;
private int heigth = 400;
private int padding = 25;
private int labelPadding = 25;
private Color lineColor = new Color(44, 102, 230, 180);
private Color pointColor = new Color(100, 100, 100, 180);
private Color gridColor = new Color(200, 200, 200, 200);
private static final Stroke GRAPH_STROKE = new BasicStroke(2f);
private int pointWidth = 4;
private int numberYDivisions = 10;
private List<Double> scores;
public GraphPanel(List<Double> scores) {
this.scores = scores;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
double xScale = ((double) getWidth() - (2 * padding) - labelPadding) / (scores.size() - 1);
double yScale = ((double) getHeight() - 2 * padding - labelPadding) / (getMaxScore() - getMinScore());
List<Point> graphPoints = new ArrayList<>();
for (int i = 0; i < scores.size(); i++) {
int x1 = (int) (i * xScale + padding + labelPadding);
int y1 = (int) ((getMaxScore() - scores.get(i)) * yScale + padding);
graphPoints.add(new Point(x1, y1));
}
// draw white background
g2.setColor(Color.WHITE);
g2.fillRect(padding + labelPadding, padding, getWidth() - (2 * padding) - labelPadding, getHeight() - 2 * padding - labelPadding);
g2.setColor(Color.BLACK);
// create hatch marks and grid lines for y axis.
for (int i = 0; i < numberYDivisions + 1; i++) {
int x0 = padding + labelPadding;
int x1 = pointWidth + padding + labelPadding;
int y0 = getHeight() - ((i * (getHeight() - padding * 2 - labelPadding)) / numberYDivisions + padding + labelPadding);
int y1 = y0;
if (scores.size() > 0) {
g2.setColor(gridColor);
g2.drawLine(padding + labelPadding + 1 + pointWidth, y0, getWidth() - padding, y1);
g2.setColor(Color.BLACK);
String yLabel = ((int) ((getMinScore() + (getMaxScore() - getMinScore()) * ((i * 1.0) / numberYDivisions)) * 100)) / 100.0 + "";
FontMetrics metrics = g2.getFontMetrics();
int labelWidth = metrics.stringWidth(yLabel);
g2.drawString(yLabel, x0 - labelWidth - 5, y0 + (metrics.getHeight() / 2) - 3);
}
g2.drawLine(x0, y0, x1, y1);
}
// and for x axis
for (int i = 0; i < scores.size(); i++) {
if (scores.size() > 1) {
int x0 = i * (getWidth() - padding * 2 - labelPadding) / (scores.size() - 1) + padding + labelPadding;
int x1 = x0;
int y0 = getHeight() - padding - labelPadding;
int y1 = y0 - pointWidth;
if ((i % ((int) ((scores.size() / 20.0)) + 1)) == 0) {
g2.setColor(gridColor);
g2.drawLine(x0, getHeight() - padding - labelPadding - 1 - pointWidth, x1, padding);
g2.setColor(Color.BLACK);
String xLabel = i + "";
FontMetrics metrics = g2.getFontMetrics();
int labelWidth = metrics.stringWidth(xLabel);
g2.drawString(xLabel, x0 - labelWidth / 2, y0 + metrics.getHeight() + 3);
}
g2.drawLine(x0, y0, x1, y1);
}
}
// create x and y axes
g2.drawLine(padding + labelPadding, getHeight() - padding - labelPadding, padding + labelPadding, padding);
g2.drawLine(padding + labelPadding, getHeight() - padding - labelPadding, getWidth() - padding, getHeight() - padding - labelPadding);
Stroke oldStroke = g2.getStroke();
g2.setColor(lineColor);
g2.setStroke(GRAPH_STROKE);
for (int i = 0; i < graphPoints.size() - 1; i++) {
int x1 = graphPoints.get(i).x;
int y1 = graphPoints.get(i).y;
int x2 = graphPoints.get(i + 1).x;
int y2 = graphPoints.get(i + 1).y;
g2.drawLine(x1, y1, x2, y2);
}
g2.setStroke(oldStroke);
g2.setColor(pointColor);
for (int i = 0; i < graphPoints.size(); i++) {
int x = graphPoints.get(i).x - pointWidth / 2;
int y = graphPoints.get(i).y - pointWidth / 2;
int ovalW = pointWidth;
int ovalH = pointWidth;
g2.fillOval(x, y, ovalW, ovalH);
}
}
// #Override
// public Dimension getPreferredSize() {
// return new Dimension(width, heigth);
// }
private double getMinScore() {
double minScore = Double.MAX_VALUE;
for (Double score : scores) {
minScore = Math.min(minScore, score);
}
return minScore;
}
private double getMaxScore() {
double maxScore = Double.MIN_VALUE;
for (Double score : scores) {
maxScore = Math.max(maxScore, score);
}
return maxScore;
}
public void setScores(List<Double> scores) {
this.scores = scores;
invalidate();
this.repaint();
}
public List<Double> getScores() {
return scores;
}
private static void createAndShowGui() {
List<Double> scores = new ArrayList<>();
Random random = new Random();
int maxDataPoints = 40;
int maxScore = 10;
for (int i = 0; i < maxDataPoints; i++) {
scores.add((double) random.nextDouble() * maxScore);
// scores.add((double) i);
}
GraphPanel mainPanel = new GraphPanel(scores);
mainPanel.setPreferredSize(new Dimension(800, 600));
JFrame frame = new JFrame("DrawGraph");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
It looks like this:
Or simply use the JFreechart library - http://www.jfree.org/jfreechart/ .
There exist many open source projects that handle all the drawing of line charts for you with a couple of lines of code. Here's how you can draw a line chart from data in a couple text (CSV) file with the XChart library. Disclaimer: I'm the lead developer of the project.
In this example, two text files exist in ./CSV/CSVChartRows/. Notice that each row in the files represents a data point to be plotted and that each file represents a different series. series1 contains x, y, and error bar data, whereas series2 contains just x and y, data.
series1.csv
1,12,1.4
2,34,1.12
3,56,1.21
4,47,1.5
series2.csv
1,56
2,34
3,12
4,26
Source Code
public class CSVChartRows {
public static void main(String[] args) throws Exception {
// import chart from a folder containing CSV files
XYChart chart = CSVImporter.getChartFromCSVDir("./CSV/CSVChartRows/", DataOrientation.Rows, 600, 400);
// Show it
new SwingWrapper(chart).displayChart();
}
}
Resulting Plot
Override the paintComponent method of your panel so you can custom draw. Like this:
#Override
public void paintComponent(Graphics g) {
Graphics2D gr = (Graphics2D) g; //this is if you want to use Graphics2D
//now do the drawing here
...
}
Hovercraft Full Of Eels' answer is very good, but i had to change it a bit in order to get it working on my program:
int y1 = (int) ((this.height - 2 * BORDER_GAP) - (values.get(i) * yScale - BORDER_GAP));
instead of
int y1 = (int) (scores.get(i) * yScale + BORDER_GAP);
because if i used his way the graphic would be upside down
(you'd see it if you used hardcoded values (e.g 1,3,5,7,9) instead of random values)

Determine if circles intersect

I am working on a project where I have to draw 20 circles with random starting points and random sizes. Then I have to determine if any of the circles intersect. If a circle intersects with another, I have to color that circle green. And if the circle does not intersect with another, the color needs to be red. I have all of the code... I think... but when I run it, I still get some circles that should be green, but are red instead. Here is my code. Any help will be greatly appreciated.
import java.awt.Graphics;
import javax.swing.JPanel;
import java.util.Random;
import javax.swing.JFrame;
import java.awt.*;
public class IntersectingCircles extends JPanel
{
private int[] xAxis = new int [20]; // array to hold x axis points
private int[] yAxis = new int [20]; // array to hold y axis points
private int[] radius = new int [20]; // array to hold radius length
public static void main (String[] args)
{
JFrame frame = new JFrame("Random Circles");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add (new IntersectingCircles());
frame.pack();
frame.setVisible(true);
}
public IntersectingCircles()
{
setPreferredSize(new Dimension(1300, 800)); // set window size
Random random = new Random();
for (int i = 0; i < 20; i++)
{
xAxis[i] = random.nextInt(800) + 100;
yAxis[i] = random.nextInt(500) + 100;
radius[i] = random.nextInt(75) + 10;
}
}
public void paintComponent(Graphics g)
{
for (int i = 0; i < 20; i++)
{
int color = 0;
for (int h = 0; h < 20; h++)
{
if(i < h)
{
double x1 = 0, x2 = 0, y1 = 0, y2 = 0, d = 0;
x1 = (xAxis[i] + radius[i]);
y1 = (yAxis[i] + radius[i]);
x2 = (xAxis[h] + radius[h]);
y2 = (yAxis[h] + radius[h]);
d = (Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1)*(y2 - y1))));
if (d > radius[i] + radius[h] || d < (Math.abs(radius[i] - radius[h])))
{
color = 0;
}
else
{
color = 1;
break;
}
}
}
if (color == 0)
{
g.setColor(Color.RED);
g.drawOval(xAxis[i], yAxis[i], radius[i] * 2, radius[i] * 2);
}
else
{
g.setColor(Color.GREEN);
g.drawOval(xAxis[i], yAxis[i], radius[i] * 2, radius[i] * 2);
}
}
}
}
In the inside for loop, you are only comparing circles of i index with circles with h index, but only those with i < h, because of the condition:
for (int h = 0; h < 20; h++)
{
if(i < h)
{
...
So, instead you should compare every i circle with every h circle, except if they are the same. You want instead:
for (int h = 0; h < 20; h++)
{
if(i != h) //note the change here
{
...

Drawing a simple 2D graph in java

I got a below java code which plots a 2D graph where x axis has values 1,2,3,......20
and y axis has values 21,14,18..........18
The code works perfectly but the only problem is that the graph does not shows the corresponding x and y values on x axis and y axis respectively. I know it could be a small addition to the code. but i am new to java graphics and i am not able to figure out where to add the relevant code considering the time constraint.
/*Sample code */
public class GraphingData extends JPanel {
int[] data = {
21, 14, 18, 03, 86, 88, 74, 87, 54, 77,
61, 55, 48, 60, 49, 36, 38, 27, 20, 18
};
final int PAD = 20;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int w = getWidth();
int h = getHeight();
// Draw ordinate.
g2.draw(new Line2D.Double(PAD, PAD, PAD, h-PAD));
// Draw abcissa.
g2.draw(new Line2D.Double(PAD, h-PAD, w-PAD, h-PAD));
// Draw labels.
Font font = g2.getFont();
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = font.getLineMetrics("0", frc);
float sh = lm.getAscent() + lm.getDescent();
// Ordinate label.
String s = "Average Byte Value";
float sy = PAD + ((h - 2*PAD) - s.length()*sh)/2 + lm.getAscent();
for(int i = 0; i < s.length(); i++) {
String letter = String.valueOf(s.charAt(i));
float sw = (float)font.getStringBounds(letter, frc).getWidth();
float sx = (PAD - sw)/2;
g2.drawString(letter, sx, sy);
sy += sh;
}
// Abcissa label.
s = "file blocks";
sy = h - PAD + (PAD - sh)/2 + lm.getAscent();
float sw = (float)font.getStringBounds(s, frc).getWidth();
float sx = (w - sw)/2;
g2.drawString(s, sx, sy);
// Draw lines.
double xInc = (double)(w - 2*PAD)/(data.length-1);
double scale = (double)(h - 2*PAD)/getMax();
g2.setPaint(Color.green.darker());
for(int i = 0; i < data.length-1; i++) {
double x1 = PAD + i*xInc;
double y1 = h - PAD - scale*data[i];
double x2 = PAD + (i+1)*xInc;
double y2 = h - PAD - scale*data[i+1];
g2.draw(new Line2D.Double(x1, y1, x2, y2));
}
// Mark data points.
g2.setPaint(Color.red);
for(int i = 0; i < data.length; i++) {
double x = PAD + i*xInc;
double y = h - PAD - scale*data[i];
g2.fill(new Ellipse2D.Double(x-2, y-2, 4, 4));
}
}
private int getMax() {
int max = -Integer.MAX_VALUE;
for(int i = 0; i < data.length; i++) {
if(data[i] > max)
max = data[i];
}
return max;
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new GraphingData());
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
}
}
public void drawGrid(Graphics g)
{
g.setColor(Color.black);
int rows = model.maxy-model.miny+1;
int cols = model.maxx-model.minx+1;
int colWidth = (getWidth()-paddingFromRight - ylabelWidth)/cols;
int rowHeight = (getHeight()-xlabelHeight-headingHeight)/rows;
int endX = ylabelWidth + cols * colWidth;
int endY = headingHeight + rows*rowHeight;
for (int k = 0; k <= cols; k++)
{
g.drawLine(ylabelWidth+colWidth*k, headingHeight, ylabelWidth+colWidth*k, endY); //getHeight()-xlabelHeight
}
for (int k = 0; k <= rows;k++)
{
g.drawLine(ylabelWidth, headingHeight+rowHeight*k,endX, headingHeight+rowHeight*k);
}
}
public void drawLines(Graphics g)
{
ArrayList<Line> lines = model.getLines();
Random random = new Random(50);
for (int k = 0; k < lines.size(); k++)
{
g.setColor(new Color(255-50*k, 50*k, 2*50*k));
//g.setColor(Color.red);
drawLine(g, lines.get(k));
}
}
public void drawLine(Graphics g, Line line)
{
ArrayList<Point> points = line.points;
for (int k = 0; k<points.size()-1;k++)
{
//scale up points
Point p1 = points.get(k);
Point p2 = points.get(k+1);
g.drawLine(scaleUpX(p1.x), scaleUpY(p1.y), scaleUpX(p2.x), scaleUpY(p2.y));
g.fillOval(scaleUpX(p1.x)-5, scaleUpY(p1.y)-5, 10, 10);
}
Point p1 = points.get(points.size()-1);
g.fillOval(scaleUpX(p1.x)-5, scaleUpY(p1.y)-5, 10, 10);
}
public int scaleUpX(int x)
{
int cols = model.maxx-model.minx+1;
int colWidth = (getWidth()-paddingFromRight - ylabelWidth)/cols;
return ylabelWidth+colWidth*x;
}
public int scaleUpY(int y)
{
int rows = model.maxy-model.miny+1;
int rowHeight = (getHeight()-xlabelHeight-headingHeight)/(rows);
//int endY = getHeight()-xlabelHeight;
int endY = headingHeight+rows*rowHeight;
return endY - rowHeight*y;
}
public void drawLabels(Graphics g)
{
Dimension d = getSize();
//xlabel
g.drawString(model.xlabel, d.width/2, d.height-xlabelHeight/4);
//ylabel
g.drawString(model.ylabel, 0+5, d.height/2);
//xaxis
int rows = model.maxy-model.miny+1;
int cols = model.maxx-model.minx+1;
int colWidth = (getWidth()-paddingFromRight - ylabelWidth)/cols;
int rowHeight = (getHeight()-xlabelHeight-headingHeight)/rows;
for (int k = 0;k<=cols;k++)
{
g.drawString(String.valueOf(model.minx+k), ylabelWidth+k*colWidth-5, rowHeight*rows+headingHeight+15);
}
//yaxis
for (int k = 0;k<=rows;k++)
{
g.drawString(String.valueOf(model.maxy-k+1),ylabelWidth-15,headingHeight+k*rowHeight);
}
//heading
FontMetrics fm = g.getFontMetrics();
g.setFont(g.getFont().deriveFont((float)25.0));
g.drawString(model.title, d.width/2-fm.stringWidth(model.title), headingHeight/2+headingHeight/4);
}

Categories