I am doing a problem I found online for practice and I am having trouble figuring out a step. My goal is to print 6 concentric circles with random colors while using an array as the diameter.
I have managed to get everything working except my circles are not concentric and seem to just draw away from each other.
Any ideas?
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
import java.awt.*;
import java.util.Random;
public class E3 {
public static int [] diameters = new int[6];
public static void main(String[] args) throws FileNotFoundException {
Scanner console = new Scanner(new File("Practice47.txt"));
int panelX = 400, panelY = 400;
DrawingPanel panel = new DrawingPanel(panelX, panelY);
panel.setBackground(Color.WHITE);
Graphics g = panel.getGraphics();
Random r = new Random();
int xCenter = r.nextInt(400);
int yCenter = r.nextInt(400);
for (int i = 0; i < diameters.length; i++) {
diameters[i]=console.nextInt();
g.setColor(new Color(r.nextInt(256),r.nextInt(256), r.nextInt(256)));
g.fillOval(xCenter, yCenter, diameters[i], diameters[i]);
}
for (int i=0;i<diameters.length;i++)
System.out.println("diameters["+i+"] = "+ diameters[i]);
}
}
Here's what my output looks like:
Your fixpoint is the top left corner initially created instead of the middle of the circles. This happens because you specify the rectangle in which to draw an oval inside with fillOval(leftOffset, topOffset, width, height) and not like in your program.
To correct this:
calculate a fixpoint (x0|y0) in your case (xCenter|yCenter), so this step is already done
use fillOval(x0 - d/2, y0 - d/2, d, d) where d is the diameter
Related
I just started to study Java. I am trying to make a program that will show five circles (random color, size and placement). I thought I would try to draw one circle (before I try five). But I draw two circles! What is going on? How is it drawing two circles?
Here is my code:
import java.awt.Graphics;
import java.awt.Color;
import javax.swing.JFrame;
import java.util.Random;
public class Rita extends JFrame
{
public Rita()
{
setTitle("Rita");
setSize(960, 960);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void paint(Graphics g)
{
// Initiateea random object
Random rand = new Random();
// loop to draw cicles
//for (int i = 0; i<5; i++);
//Initiate random color
int red = rand.nextInt(256);
int green = rand.nextInt(256);
int blue = rand.nextInt(256);
Color randomColor = new Color (red, green, blue);
// Generate random circle width 20 and X pixels
int width = rand.nextInt(201) + 20;
// Generate random X/Y koordinater
int radius = (int)(Math.random()*49) + 2;
int x = (int)(Math.random()*(960-radius*2) + radius);
int y = (int)(Math.random()*(960-radius*2) + radius);
//int x = rand.nextInt(960);
//int y = rand.nextInt(960);
// set the color
g.setColor(randomColor);
// Draw the circle
g.fillOval(x, y, width, width); // aka rita oval, storlek
}
public static void main(String[] args)
{
Rita rita= new Rita();
rita.paint(null);
}
}
I tried to put this code in to hopefully override the two circles drawn or something. It didn't work (of course I deleted the comment-slashes first). It still draws two circles.
// loop to draw cicles
//for (int i = 0; i<5; i++);
Before anything: Is it alright to submit a question to Stack Overflow when you're trying to learn to code? I've really put about 20 hours into this problem and am entirely stuck, but if I should remain stuck for the experience of realizing how to craft my own solutions, please say the word Stack Overlords.
I am attempting to create a function that creates ten circles of a semi-random size and location and a random color.
The size and location are semi-random because the circle's radius must be between 5 - 50 pixels; the location must be within the Jpanel.
The color can be anything. The production of the circles must stop at ten and all the circles must be static in the same Jpanel at once.
I've finished the problem almost entirely asides from being able to get the ten circles to remain static within the Jpanel after they've been generated.
I've tried applying a basic for-loop around various sections of the code I thought could produce the desired result. My for-loop is shown below.
for(int i = 0; i < 10; ++i) {
}
package assignment3;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
import javax.swing.JFrame;
public class Random_Circles extends JPanel{
private static final long serialVersionUID = 1L;
// Below is the input for our random size.
public static int RandomSize() {
double randomDouble = Math.random();
randomDouble = randomDouble * 50 + 1;
int randomInt = (int) randomDouble;
return randomInt;
}
// Below is the input for our random X-coordinate.
public static int RandomPosition1() {
double randomDouble = Math.random();
randomDouble = randomDouble * 900 + 1;
int randomInt = (int) randomDouble;
return randomInt;
}
// Below is the input for our random Y-coordinate.
public static int RandomPosition2() {
double randomDouble = Math.random();
randomDouble = randomDouble * 400 + 1;
int randomInt = (int) randomDouble;
return randomInt;
}
// I don't really know what this does, but I've gotta do it apparently.
Random rand = new Random();
// Below is the input for our random color.
public void paintComponent(Graphics RC) {
super.paintComponent(RC);
this.setBackground(Color.white);
// Random Size
int RS;
RS = RandomSize();
// X-coordinate
int RP1;
RP1 = RandomPosition1();
// Y-coordinate
int RP2;
RP2 = RandomPosition2();
// Color inputs
float r = rand.nextFloat();
float g = rand.nextFloat();
float b = rand.nextFloat();
Color randomColor = new Color(r, g, b);
// Color function
RC.setColor(randomColor);
// Location and size function
RC.fillOval(RP1, RP2, RS, RS);
}
}
Main function that produces Jpanel, calls previous code.
package assignment3;
import javax.swing.JFrame;
import assignment3.Random_Circles;
public class Random_Circles_Exe {
public static void main(String[] args) {
JFrame f = new JFrame("Random Cirlces");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Random_Circles r = new Random_Circles();
f.add(r);
f.setSize(1000,500);
f.setVisible(true);
}
}
Expected: Ten circles with the required parameters appearing and remaining in the JPanel.
Actual: Ten circles being generated the second the function runs, but with each new circle the old one expires. With re-sizing the JPanel ( just by clicking and dragging its border ), more circles are generated.
I am having trouble getting my histogram to fill correctly.
I was given a large data file full of doubles that represented GPAs, about 5500 of them. I created a method to calculate the count, mean, and standard deviation of the data, however my last problem is to graph the data.
I am to make a histogram for each of the possible grades (12 of them) and graph them about the total of each grade.
I think I have coded the total for each grade correctly, but when it comes to actually drawing the histogram I cannot figure out the 4 arguments needed for fillRect.
I've been playing around with different variables, but nothing seems to get me close.
Any help is appreciated.
private static int[] gradeCounts(double[] stats) throws Exception{
double stdv = 0;
double sum = 0;
double sum2 = 0;
double variance = 0;
Scanner fsc = new Scanner(new File("introProgGrades.txt"));
while (!fsc.hasNextDouble())
fsc.nextLine();
int[] binCounts = new int[NUM_OF_GRADE_CATEGORIES];
double x = 0;
while (fsc.hasNextDouble()){
stats[2]++;
x = fsc.nextDouble();
sum += x;
sum2 += x * x;
if (x == 0.0)
binCounts[0]++;
else if (x == 0.6666667)
binCounts[1]++;
else if (x == 1.0)
binCounts[2]++;
else if (x == 1.3333333)
binCounts[3]++;
else if (x == 1.6666667)
binCounts[4]++;
else if (x == 2.0)
binCounts[5]++;
else if (x == 2.3333333)
binCounts[6]++;
else if (x == 2.6666667)
binCounts[7]++;
else if (x == 3.0)
binCounts[8]++;
else if (x == 3.3333333)
binCounts[9]++;
else if (x == 3.6666667)
binCounts[10]++;
else
binCounts[11]++;
}
stats[0] = sum/stats[2];
variance = (stats[2] * sum2 - sum * sum) / (stats[2]*(stats[2]-1));
stdv = Math.sqrt(variance);
stats[1] = stdv;
return binCounts;
}
What I am having trouble with:
private static void plotHistogram(int[] binCounts){
int max = Arrays.stream(binCounts).max().getAsInt();
DrawingPanel panel = new DrawingPanel (800,800);
Graphics2D g = panel.getGraphics();
g.fillRect(0, 0, 800/binCounts.length,max);
}
I think I have to iterate through the data with a for loop, but it's the parameters of fillRect that I am clueless on.
but when it comes to actually drawing the histogram I cannot figure out the 4 arguments needed for fillRect.
The JavaDocs are quite explicit in the properties and their meanings, it's just a box, with a position (x/y) and size (width/height)
public abstract void fillRect​(int x,
int y,
int width,
int height)
Fills the specified rectangle. The left and right edges of the rectangle are at x and x +
width - 1. The top and bottom edges are at y and y + height - 1. The
resulting rectangle covers an area width pixels wide by height pixels
tall. The rectangle is filled using the graphics context's current
color. Parameters: x - the x coordinate of the rectangle to be filled.
y - the y coordinate of the rectangle to be filled. width - the width
of the rectangle to be filled. height - the height of the rectangle to
be filled.
I've been playing around with different variables, but nothing seems to get me close.
So, two things come to mind, the first comes from the JavaDocs above...
The rectangle is filled using the graphics context's current
color
This is something that's easy to forget
The second is it seems that you misunderstand how painting works in Swing.
Painting in Swing has a very specific and well documented workflow. The first thing you should do is go read Performing Custom Painting and Painting in AWT and Swing to get a better understanding of how painting works and how you should work with it.
There is never a good reason to call JComponent#getGraphics, apart from been able to return null, this is just a snapshot of the last paint cycle and will be wiped clean on the next paint pass (which may occur at any time for any number of reasons).
Instead, you will need a custom component and override it's paintComponent method instead.
You should then have a read through the 2D Graphics trail to get a better understanding of how the API works and what features/functionality it can provide.
For example....
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.Arrays;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Random rnd = new Random();
int[] binCounts = new int[10];
for (int index = 0; index < binCounts.length; index++) {
binCounts[index] = rnd.nextInt(100);
}
JFrame frame = new JFrame();
frame.add(new DrawingPanel(binCounts));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawingPanel extends JPanel {
private int[] binCounts;
private int max;
public DrawingPanel(int[] binCounts) {
this.binCounts = binCounts;
max = Arrays.stream(binCounts).max().getAsInt();
System.out.println(max);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 800);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int barWidth = 800 / binCounts.length;
for (int i = 0; i < binCounts.length; i++) {
int barHeight = (int)((binCounts[i] / (double)max) * getHeight());
// I personally would cache this until the state of the component
// changes, but for brevity
Rectangle rect = new Rectangle(i * barWidth, getHeight() - barHeight, barWidth, barHeight);
g2d.setColor(Color.BLUE);
g2d.fill(rect);
g2d.setColor(Color.BLACK);
g2d.draw(rect);
}
g2d.dispose();
}
}
}
Please help. I am trying to use the Java Random class to draw spirals of random locations, size, color, etc. on drawing canvas. I am able to get the Random class to work when I call my drawCurvedSpiral method. However, sometimes it will print some of my spirals partially off the screen. So, how can I prevent this from happening?
Below is what I have...
import java.awt.Graphics;
import java.awt.Color;
import java.util.Random;
public class AbstractArt
{
public static void main(String[] args)
{
DrawingCanvas canvas = new DrawingCanvas();
Graphics g = canvas.getGraphics();
Random rand = new Random();
for (int i = 0; i < 10; i++)
{
int width = 25 + rand.nextInt(76);
int arc = 0 + rand.nextInt(361);
int x = rand.nextInt(canvas.getWidth()-width);
int y = rand.nextInt(canvas.getHeight()-width);
drawCurvedSpiral(g, x, y, width, width, arc, arc, getRandomCOlor());
}
}
I have some code here, and it graphs exponentially but, it graphs the wrong way. negative exponential growth. Here is my code, I'm trying to flip it up. I'll be working on it, but if you have an answer please tell me.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Graphics extends JPanel{
public static void main(String[] args) {
JFrame f =new JFrame ("Function");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Graphics g = new Graphics();
f.add(g);
f.setSize(700, 700);
f.setVisible(true);
}
public void paintComponent (java.awt.Graphics g) {
super.paintComponent(g);
int i = this.getWidth()-this.getWidth() + 5;
int xoffset = this.getWidth()/2;
int yoffset = this.getHeight()/2;
for (int x = 0 ; x < 20 ; x++){
g.setColor(Color.BLACK);
this.setBackground(Color.WHITE);
int p = x*x;
g.fillRect(i+xoffset,10+yoffset,5,p);
i = i + 10;
}
}
}
Does anyone know how to fix this?
Change the x/y position at where the rectangle starts to draw from (it always draws right/down)
So instead of
g.fillRect(i+xoffset,10+yoffset,5,p);
you could have...
g.fillRect(i + xoffset, 10 + yoffset - p, 5, p);
I've got no idea what your intentions are for int i = this.getWidth()-this.getWidth() + 5;, but clearly makes no sense (width - width == 0?)