Analog Clock working but seconds repainting - java

I made an Analog Clock and its working but when a remove the filloval (Background) the seconds hand keep repeating itself and but when i add filloval it is working. but i do not want the background there. Thanks
here is the code
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Clock extends JPanel implements Runnable {
Thread thread = null;
SimpleDateFormat formatter = new SimpleDateFormat("s", Locale.getDefault());
Date currentDate;
int xcenter = 175, ycenter = 175, lastxs = 0, lastys = 0, lastxm = 0, lastym = 0, lastxh = 0, lastyh = 0;
private void drawStructure(Graphics g) {
g.setFont(new Font("TimesRoman", Font.BOLD, 20));
g.setColor(Color.black);
//g.fillOval(xcenter - 150, ycenter - 150, 300, 300);
g.setColor(Color.blue);
g.setColor(Color.green);
g.drawString("9", xcenter - 145, ycenter + 0);
g.drawString("3", xcenter + 135, ycenter + 0);
g.drawString("12", xcenter - 10, ycenter - 130);
g.drawString("6", xcenter - 10, ycenter + 145);
}
public void paint(Graphics g) {
int xhour, yhour, xminute, yminute, xsecond, ysecond, second, minute, hour;
drawStructure(g);
currentDate = new Date();
formatter.applyPattern("s");
second = Integer.parseInt(formatter.format(currentDate));
formatter.applyPattern("m");
minute = Integer.parseInt(formatter.format(currentDate));
formatter.applyPattern("h");
hour = Integer.parseInt(formatter.format(currentDate));
xsecond = (int) (Math.cos(second * 3.14f / 30 - 3.14f / 2) * 120 + xcenter);
ysecond = (int) (Math.sin(second * 3.14f / 30 - 3.14f / 2) * 120 + ycenter);
xminute = (int) (Math.cos(minute * 3.14f / 30 - 3.14f / 2) * 100 + xcenter);
yminute = (int) (Math.sin(minute * 3.14f / 30 - 3.14f / 2) * 100 + ycenter);
xhour = (int) (Math.cos((hour * 30 + minute / 2) * 3.14f / 180 - 3.14f / 2) * 80 + xcenter);
yhour = (int) (Math.sin((hour * 30 + minute / 2) * 3.14f / 180 - 3.14f / 2) * 80 + ycenter);
// Erase if necessary, and redraw
g.drawLine(xcenter, ycenter, xsecond, ysecond);
g.setColor(Color.red);
g.drawLine(xcenter, ycenter - 1, xminute, yminute);
g.drawLine(xcenter - 1, ycenter, xminute, yminute);
g.setColor(Color.green);
g.drawLine(xcenter, ycenter - 1, xhour, yhour);
g.drawLine(xcenter - 1, ycenter, xhour, yhour);
lastxs = xsecond;
lastys = ysecond;
lastxm = xminute;
lastym = yminute;
lastxh = xhour;
lastyh = yhour;
}
public void start() {
if (thread == null) {
thread = new Thread(this);
thread.start();
}
}
public void stop() {
thread = null;
}
public void run() {
while (thread != null) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
repaint();
}
thread = null;
}
public void update(Graphics g) {
paint(g);
}
public static void main(String args[]) {
JFrame frame = new JFrame();
Color c = new Color(118, 73, 190);
frame.setBackground(c);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0, 0, 400, 400);
Clock clock = new Clock();
frame.getContentPane().add(clock);
frame.setVisible(true);
}
}

