If you run this program you will notice that the table that displays the celsius conversion looks funky. What I have been trying to do is have it stop at the tenth place. I really would I appreciate any feedback. Thanks in advance.
Output:
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
public class Foo extends Frame
{
public Foo()
{
setTitle(" Fahrenheit To Celsius Chart");
setSize(400, 600);
setVisible(true);
addWindowListener(
new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);
}
public static void main(String[] args)
{
Foo chart = new Foo();
}
public void paint (Graphics g)
{
for(int i = 0; i < 25; i++)
{
g.setColor(Color.BLACK);
g.setFont(new Font("SansSerif", Font.BOLD, 14 ));
g.drawString("Fahrenheit", 70, 110);
g.drawString("Celsius", 200, 110);
int[] tempF = new int[25];
int y = 100, x = 130;
int y1 = 215, x1 = 130;
tempF[0] = 0;
int counter = 0;
while(counter < 26)
{
int index = 0;
String Fahrenheit = String.valueOf(tempF[index]);
double tempC = (tempF[index] - 32) * (5/9.0);
String Celsius = String.valueOf(tempC);
String formatedCelcius = String.format("%.1f", tempC);
g.drawString(Fahrenheit, y, x);
g.drawString(Celsius, y1, x1);
x += 15;
x1 += 15;
tempF[index] += 10;
index++;
counter++;
}
}
}
}
The code for rendering the temperatures should look like:
String Fahrenheit = String.valueOf(tempF[index]);
double tempC = (tempF[index] - 32) * (5/9.0);
String formattedCelcius = String.format("%.1f", tempC);
g.drawString(Fahrenheit, y, x);
g.drawString(formattedCelcius, y1, x1);
In your code, you did:
String.format("%.1f", Celsius);
Rather than:
String.format("%.1f", tempC);
(I hope the difference is clear)
The %f format specifier expects a Double argument (like tempC) but you were passing in a String (Celsius)
This caused a java.util.IllegalFormatConversionException: f != java.lang.String (which you may not have seen as the exception was thrown into the Swing event thread) which aborted the rest of paint method.
Thank you everyone for your feedback. I found the solution. The Math class has a function round() that did the trick. I put this in and it fixed the issue:
double tempC = (tempF[index] - 32) * (5/9.0);
double c = Math.round(tempC);
After changing this I'm getting the proper output:
Final Output
Again, thank you all for your feedback.
Best regards,
DDKGM
Related
I'm trying to write a code that approximates the value of PI.
What I'm doing is:
drawing a circle inside a rectangle
drawing random points inside the rectangle and circle
calculating the ratio between rect/cicle
calculating 4/ratio
that should be PI
This my code:
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Random;
public class Main extends Frame {
int width = 800;
ArrayList<Point> list = new ArrayList<Point>();
public void points(Graphics g) {
int numPoint = 10000000;
for (int i = 0; i < numPoint; i++) {
int min = 23;
int max = 23 + width;
Random rand = new Random();
int x = rand.nextInt(width);
int y = (int) (Math.random() * (max - min + 1) + min);
Point temp = new Point(x, y);
list.add(temp);
if (inCircle(temp)) {
g.setColor(Color.green);
} else {
g.setColor(Color.blue);
}
g.drawLine(x, y, x, y);
}
}
public void paint(Graphics g) {
g.fillRect(0, 0, 1000, 1000);
int x = width / 2;
int y = width / 2 + 23;
int radius = width / 2;
g.setColor(Color.WHITE);
g.drawOval(x - radius, y - radius, radius * 2, radius * 2);
g.drawRect(0, 23, width, width);
points(g);
calculatingPI();
}
public void calculatingPI() {
double inCircle = 0;
double inRect = list.size();
for (Point p : list) {
if (inCircle(p)) {
inCircle++;
}
}
double ratio = inRect / inCircle;
System.out.print("PI is approximated to: " + 4 / ratio + " ");
}
public boolean inCircle(Point p) {
Point center = new Point(width / 2, width / 2 + 23);
return center.distance(p) <= width / 2;
}
public static void main(String[] args) {
Frame frame = new Main();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
// circle coordinates.
frame.setSize(800, 1000);
frame.setVisible(true);
}
}
It works quite fine, even if most of the time the number is around 1,13 which is not a great approx.
The question is:
The more I decrease the size of the rectangle and circle, (without changing the number of points), the less PI becomes accurate. I don't understand, why is that? Is there a problem in my code?
Shouldn't it be the opposite? The smallest the area, the more points are accurate, the more PI is accurate. Why is isn't it the case?
You are using integer pixels. This means the smaller you make your "circle", the worse it approximates a true circle. For example here's the circle within a 3x3 pixel square: it does not look circular at all.
█
███
█
To get a better approximation, use double floating point numbers instead of integers. Use Point2D.Double instead of the Point class:
ArrayList<Point2D.Double> list = new ArrayList<>();
To generate the random points:
double x = Math.random() * width;
double y = Math.random() * (max - min) + min;
Point2D.Double temp = new Point2D.Double(x, y);
Note that where you had max-min+1, the +1 has to be removed.
To test if the point is within the circle:
public boolean inCircle(Point2D.Double p) {
Point2D.Double center = new Point2D.Double(width / 2d, width / 2d + 23);
return center.distance(p) <= width / 2d;
}
I'm making a derivative calculator that asks the user for the degree of their polynomial and then the coefficients for each term, partly because I'm an inexperienced programmer and can't parse input like 3x^4/4 + sin(x).
Here's my class.
package beta;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
public class DerivativeCalculator
{
public DerivativeCalculator(String d, String v)
{
int degree = Integer.parseInt(d);
double value = Double.parseDouble(v);
coeffList = new ArrayList<Double>();
for (int i = 0; i <= degree; i++)
{
String console = JOptionPane.showInputDialog("Enter the coefficient of the "
+ "x^" + i + " term.");
Double coeff = Double.parseDouble(console);
coeffList.add(coeff);
}
}
public double calc()
{
double dx = 0.0001;
double x1 = value;
double y1 = 0;
for (int d = degree; d >= 0; d--)
{
y1 += coeffList.get(d) * Math.pow(x1, d);
}
double x2 = x1 + dx;
double y2 = 0;
for (int d = degree; d >= 0; d--)
{
y2 += coeffList.get(d) * Math.pow(x2, d);
}
double slope = (y2 - y1)/ (x2 - x1);
DecimalFormat round = new DecimalFormat("##.##");
round.setRoundingMode(RoundingMode.DOWN);
return Double.valueOf(round.format(slope));
}
public String getEquation()
{
String equation = "";
for (int d = degree; d >= 0; d--)
{
equation = equation + String.valueOf(coeffList.get(d)) + "x^" + String.valueOf(d) + " + ";
}
return equation;
}
public String getValue()
{
return String.valueOf(value);
}
private int degree;
private double value;
private List<Double> coeffList;
}
Now here's my test class.
package beta;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JApplet;
import javax.swing.JOptionPane;
public class DerivativeCalculatorTest extends JApplet
{
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
String d = JOptionPane.showInputDialog("Enter the degree of your polynomial: ");
String v = JOptionPane.showInputDialog("Enter the x value "
+ "at which you want to take the derivative");
DerivativeCalculator myDerivCalc = new DerivativeCalculator(d, v);
g2.drawString(String.valueOf(myDerivCalc.calc()), 10, 100);
g2.drawString(myDerivCalc.getEquation(), 10, 40);
g2.drawString(myDerivCalc.getValue(), 10, 70);
}
}
Running this creates an applet window that displays
5.0x^0+
0.0
0.0
which is not the correct derivative.
I debugged my program and everything runs as expected until the view switches to my test class and it executes g2.drawString(String.valueOf(myDerivCalc.calc()), 10, 100);
After it executes this line, degree (the degree of the polynomial) resets to 0 even though the user entered 5. This then messes up all the for loops in my class.
Why does this happen? Any suggestions on fixing this? Thanks
You redefine degree and value as local variables inside your constructor. They shadow your class variables with the same name.
Do not re-declare them.
Instead of
int degree = <something>;
double value = <something>;
you need
degree = <something>;
value = <something>;
Isn't 5.0x^0 = 5.0 * 1 = 5.0, and the derivative of that is 0..
I believe your code is working.
I have to write a program that will generate 20 random circles with random radius lengths. If any of these circles intersect with another, the circle must be blue, and if it does not intersect, the color is red. I must also place a button on the JFrame. If this button is pressed, it needs to clear out the JFrame, and generate a new set of 20 circles following the same color rules. I am extremely new to Java Swing and am really stuck. I have everything working except the button. I cannot get a new set of circles to generate. Any help would be greatly appreciated. Thank You.
import java.awt.Graphics;
import javax.swing.JPanel;
import java.util.Random;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
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(1000, 800)); // set window size
Random random = new Random();
// Create coordinates for circles
for (int i = 0; i < 20; i++)
{
xAxis[i] = random.nextInt(700) + 100;
yAxis[i] = random.nextInt(500) + 100;
radius[i] = random.nextInt(75) + 10;
}
}
public void paintComponent(Graphics g)
{
// Add button to run again
JButton btnAgain = new JButton("Run Again");
btnAgain.setBounds(850, 10, 100, 30);
add(btnAgain);
btnAgain.addActionListener(new ButtonClickListener());
// Determine if circles intersect, create circles, color circles
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.BLUE);
g.drawOval(xAxis[i], yAxis[i], radius[i] * 2, radius[i] * 2);
}
}
}
private class ButtonClickListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String action = e.getActionCommand();
if(action.equals("Run Again"))
{
new IntersectingCircles();
}
}
}
}
Suggestions:
Give your class a method that creates the random circles and calls repaint()
This method should create the circles and add them into an ArrayList.
Consider using Ellipse2D to represent your circles, and so you'd have an ArrayList<Ellipse2D>.
Call this method in your class constructor.
Call it again in the button's ActionListener.
Never add button's or change the state of your class from within your paintComponent method. This method is for drawing the circles and drawing them only and nothing more. Your way you will be creating the button each time the paintComponent method is called, so you could be potentially needlessly creating many JButtons
and needlessly slowing down your time-critical painting method.
Instead add the button in the constructor.
Be sure to call super.paintComponent(g) in your paintComponent method as its first call. This will clear the old circles when need be.
Also in paintComponent, iterate through the ArrayList of circles, drawing each one.
After some searching on this website, i found what i needed. Everything seems to work now. Thanks.
import java.awt.Graphics;
import javax.swing.JPanel;
import java.util.Random;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
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.setPreferredSize(new Dimension(1000, 800));
ActionListener runAgain = new ActionListener()
{
#Override
public void actionPerformed(ActionEvent c)
{
frame.getContentPane().add(new IntersectingCircles());
frame.pack();
}
};
JButton btnAgain = new JButton("Run Again");
btnAgain.setBounds(850, 10, 100, 30);
btnAgain.addActionListener(runAgain);
frame.add(btnAgain);
frame.getContentPane().add (new IntersectingCircles());
frame.pack();
frame.setVisible(true);
}
public IntersectingCircles()
{
Random random = new Random();
// Create coordinates for circles
for (int i = 0; i < 20; i++)
{
xAxis[i] = random.nextInt(700) + 100;
yAxis[i] = random.nextInt(500) + 100;
radius[i] = random.nextInt(75) + 10;
}
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// Determine if circles intersect, create circles, color circles
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.BLUE);
g.drawOval(xAxis[i], yAxis[i], radius[i] * 2, radius[i] * 2);
}
}
}
}
private class ButtonClickListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
repaint();
}
}
Maybe you can have a try...
I am making a program that plots the decay of atoms. Here is my main, which also does the logic. However, I am getting a undefined constructor error, when it is clearly defined in the other class. Why is this happening?
Caution: it isn't notated. Spare me your wrath.
import java.util.Random;
import java.awt.*;
import javax.swing.*;
import javax.swing.JFrame;
public class Main {
public static void main(String args[]) {
int chance = 6;
Random r = new Random();
int num = 40;
int[] decayed;
int reps = 25;
decayed = new int[reps];
for (int j = 1; j < reps+1; j++) {
for (int i = 0; i < num; i++) {
int c = r.nextInt(chance);
if (c == chance - 1) {
decayed[j]++;
}
}
System.out.printf("\n Trial: " + j + "\n Number left: " + num
+ "\n Decayed: " + decayed[j] + "\n\n");
num = num - decayed[j];
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new Graph(decayed[])); //"Constuctor is undefined for type int" When I am clearly specifying an array.
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
}
}
And my Graph.class. It is copied from some forum (Credit to Crieg Wood).
import java.awt.*;
import javax.swing.*;
import java.util.*;
public class Graph extends JPanel
{
int PAD = 20;
boolean drawLine = true;
boolean drawDots = true;
int dotRadius = 3;
// the y coordinates of the points to be drawn; the x coordinates are evenly spaced
int[] data;
public Graph(int points[]){ //This is the constructor which specifies type int[].
for (int i = 0; i<points.length; i++){ //Copies points[] to data[]
data[i] = points[i];
}
}
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();
g2.drawLine(PAD, PAD, PAD, h-PAD);
g2.drawLine(PAD, h-PAD, w-PAD, h-PAD);
double xScale = (w - 2*PAD) / (data.length + 1);
double maxValue = 100.0;
double yScale = (h - 2*PAD) / maxValue;
// The origin location
int x0 = PAD;
int y0 = h-PAD;
// draw connecting line
if (drawLine)
{
for (int j = 0; j < data.length-1; j++)
{
int x1 = x0 + (int)(xScale * (j+1));
int y1 = y0 - (int)(yScale * data[j]);
int x2 = x0 + (int)(xScale * (j+2));
int y2 = y0 - (int)(yScale * data[j+1]);
g2.drawLine(x1, y1, x2, y2);
}
}
// draw the points as little circles in red
if (drawDots)
{
g2.setPaint(Color.red);
for (int j = 0; j < data.length; j++)
{
int x = x0 + (int)(xScale * (j+1));
int y = y0 - (int)(yScale * data[j]);
g2.fillOval(x-dotRadius, y-dotRadius, 2*dotRadius, 2*dotRadius);
}
}
}
}
The problems here are with the usage of those [] brackets.
Try to re-write your call:
f.getContentPane().add(new Graph(decayed));
Though you were not incorrect, please consider re-writing your constructor to hold to the Java standards and conventions:
public Graph(int[] points){ // NOTE: I moved the [] to a the standard position
for (int i = 0; i<points.length; i++){
data[i] = points[i];
}
}
Your syntax is invalid, to refer to your array, simply use the variable name, without the []:
f.getContentPane().add(new Graph(decayed));
Just replace this f.getContentPane().add(new Graph(decayed[]));
with this
f.getContentPane().add(new Graph(decayed));
Just use the name of the variable that you have created without that [].
Those [] brackets are used only at the time of declaration of the method parameters for arrays and not when calling the method.
How to find variable g in this code? I would like to draw line using fillRect from paintComponent.
Please help.
import java.awt.*;
import java.lang.String.*;
import java.util.Scanner;
import java.io.IOException;
import javax.swing.*;
class Test extends JPanel {
public static void main(String[] args) {
String x1;
String x2;
String y1;
String y2;
Scanner sc = new Scanner(System.in);
System.out.print("Podaj pierwsza wspolrzedna pierwszego punktu: ");
x1 = sc.nextLine();
System.out.print("Podaj druga wspolrzedna pierwszego punktu: ");
x2 = sc.nextLine();
System.out.print("Podaj pierwsza wspolrzedna drugiego punktu: ");
y1 = sc.nextLine();
System.out.print("Podaj druga wspolrzedna drugiego punktu: ");
y2 = sc.nextLine();
Test nowy = new Test();
DDA2 dda2 = new DDA2();
dda2.licz(x1, x2, y1, y2);
JFrame ramka = new JFrame();
ramka.setSize(300,300);
ramka.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ramka.getContentPane().add(new Test());
ramka.setVisible(true);
}
}
class DDA2 {
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.RED);
}
public void licz(String xx1, String xx2, String yy1, String yy2){
double dxx1 = Double.parseDouble(xx1);
double dxx2 = Double.parseDouble(xx2);
double dyy1 = Double.parseDouble(yy1);
double dyy2 = Double.parseDouble(yy2);
double dx = dxx2 - dxx1;
double dy = dyy2 - dyy1;
if (Math.abs(dx) >= Math.abs(dy))
{
double m = Math.abs(dx);
System.out.println("DX" + m);
}
else
{
// ALGORYTYM PRZYROSTOWY
double m = Math.abs(dy);
//System.out.println("DY" + m);
double x = dxx1;
double y = dyy1;
for (int i=1; i <= m; i++)
{
x = x + dx/m;
y = y + dy/m;
g.fillRect((int) x, (int) y, 1, 1);
}
}
System.out.println("Wspolrzednie punktu pierwszego to: " + "(" + dxx1 + "; " + dxx2 +")");
System.out.println("Wspolrzednie punktu drugiego to: " + "(" + dyy1 + "; " + dyy2 + ")");
}
}
You need to override the paintComponent(Graphics g) method in the class that extends the JPanel, i.e. your Test class. You wrote a paintComponent method in a class DDA2 but that does nothing.
In the paintComponent method you can then call:
g.fillRect(x, y, w, h);
In addition to what Vincent says, it looks like you want to have the fillRect taking place in your licz method. No problem. Simply call your licz method from the paintComponent method. (It's easiest to do this if your method is defined in the same class as the paintComponent method, by the way.)