/* detailPanel.java Paul Carlisle The detail panel is one of our main displays. This is where the user sees the Moon photograph, and gets information on the distance/rise/set times for the Sun/Moon. */ import java.awt.*; import java.applet.*; import java.net.*; import java.util.*; import JDate; import spaceTimeSelector; import infoField; import animationControl; import Moon; import textHelpPanel; public class detailPanel extends Panel implements Runnable { // messageID's public static int NONE = 0; public static int CALENDAR = 1; public static int HELP_REQUESTED = 2; private int Width; private int Height; private Image masterImage; private textHelpPanel help; private JDate currentDate; private JDate tempDate; // To hold reversion value during animation. private double Latitude = 0.733038285838; // Hard-coded for Detroit. private double Longitude = 1.44862327916; // Likewise. private Button calendarButton; private Button OKbutton; private int messageID = NONE; private boolean gotMessage = false; private moonCanvas moonImage; private spaceTimeSelector spaceTimePanel; private infoField infoPanel; private animationControl animationPanel; private Button Reset; private Button Info; private GridBagLayout mainLayout; private GridBagConstraints mainConstraints; private Moon moon; // Animation controls. private boolean animate = false; private static long normalDelay = 1000; // Milliseconds. private static double normalIncrement = 0.0000115740740741; // 1 second, as fraction of 24 hours. private static long animationDelay = 333; // Milliseconds. 3 frames per second. private static double animationIncrement = 0.5; // 12 hour advance between frames. private double lastRedraw = 0; // Use these strings to store the rise/set strings. Only update these // as needed. private String mr, ms, sr, ss; /********** Animation stuff **********/ public Thread thread; private double increment = normalIncrement;//0.00001157407; // 1 second. private long delay = normalDelay;//1000; // 1 second delay. public detailPanel(int width, int height, Font inputFont, Font checkFont, Font labelFont, Image masterImage, textHelpPanel helpPanel) { Width = width; Height = height; moon = new Moon(); help = helpPanel; mainLayout = new GridBagLayout(); mainConstraints = new GridBagConstraints(); setLayout(mainLayout); mainConstraints.fill = GridBagConstraints.NONE; mainConstraints.anchor = GridBagConstraints.CENTER; setFont(inputFont); setBackground(Color.lightGray); moonImage = new moonCanvas(225,225, masterImage); // Add the "Back to Calendar" button. calendarButton = new Button("Back to Calendar"); calendarButton.setBackground(Color.white); mainConstraints.gridy = 0; mainConstraints.gridheight = 1; mainConstraints.gridwidth = 2; mainConstraints.insets = new Insets(0, 0, 0, 20); mainConstraints.anchor = GridBagConstraints.CENTER; mainConstraints.fill = GridBagConstraints.BOTH; mainLayout.setConstraints(calendarButton, mainConstraints); add(calendarButton); // Add the image panel. mainConstraints.gridx = 0; mainConstraints.gridy = 1; mainConstraints.gridheight = 7; mainConstraints.gridwidth = 2; mainConstraints.insets = new Insets(10, 0, 4, 20); mainLayout.setConstraints(moonImage, mainConstraints); add(moonImage); // Add the animation control. animationPanel = new animationControl(inputFont); mainConstraints.gridx = 0; mainConstraints.gridy = 8; mainConstraints.gridheight = 1; mainConstraints.gridwidth = 2; mainConstraints.insets = new Insets(0, 0, 4, 20); mainConstraints.anchor = GridBagConstraints.CENTER; mainLayout.setConstraints(animationPanel, mainConstraints); add(animationPanel); // Add the information button. Info = new Button("Information"); Info.setBackground(Color.white); Info.setFont(checkFont); mainConstraints.gridx = 0; mainConstraints.gridy = 9; mainConstraints.gridheight = 1; mainConstraints.gridwidth = 1; mainConstraints.insets = new Insets(10, 0, 0, 10); mainLayout.setConstraints(Info, mainConstraints); add(Info); // Add the reset button. Reset = new Button("Reset to Current"); Reset.setBackground(Color.white); Reset.setFont(checkFont); mainConstraints.gridx = 1; mainConstraints.gridy = 9; mainConstraints.gridheight = 1; mainConstraints.gridwidth = 1; mainConstraints.insets = new Insets(10, 10, 0, 20); mainLayout.setConstraints(Reset, mainConstraints); add(Reset); // Add the date/time selector. currentDate = new JDate(); tempDate = new JDate(); //*Modify spaceTimeSelector to just take currentDate, which now includes time. spaceTimePanel = new spaceTimeSelector(Width / 2, Height, currentDate, inputFont, checkFont, labelFont, help); spaceTimePanel.setLatitude(Latitude); spaceTimePanel.setLongitude(Longitude); mainConstraints.gridx = 2; mainConstraints.gridy = 0; mainConstraints.gridheight = 4; mainConstraints.insets = new Insets(0, 10, 0, 10); mainConstraints.anchor = GridBagConstraints.CENTER; mainConstraints.fill = GridBagConstraints.BOTH; mainLayout.setConstraints(spaceTimePanel, mainConstraints); add(spaceTimePanel); // Add the information display. infoPanel = new infoField(checkFont, help); // Really dumb: Java doesn;t know how to resize these fields. If the // size starts out too small, large entries are forever truncated. // So we force them, here, to be large enough to handle whatever // we may need. infoPanel.reset("WWWWWWWWWWWWWWWWWWWWWWW", "WWWWWWWW", 888888, "WWWWWWWW", "WWWWWWWW", 888888888, "WWWWWWWW", "WWWWWWWW"); mainConstraints.gridx = 2; mainConstraints.gridy = 4; mainConstraints.gridheight = 7; mainConstraints.insets = new Insets(4, 10, 0, 10); mainConstraints.anchor = GridBagConstraints.NORTH; mainConstraints.fill = GridBagConstraints.NONE; mainLayout.setConstraints(infoPanel, mainConstraints); add(infoPanel); // Add a pad across the bottom, so browser doesn't clip off display. Panel padPanel = new Panel(); mainConstraints.gridx = 0; mainConstraints.gridy = 12; mainConstraints.gridheight = 1; mainConstraints.gridwidth = 2; mainConstraints.insets = new Insets(1, 0, 0, 0); mainConstraints.anchor = GridBagConstraints.NORTH; mainConstraints.fill = GridBagConstraints.NONE; mainLayout.setConstraints(padPanel, mainConstraints); add(padPanel); } public void destroy() { if (thread != null) thread.stop(); } public JDate getDate() { return currentDate; } // Tell user whether we generated a message or not. public boolean getMessage() { boolean temp = gotMessage; gotMessage = false; return temp; } public int getMessageID() { return messageID; } public boolean handleEvent(Event e) { boolean result = true; if ( (e.id != Event.ACTION_EVENT) && (e.id != Event.MOUSE_DOWN) ) return true; if (e.target == calendarButton) { messageID = CALENDAR; gotMessage = true; result = false; animate = false; lastRedraw = 0; increment = normalIncrement; delay = normalDelay; currentDate = spaceTimePanel.getDate(); } else if (e.target == Reset) { currentDate.setToCurrent(); spaceTimePanel.setDate(currentDate); spaceTimePanel.setLatitude(0.733038285838); // Back to Detroit. spaceTimePanel.setLongitude(1.44862327916); Latitude = 0.733038285838; Longitude = 1.44862327916; lastRedraw = 0; } else if (e.target == Info) { gotMessage = true; result = false; messageID = HELP_REQUESTED; help.getHelp("DetailInfo"); lastRedraw = 0; } else if (spaceTimePanel.getMessage()) { if (spaceTimePanel.getMessageID() == spaceTimeSelector.DATE_SELECTED) { currentDate = spaceTimePanel.getDate(); Latitude = spaceTimePanel.getLatitude(); Longitude = spaceTimePanel.getLongitude(); redraw(true); gotMessage = false; result = true; } else if (spaceTimePanel.getMessageID() == spaceTimeSelector.HELP_REQUESTED) { gotMessage = true; result = false; messageID = HELP_REQUESTED; } lastRedraw = 0; } else if (animationPanel.getMessage()) { if (animationPanel.getMessageID() == animationControl.ANIMATE) { // If we're currently animating... if (animate) currentDate.setJD(tempDate.getJD()); // If we're about to start animating... if (!animate) tempDate.setJD(currentDate.getJD()); animate = !animate; } else if (animationPanel.getMessageID() == animationControl.REVERSE) { if ( (animationPanel.getForward()) && (animationIncrement < 0) ) animationIncrement = -animationIncrement; if ( (!animationPanel.getForward()) && (animationIncrement >= 0) ) animationIncrement = - animationIncrement; } } else if (infoPanel.getMessage()) { if (infoPanel.getMessageID() == infoField.HELP_REQUESTED) { gotMessage = true; result = false; messageID = HELP_REQUESTED; } } return result; } public void redraw(boolean all) { moon.setDate(currentDate); moon.position(); double phase = moon.phase(); double pa = moon.pAng(); moonImage.redraw(phase, pa); // No point in doing this lengthy calculation too often. // We settle for once each hour. if (Math.abs(Math.round(currentDate.getJD()) - lastRedraw) >= 1.0) { moon.RiseSet(Latitude, Longitude); lastRedraw = Math.round(currentDate.getJD()); if (moon.MoonCircumpolar) { mr = " --:-- --"; ms = mr; } else { mr = (moon.moonRise()).getHMString(); ms = (moon.moonSet()).getHMString(); } if (moon.SunCircumpolar) { sr = " --:-- --"; ss = sr; } else { sr = (moon.sunRise()).getHMString(); ss = (moon.sunSet()).getHMString(); } } String dt = currentDate.getDateString(); String tm = currentDate.getHMString(); infoPanel.reset(dt, tm, moon.moonDistance(), mr, ms, moon.sunDistance(), sr, ss); if (all) { spaceTimePanel.setDate(currentDate); } } public void run() { double startTime = currentDate.getJD(); try { while (true) { long start = System.currentTimeMillis(); if (animate) { redraw(false); delay = animationDelay; increment = animationIncrement; } else if (!animate) { // If less than a minute has passed, don't update // information displays. if ( (Math.abs(currentDate.getJD() - startTime) ) < 0.00069444444444 ) redraw(false); else { redraw(true); startTime = currentDate.getJD(); } delay = normalDelay; increment = normalIncrement; } // Update the time (and date). If the allowable range is exceeded, // just run in place until the usr changes back to an allowed range. currentDate.addFrac(increment); if ( (currentDate.getJD() >= 3182029.5) || (currentDate.getJD() <= 260788.5) ) currentDate.addFrac(-increment); long sleep = delay - (System.currentTimeMillis() - start); if (sleep > 0) Thread.sleep(sleep); } } catch (InterruptedException e) { System.out.println("Interrupted Exception"); } } public void setControls() { animationPanel.setControls(true, false); animate = false; increment = 0.0000115740740741; delay = 1000; normalDelay = 1000; normalIncrement = 0.0000115740740741; animationDelay = 333; animationIncrement = 0.5; } public void setDate(JDate date) { currentDate.setJD(date.getJD()); tempDate.setJD(date.getJD()); spaceTimePanel.setDate(currentDate); } public void start() { if (thread != null) thread.resume(); } public void stop() { if (thread != null) thread.stop(); } }