Instead of overriding paint(), Swing programs should override paintComponent(). In addition, invoke super.paintComponent() to avoid this kind of rendering artifact. A similar problem is illustrated in this related example. Some additional observations:
Swing programs should be constructed and updates on the event dispatch thread.
Use a Swing timer to update the display.
As tested:
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
//* #see https://stackoverflow.com/a/26213625/230513 */
public class Clock extends JPanel {
private Timer t = new Timer(1000, (ActionEvent e) -> {
repaint();
});
private SimpleDateFormat formatter = new SimpleDateFormat("s", Locale.getDefault());
private Date currentDate;
private int xcenter = 175, ycenter = 175, lastxs = 0, lastys = 0, lastxm = 0, lastym = 0, lastxh = 0, lastyh = 0;
private void drawStructure(Graphics g) {
g.setFont(new Font("TimesRoman", Font.BOLD, 20));
g.drawString("9", xcenter - 145, ycenter + 0);
g.drawString("3", xcenter + 135, ycenter + 0);
g.drawString("12", xcenter - 10, ycenter - 130);
g.drawString("6", xcenter - 10, ycenter + 145);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int xhour, yhour, xminute, yminute, xsecond, ysecond, second, minute, hour;
drawStructure(g);
currentDate = new Date();
formatter.applyPattern("s");
second = Integer.parseInt(formatter.format(currentDate));
formatter.applyPattern("m");
minute = Integer.parseInt(formatter.format(currentDate));
formatter.applyPattern("h");
hour = Integer.parseInt(formatter.format(currentDate));
xsecond = (int) (Math.cos(second * 3.14f / 30 - 3.14f / 2) * 120 + xcenter);
ysecond = (int) (Math.sin(second * 3.14f / 30 - 3.14f / 2) * 120 + ycenter);
xminute = (int) (Math.cos(minute * 3.14f / 30 - 3.14f / 2) * 100 + xcenter);
yminute = (int) (Math.sin(minute * 3.14f / 30 - 3.14f / 2) * 100 + ycenter);
xhour = (int) (Math.cos((hour * 30 + minute / 2) * 3.14f / 180 - 3.14f / 2) * 80 + xcenter);
yhour = (int) (Math.sin((hour * 30 + minute / 2) * 3.14f / 180 - 3.14f / 2) * 80 + ycenter);
g.drawLine(xcenter, ycenter, xsecond, ysecond);
g.drawLine(xcenter, ycenter - 1, xminute, yminute);
g.drawLine(xcenter - 1, ycenter, xminute, yminute);
g.drawLine(xcenter, ycenter - 1, xhour, yhour);
g.drawLine(xcenter - 1, ycenter, xhour, yhour);
lastxs = xsecond;
lastys = ysecond;
lastxm = xminute;
lastym = yminute;
lastxh = xhour;
lastyh = yhour;
}
public void start() {
t.start();
}
public void stop() {
t.stop();
}
public static void main(String args[]) {
EventQueue.invokeLater(() -> {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0, 0, 400, 400);
Clock clock = new Clock();
frame.getContentPane().add(clock);
frame.setVisible(true);
clock.start();
});
}
}

Related

My fractal isn't printing properly, when I use the right values, it doesn't print at all

The fractal is called Vicsek fractal .When I set midpoint's x and y values to = firstDot's x and y values / 3, i get the fractal, but my fractal is very small, and off to the side. However, when I set it to equal firstDot's values * 3/2, what is suppose to be, only the square prints, and not the fractal.
package fractals;
import java.awt.Color;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
/**
*
* #author Joshua
*/
public class SquarePanel extends JPanel {
static final int[] xPoints = new int[]{270, 270, 810, 810};//Square x coordiantes
static final int[] yPoints = new int[]{92, 632, 632, 92};//Square y coordinates
int firstDotx = 270 + (int) (Math.random() * ((810 - 270) + 1));
int firstDoty = 92 + (int) (Math.random() * ((632 - 92) + 1));
public final static int iterations = 100000;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.black);
g2.drawPolygon(xPoints, yPoints, 4);
g2.drawRect(firstDotx, firstDoty, 0, 0);
for (int i = 0; i <= iterations; i++) {
int midpointX;
int midpointY;
int Vertex = (int) (Math.random() * 5 + 1);
switch (Vertex) {
case 1: //top left corner
g2.setColor(Color.blue);
midpointX = (firstDotx + 270) / 3;
midpointY = (firstDoty + 92) / 3;
g2.drawRect(midpointX, midpointY, 0, 0);
firstDotx = midpointX;
firstDoty = midpointY;
break;
case 2://bottom left
g2.setColor(Color.blue);
midpointX = (firstDotx + 270) / 3;
midpointY = (firstDoty + 632) / 3;
g2.drawRect(midpointX, midpointY, 0, 0);
firstDotx = midpointX;
firstDoty = midpointY;
break;
case 3://bottom right
g2.setColor(Color.blue);
midpointX = (firstDotx + 810) / 3;
midpointY = (firstDoty + 632) / 3;
g2.drawRect(midpointX, midpointY, 0, 0);
firstDotx = midpointX;
firstDoty = midpointY;
break;
case 4://bottom left
g2.setColor(Color.blue);
midpointX = (firstDotx + 810) / 3;
midpointY = (firstDoty + 92) / 3;
g2.drawRect(midpointX, midpointY, 0, 0);
firstDotx = midpointX;
firstDoty = midpointY;
break;
case 5:
g2.setColor(Color.red);
midpointX = (firstDotx + 540) / 3;
midpointY = (firstDoty + 384) / 3;
g2.drawRect(midpointX, midpointY, 0, 0);
firstDotx = midpointX;
firstDoty = midpointY;
break;
default:
break;
}
}
}
}
This is the class file for the Frame, im planning to add a GUI, with buttons, but I havn't gotten there yet.
package fractals;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
/**
*
* #author Joshua
*/
public class SqaureFrame {
public static void main(String[] args) {
JFrame Sframe = new JFrame("Vicsek Fractal");
Sframe.setSize(1080, 768);
Sframe.setLocation(300, 200);
Sframe.setDefaultCloseOperation(EXIT_ON_CLOSE);
SquarePanel Vicsek = new SquarePanel();
JButton Square = new JButton("Click for the Vicsek Fractal");
Sframe.add(Vicsek);
Sframe.setVisible(true);
}
}
Well thanks to everyone who looked at it, but I managed to solve it. I noticed that the size of my fractal was the same size as a quarter of the square, so I took the coordinates of each of the vertices in the square (the "+270" for example) and doubled them. My fractal now prints correctly.
For instance:
midpointY = (firstDoty + 92*2) / 3

