Not sure why this didn't work properly.
So I programmed out a clock for practice/educational value for myself, and I got it near the end and encountered a problem. My program has 2 sets of class fields and a few temporary ones. The first set of class fields are text fields (hours, mins, secs) and the second set are Integers (h, m, s) (not int's ... Integers). I have two methods (setText and setTime) that convert between these two sets. setText sets the text fields to whatever time is stored in the Integers, and setTime sets the Integer values to whatever is stored in the text fields (assuming they're valid ints, of course).
The code that was behaving strangely is shown below between the large comment lines. I needed some way to update the time, so I first tried changing the Integer values and then calling setText() ... but it didn't work. So I then tried setting the text fields and calling setTime() and that DID work. The end result of both should be the same, and yet it wasn't. I was wondering why not? Can anyone help/explain?
I figure it has something to do with Integers and mutability, but that doesn't seem likely since they're both declared at the class-level and not within a method. I did some debugging of it (added System.out.println messages) and found out that the Integer value was changing, but then it was being reset back to what it was initially. bleh - I think I'm doing a bad job of explaining it. Anyway - here's the entire code below. It works correctly currently. But I left the bit of code in that wasn't working properly - just commented out. If you uncomment those and comment the 4 lines above them, you'll hopefully see what I'm talking about.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.util.Calendar;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
// Math.sin, Math.cos, Math.tan use RADIANS .. not degrees.
// 0 rad/deg is at east and proceeds clockwise for increasing angle
publicclass myClockextends JFrameimplements ActionListener, DocumentListener
{
JTextField hours;
JTextField mins;
JTextField secs;
Calendar now;
ClockPane clock =new ClockPane();
JPanel textPane;
Integer m;double mrad;
Integer h;double hrad;
Integer s;double srad;
myClock()
{
setSize(300,360);
setResizable(false);
setTitle("Clock!");
// get starting time
now = Calendar.getInstance();
hours =new JTextField(String.valueOf(now.get(Calendar.HOUR)%12), 2);
mins =new JTextField(String.valueOf(now.get(Calendar.MINUTE)), 2);
secs =new JTextField(String.valueOf(now.get(Calendar.SECOND)), 2);
setTime();
// set the document listeners
hours.getDocument().addDocumentListener(this);
mins.getDocument().addDocumentListener(this);
secs.getDocument().addDocumentListener(this);
// create visual layout of frame
textPane = createSouthPane();
add(textPane, BorderLayout.SOUTH);
add(clock, BorderLayout.CENTER);
// start clock update timer - updates every second (1000 milliseconds)
new Timer(1000,this).start();
}
publicstaticvoid main(String[] args)
{
myClock app =new myClock();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setVisible(true);
}
class ClockPaneextends JPanel
{
publicvoid paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Dimension dim = getSize();
double midx = dim.width / 2;
double midy = dim.height / 2;
Ellipse2D e =new Ellipse2D.Double(midx - 140, midy - 140, 280, 280);
g2.draw(e);
srad = s.doubleValue() / 60 * 2 * Math.PI;
mrad = m.doubleValue() / 60 * 2 * Math.PI;
mrad = mrad + srad / 60;
hrad = h.doubleValue() / 12 * 2 * Math.PI;
hrad = hrad + mrad / 12 + srad / 720;
srad = srad - Math.PI / 2;
mrad = mrad - Math.PI / 2;
hrad = hrad - Math.PI / 2;
Line2D shand =new Line2D.Double(midx, midy, midx + (e.getWidth() / 2 - 10) * Math.cos(srad), midy + (e.getHeight() / 2 - 10) * Math.sin(srad));
Line2D mhand =new Line2D.Double(midx, midy, midx + (e.getWidth() / 2 - 10) * Math.cos(mrad), midy + (e.getHeight() / 2 - 10) * Math.sin(mrad));
Line2D hhand =new Line2D.Double(midx, midy, midx + (e.getWidth() / 2 - 40) * Math.cos(hrad), midy + (e.getHeight() / 2 - 40) * Math.sin(hrad));
g2.setPaint(Color.BLACK);
g2.draw(hhand);
g2.draw(mhand);
g2.setPaint(Color.RED);
g2.draw(shand);
}
}
private JPanel createSouthPane()
{
JPanel p =new JPanel();
p.add(new JLabel("Hours:"));
p.add(hours);
p.add(new JLabel("Mins:"));
p.add(mins);
p.add(new JLabel("Secs:"));
p.add(secs);
return p;
}
// sets the Integer values of h, m, s to what the text fields read
privatevoid setTime()
{
h =new Integer(hours.getText());
m =new Integer(mins.getText());
s =new Integer(secs.getText());
}
// sets the text fields hours, mins, secs to what the Integer values contain
privatevoid setText()
{
hours.setText(String.valueOf(h.intValue()));
mins.setText(String.valueOf(m.intValue()));
secs.setText(String.valueOf(s.intValue()));
}
// action listener for Timer
publicvoid actionPerformed(ActionEvent e)
{
int ss = s.intValue();
int mm = m.intValue();
int hh = h.intValue();
ss++;
mm = mm + ss / 60;
hh = hh + mm / 60;
ss = ss % 60;
mm = mm % 60;
hh = hh % 12;
/////////////////////////////////////////////////////////////////////////////////////////////////
hours.setText(String.valueOf(hh));
mins.setText(String.valueOf(mm));
secs.setText(String.valueOf(ss));
setTime();
//s = new Integer(ss);
//m = new Integer(mm);
//h = new Integer(hh);
//setText();
/////////////////////////////////////////////////////////////////////////////////////////////////
clock.repaint();
}
// document listener for text fields
publicvoid changedUpdate(DocumentEvent e)
{
if (mins.getText().equals("") || hours.getText().equals("") || secs.getText().equals("")) ;
else
{
setTime();
clock.repaint();
}
}
publicvoid removeUpdate(DocumentEvent e)
{
if (mins.getText().equals("") || hours.getText().equals("") || secs.getText().equals("")) ;
else
{
setTime();
clock.repaint();
}
}
publicvoid insertUpdate(DocumentEvent e)
{
if (mins.getText().equals("") || hours.getText().equals("") || secs.getText().equals("")) ;
else
{
setTime();
clock.repaint();
}
}
}