How to fix the clock from flickering?

I am currently making an analog clock in java using AWT Package and Swing. But the digital clock overlay is currently flickering every once in a while and I'd like to fix that.
I've read about implementing double buffered in conjunction with repaint() but I am stuck on how to implement it.
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
public class Clock2d extends Applet {
GregorianCalendar cal;
Timer clockTimer = new Timer();
TimeZone clockTimeZone = TimeZone.getDefault();
public Clock2d() {
clockTimer.schedule(new TickTimerTask(), 0, 1000);
}
#Override
public void init() {
}
public void paint(Graphics g) {
g.setColor(Color.BLUE);
g.fillOval(40, 40, 220, 220);
g.setColor(Color.WHITE);
g.fillOval(50, 50, 200, 200);
double second = cal.get(Calendar.SECOND);
double minute = cal.get(Calendar.MINUTE);
double hours = cal.get(Calendar.HOUR);
for (int i = 0; i < 60; i++) {
int length = 90;
double rad = (i * 6) * (Math.PI) / 180;
if (i % 5 == 0) {
length = 82;
g.setColor(Color.BLUE);
} else {
g.setColor(Color.GRAY);
}
int x = 150 + (int) (95 * Math.cos(rad - (Math.PI / 2)));
int y = 150 + (int) (95 * Math.sin(rad - (Math.PI / 2)));
int x1 = 150 + (int) (length * Math.cos(rad - (Math.PI / 2)));
int y1 = 150 + (int) (length * Math.sin(rad - (Math.PI / 2)));
g.drawLine(x, y, x1, y1);
}
drawHands(g, second, minute, hours);
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
g.setColor(Color.BLUE);
g.setFont(new Font("Tahoma", Font.BOLD, 16));
g.drawString(sdf.format(cal.getTime()), 120, 20);
g.setFont(new Font("Arial", Font.BOLD, 10));
}
public void drawHands(Graphics g, double second, double minute, double hours) {
double rSecond = (second * 6) * (Math.PI) / 180;
double rMinute = ((minute + (second / 60)) * 6) * (Math.PI) / 180;
double rHours = ((hours + (minute / 60)) * 30) * (Math.PI) / 180;
g.setColor(Color.RED);
g.drawLine(150, 150, 150 + (int) (100 * Math.cos(rSecond - (Math.PI / 2))), 150 + (int) (100 * Math.sin(rSecond - (Math.PI / 2))));
g.setColor(Color.BLACK);
g.drawLine(150, 150, 150 + (int) (70 * Math.cos(rMinute - (Math.PI / 2))), 150 + (int) (70 * Math.sin((rMinute - (Math.PI / 2)))));
g.drawLine(150, 150, 150 + (int) (50 * Math.cos(rHours - (Math.PI / 2))), 150 + (int) (50 * Math.sin(rHours - (Math.PI / 2))));
}
class TickTimerTask extends TimerTask {
#Override
public void run() {
cal = (GregorianCalendar) GregorianCalendar.getInstance(clockTimeZone);
repaint();
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Clock 2D");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(330, 330));
Clock2d clock2d = new Clock2d();
clock2d.setPreferredSize(new Dimension(320, 320));
clock2d.init();
frame.setLayout(new BorderLayout());
frame.getContentPane().add(clock2d, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
The code work exactly as intended aside from the occasional flickering of the Numbered Digital clock.
public class Clock2d extends Applet A java.awt.Applet is not only deprecated, but also not double buffered by default. Change that to extend a JPanel (which is).
Then change public void paint(Graphics g) { to public void paintComponent(Graphics g) { super.paintComponent(g); to respect the paint chain.
class TickTimerTask extends TimerTask use a javax.swing.Timer instead. It runs on the Event Dispatch Thread, and any calls to the GUI should be made on the EDT.
Here are those three points, expressed in the code. Do you see the 'flickering' artifacts in this version?
import java.awt.*;
import java.awt.event.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import javax.swing.*;
public class Clock2d extends JPanel {
TimeZone clockTimeZone = TimeZone.getDefault();
GregorianCalendar cal =
(GregorianCalendar) GregorianCalendar.getInstance(clockTimeZone);
ActionListener repaintListener = (ActionEvent e) -> {
cal = (GregorianCalendar) GregorianCalendar.getInstance(clockTimeZone);
repaint();
};
Timer clockTimer = new Timer(100, repaintListener);
public Clock2d() {
clockTimer.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillOval(40, 40, 220, 220);
g.setColor(Color.WHITE);
g.fillOval(50, 50, 200, 200);
double second = cal.get(Calendar.SECOND);
double minute = cal.get(Calendar.MINUTE);
double hours = cal.get(Calendar.HOUR);
for (int i = 0; i < 60; i++) {
int length = 90;
double rad = (i * 6) * (Math.PI) / 180;
if (i % 5 == 0) {
length = 82;
g.setColor(Color.BLUE);
} else {
g.setColor(Color.GRAY);
}
int x = 150 + (int) (95 * Math.cos(rad - (Math.PI / 2)));
int y = 150 + (int) (95 * Math.sin(rad - (Math.PI / 2)));
int x1 = 150 + (int) (length * Math.cos(rad - (Math.PI / 2)));
int y1 = 150 + (int) (length * Math.sin(rad - (Math.PI / 2)));
g.drawLine(x, y, x1, y1);
}
drawHands(g, second, minute, hours);
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
g.setColor(Color.BLUE);
g.setFont(new Font("Tahoma", Font.BOLD, 16));
g.drawString(sdf.format(cal.getTime()), 120, 20);
g.setFont(new Font("Arial", Font.BOLD, 10));
}
public void drawHands(Graphics g, double second, double minute, double hours) {
double rSecond = (second * 6) * (Math.PI) / 180;
double rMinute = ((minute + (second / 60)) * 6) * (Math.PI) / 180;
double rHours = ((hours + (minute / 60)) * 30) * (Math.PI) / 180;
g.setColor(Color.RED);
g.drawLine(150, 150, 150 + (int) (100 * Math.cos(rSecond - (Math.PI / 2))), 150 + (int) (100 * Math.sin(rSecond - (Math.PI / 2))));
g.setColor(Color.BLACK);
g.drawLine(150, 150, 150 + (int) (70 * Math.cos(rMinute - (Math.PI / 2))), 150 + (int) (70 * Math.sin((rMinute - (Math.PI / 2)))));
g.drawLine(150, 150, 150 + (int) (50 * Math.cos(rHours - (Math.PI / 2))), 150 + (int) (50 * Math.sin(rHours - (Math.PI / 2))));
}
public static void main(String[] args) {
// Swing / AWT GUIs should be created & changed on the EDT ..
Runnable r = () -> {
JFrame frame = new JFrame("Clock 2D");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(330, 330));
Clock2d clock2d = new Clock2d();
clock2d.setPreferredSize(new Dimension(320, 320));
frame.setLayout(new BorderLayout());
frame.getContentPane().add(clock2d, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
};
// .. this is how we ensure that Runnable is on the EDT.
SwingUtilities.invokeLater(r);
}
}
Further tip re fonts:
g.setFont(new Font("Arial", Font.BOLD, 10));
Given the paint method is called repeatedly, it would be best to establish the fonts (both of them) when the class is constructed and store them a attributes of the class (which can be referenced in the methods).
But better to use logical fonts instead of something like 'Arial', like this:
g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 10));
Not only does that provide compile time checking, but it adapts across OS platforms. For example, the SANS_SERIF font would result in Arial on Windows and probably most *nix boxes, but on OS X the default SANS_SERIF (undecorated) font is Helvetica.
The other font, Tahoma, is more problematic. Again it's likely to be present on many Windows boxes, but it might be best to either test for it and have a list of backups, or supply the font with the clock app. (assuming you have distribution rights).

How can I clear/reset the canvas with a counter or countdown in Processing?

I would like to know how can I set a reset loop:
While the draw() is going on I would like to clear the canvas so I can start to draw on a clean canvas again and again.
(I don't want to use keyPressed() or mousePressed() it has to be automatic)
import ddf.minim.*;
Minim minim;
AudioInput in;
void setup() {
minim = new Minim(this);
minim.debugOn ();
in = minim.getLineIn(Minim.MONO, 100);
fullScreen();
background(255, 60, 80);
}
void draw() {
float soundlevel;
float distance_top = random(100);
int t;
int interval = 10;
String time = "010";
soundlevel = in.mix.get(0);
stroke(255, random(90, 255));
line(0, distance_top + soundlevel * 4000, width, distance_top + soundlevel * 1000);
line(0, distance_top + soundlevel * 1000, width, distance_top + soundlevel * 4000);
t = interval-int(millis()/100);
time = nf(t, 3);
if (t == 0) {
redraw();
interval = interval +10;
}
}
Thank you for your help in advice!
You can simply clear the background again, for example when you press a key:
void keyPressed(){
background(255, 60, 80);
}
You can do the same on some other event (amount of time, loudness, etc.)
Here's an example based on your code that clears the background every 3 seconds:
import ddf.minim.*;
Minim minim;
AudioInput in;
//3s as millis
int interval = 3 * 1000;
int time;
void setup() {
fullScreen();
background(255, 60, 80);
time = millis();
minim = new Minim(this);
//minim.debugOn ();
in = minim.getLineIn(Minim.MONO, 100);
}
void draw() {
float soundlevel;
float distance_top = random(100);
soundlevel = in.mix.get(0);
stroke(255, random(90, 255));
line(0, distance_top + soundlevel * 4000, width, distance_top + soundlevel * 1000);
line(0, distance_top + soundlevel * 1000, width, distance_top + soundlevel * 4000);
if(millis() - time >= interval){
// clear background
background(255, 60, 80);
// reset time for next interval
time = millis();
// debug
println("=========================> tick");
}
}
For more info on millis() for a delay see this answer
Another option is to do the calculation frame based using frameCount.
For example if the sketch's frameRate is about 60 fps and you want to clear roughly every 3 seconds you can check if the multiples of 180 (3 * 60) frames passed in tandem with the modulo(%) operator
import ddf.minim.*;
Minim minim;
AudioInput in;
void setup() {
//fullScreen();
size(300,300);
background(255, 60, 80);
minim = new Minim(this);
//minim.debugOn ();
in = minim.getLineIn(Minim.MONO, 100);
}
void draw() {
float soundlevel;
float distance_top = random(100);
soundlevel = in.mix.get(0);
stroke(255, random(90, 255));
line(0, distance_top + soundlevel * 4000, width, distance_top + soundlevel * 1000);
line(0, distance_top + soundlevel * 1000, width, distance_top + soundlevel * 4000);
if(frameCount % (3 * 60) == 0){
// clear background
background(255, 60, 80);
// debug
println("=========================> tick");
}
}

PieChart in java not showing

My piechart in java isn't showing, for my class we are to make a piechart using graphics and the values are user-input based. even after trying to input any values, my piechart would not show up at all.
What am i doing wrong?
My code:
package ass15;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.HeadlessException;
import javax.swing.JFrame;
public class PieChart extends JFrame {
private int iNorth, iSouth, iEast, iWest, iMidWest;
public PieChart(int North, int South, int East, int West, int MidWest) throws HeadlessException {
super("Assignment 15");
this.iNorth = North;
this.iSouth = South;
this.iEast = East;
this.iWest = West;
this.iMidWest = MidWest;
}
public void Paint(Graphics g) {
//Integer to percent
double dNorth,dSouth,dEast,dWest,dMidWest, total;
dNorth = 0.00 + iNorth;
dSouth = 0.00 + iSouth;
dEast = 0.00 + iEast;
dWest = 0.00 + iWest;
dMidWest = 0.00 + iMidWest;
total = dNorth + dSouth + dEast + dWest + dMidWest;
//initial arc
int startAngle = 0;
double curValue = 0.00;
startAngle = (int) (curValue * 360/total);
int arcAngle = (int) (dNorth * 360/total);
g.setColor(Color.red);
g.fillArc(50, 50, 100, 100, startAngle, arcAngle);
//new arc
curValue += dNorth;
startAngle = (int) (curValue * 360/total);
arcAngle = (int) (dSouth * 360/total);
g.setColor(Color.green);
g.fillArc(50, 50, 50, 50, startAngle, arcAngle);
//new arc
curValue += dSouth;
startAngle = (int) (curValue * 360/total);
arcAngle = (int) (dEast * 360/total);
g.setColor(Color.blue);
g.fillArc(50, 50, 50, 50, startAngle, arcAngle);
//new arc
curValue += dEast;
startAngle = (int) (curValue * 360/total);
arcAngle = (int) (dWest * 360/total);
g.setColor(Color.magenta);
g.fillArc(50, 50, 50, 50, startAngle, arcAngle);
//new arc
curValue += dWest;
startAngle = (int) (curValue * 360/total);
arcAngle = (int) (dMidWest * 360/total);
g.setColor(Color.yellow);
g.fillArc(50, 50, 50, 50, startAngle, arcAngle);
//background circle
g.setColor( Color.black );
g.drawArc( 50, 50, 50, 50, 0, 360 );
}
}
and my main is:
package ass15;
import java.util.StringTokenizer;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class TestPieChart {
public static void main(String[] args) {
int north,south,east,west,midwest;
String token;
String in = "";
in = JOptionPane.showInputDialog("Input sales for regions");
StringTokenizer stk = new StringTokenizer(in, ",");
token = stk.nextToken().trim();
north = Integer.parseInt(token);
token = stk.nextToken().trim();
south = Integer.parseInt(token);
token = stk.nextToken().trim();
east = Integer.parseInt(token);
token = stk.nextToken().trim();
west = Integer.parseInt(token);
token = stk.nextToken().trim();
midwest = Integer.parseInt(token);
PieChart pi = new PieChart(north,south,east,west,midwest);
pi.setVisible(true);
pi.setSize(500, 500);
}
}
It was a stupid mistake...
ANSWER:
the method
Paint(Graphics g)
should be
paint(Graphics g)
did not realize that until i played with the code.

Why does the clock flicker?

The following code is an animation of a clock.
What changes would have to be made in the program to make it not flicker?
Why does the field initiation have to take place in the addNotify() function for the hands to be displayed?
You can copy all of it into one .java file and it should work (flicker ;) ).
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class ac extends Frame implements Runnable {
// for double buffering
Graphics og;
Image oi;
Thread t = null;
int width, height;
int timeH, timeM, timeS, radius = 50, lenH, lenM, lenS,
lenIn, cx, cy, x1, y1, x2, y2;
private boolean timeToQuit;
ac() {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
stopRunning();
dispose();
}
});
setMinimumSize(new Dimension(300, 300));
EventQueue.invokeLater(new Runnable() {
public void run() {
setVisible(true);
}
});
}
public void addNotify() {
super.addNotify();
width = getBounds().width;
height = getBounds().height;
setSize(width, height);
lenH = 5 * radius / 10;
lenM = 6 * radius / 10;
lenS = 7 * radius / 10;
lenIn = 8 * radius / 10;
cx = width / 2;
cy = height / 2;
// for double buffering
oi = createImage(width, height);
og = oi.getGraphics();
}
public static void main(String [] args) {
ac clock = new ac();
clock.start();
}
public void start() {
if (t == null) {
t = new Thread(this);
t.start();
}
}
public void stopRunning() {
timeToQuit = true;
}
public void run() {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY - 1);
do {
repaint();
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
}
}
while (!timeToQuit);
System.out.println("Quitting");
}
public void paint(Graphics g) {
og.setColor(new Color(170, 170, 170));
og.fillRect(0, 0, width, height);
Calendar cal = new GregorianCalendar();
timeH = cal.get(Calendar.HOUR);
timeM = cal.get(Calendar.MINUTE);
timeS = cal.get(Calendar.SECOND);
if (timeH >= 12)
timeH -= 12;
for (int i = 1 ; i < 13 ; i++) {
og.setColor(new Color(20, 20, 20));
x2 = (int) (cx + radius * Math.sin(i * 2 * 3.14159f / 12));
y2 = (int) (cy - radius * Math.cos(i * 2 * 3.14159f / 12));
if (i % 3 != 0) {
x1 = (int) (cx + 0.9f * radius * Math.sin(i * 2 * 3.14159f / 12));
y1 = (int) (cy - 0.9f * radius * Math.cos(i * 2 * 3.14159f / 12));
}
else {
x1 = (int) (cx + 0.8f * radius * Math.sin(i * 2 * 3.14159f / 12));
y1 = (int) (cy - 0.8f * radius * Math.cos(i * 2 * 3.14159f / 12));
}
og.drawLine(x1, y1, x2, y2);
og.setColor(new Color(230, 230, 230));
og.drawLine(x1 - 1, y1 - 1, x2 - 1, y2 - 1);
}
og.setColor(new Color(20, 20, 20));
x2 = (int) (cx + lenH * Math.sin((timeH + timeM / 60.0f + timeS / 3600.0f)
* 2 * 3.14159f / 12));
y2 = (int) (cy - lenH * Math.cos((timeH + timeM / 60.0f + timeS / 3600.0f)
* 2 * 3.14159f / 12));
og.drawLine(cx, cy, x2, y2);
og.setColor(Color.red);
og.drawLine(cx - 1, cy - 1, x2 - 1, y2 - 1);
og.setColor(new Color(20, 20, 20));
x2 = (int) (cx + lenM * Math.sin((timeM + timeS / 60.0f) * 2 * 3.14159f
/ 60));
y2 = (int) (cy - lenM * Math.cos((timeM + timeS / 60.0f) * 2 * 3.14159f
/ 60));
og.drawLine(cx, cy, x2, y2);
og.setColor(Color.green);
og.drawLine(cx - 1, cy - 1, x2 - 1, y2 - 1);
og.setColor(new Color(20, 20, 20));
x2 = (int) (cx + lenS * Math.sin(timeS * 2 * 3.14159f / 60));
y2 = (int) (cy - lenS * Math.cos(timeS * 2 * 3.14159f / 60));
og.drawLine(cx, cy, x2, y2);
og.setColor(Color.blue);
og.drawLine(cx - 1, cy - 1, x2 - 1, y2 - 1);
og.setColor(new Color(20, 20, 20));
og.drawOval((width - 2 * radius) / 2, (height - 2 * radius) / 2,
2 * radius, 2 * radius);
og.setColor(new Color(230, 230, 230));
og.drawOval((width - 2 * radius) / 2 - 1, (height - 2 * radius) / 2 - 1,
2 * radius, 2 * radius);
g.drawImage(oi, 0, 0, this);
}
}
This uses awt which is old and it paints on to the main Frame - not the best way to make a swing UI. You can try this :
make the timer - sleep amount to less or more, try 300 or 800
use a Panel to draw on, add the panel to the frame
use swing (use a JComponent, it double buffers automatically, and a JFrame
For 2 and 3 you can keep original class to make Frame/JFrame and a new class for the java.awt.Panel or javax.swing.JComponent which is added to the former.
Does not flicker on my mac system, so i think its an OS + times its refreshed issue. Meaning suggestion 1 might work - try that first. Talking about line of code :
Thread.sleep(800);
Believe it or not, the problem was solved by adding the function:
public void update(Graphics g)
{
paint(g);
}
But the question remains, why? And why aren't the hands displayed when you initiate the class fields outside the addNotify() function?

Categories

Resources