/****************************************************************************** * 星空ウォッチング(プラネタリウム) * * by「菊池さん」 * * Copyright(C) 2001 Kikuchi-san's workshop. All rights reserved. * *****************************************************************************/ import java.applet.*; import java.awt.*; import java.util.*; import java.awt.event.*; import java.net.*; public class SkyWatching extends Applet implements SkyData { SkyStatus status; //ステータスパネル SkyControls controls; //コントロールパネル static SkyCanvas canvas; //描画キャンパス static SkyScroll scrpanel; //スクロールパネル static Calendar now; static int year,mon,day,wk,hour,min; static String week[] = {"日","月","火","水","木","金","土"}; static URL anchor = null; //アプレット入手先アンカー static Image banner; //リンク用バナー画像 static Rectangle area = new Rectangle(220, 42, 88, 31); //バナークリック領域 static AppletContext context; //アプレット入手先用コンテキスト定義 static Scrollbar vert, horz; //スクロールバー定義 static Panel innerPanel; //スクロール用画面領域 public void init() { //URLオブジェクト作成 try { anchor = new URL("http://kikuchisan.net/"); } catch (MalformedURLException e) { System.out.println("Error:" + e.getMessage()); } //アプレット入手先用コンテキスト context = getAppletContext(); //HTML文書よりパラメータの内容を受け取る。 canvas.R = Integer.parseInt(getParameter("size")); //画面サイズ canvas.R0 = canvas.R; if(getParameter("size") == null) canvas.R = 440; canvas.SHAPE = getParameter("shape"); //天球形状 if(canvas.SHAPE == null) canvas.SHAPE = "全球"; canvas.cityName = getParameter("city"); //観測地名 if(canvas.cityName == null) canvas.cityName = "横浜"; //バナー画像定義 banner = getImage(getDocumentBase(),"banner.gif"); //初期画面の日付/時刻・背景色(現在時刻)設定 now = Calendar.getInstance(); //日付取得 wk = now.get(Calendar.DAY_OF_WEEK); year = now.get(Calendar.YEAR); mon = now.get(Calendar.MONTH)+1; day = now.get(Calendar.DAY_OF_MONTH); hour = now.get(Calendar.HOUR_OF_DAY); min = now.get(Calendar.MINUTE); canvas.DATE = year+"/"+mon+"/"+day; //日付(ローカル) canvas.HOUR = (min <10)? hour+":0"+min : hour+":"+min; //時刻(ローカル) canvas.JDATE = canvas.DATE+"("+week[wk-1]+")"; //日付(現在) canvas.JHOUR = canvas.HOUR; //時刻(現在) SkyCalculate.Dn = hour/24.0 + min/1440.0; //現在時刻セット(0.xxx日) SkyCalculate.calc_SunRiseSet(0); //太陽出没時刻セット //日時テキストフィールド初期値セット status.textfield_date.setText(canvas.DATE); status.textfield_hour.setText(canvas.HOUR); //描画色設定 setForeground(new Color(0,0,0)); //スクロールパネル定義 canvas = new SkyCanvas(); innerPanel = new Panel(); innerPanel.setLayout(new BorderLayout()); //innerPanelサイズ設定 canvas.sizeX = canvas.R+canvas.offsetX*2; canvas.sizeX0 = canvas.sizeX; if(canvas.SHAPE.equals("半球")) canvas.sizeZ =canvas.R/2+canvas.offsetZ*2; else canvas.sizeZ = canvas.R+canvas.offsetZ*2; canvas.sizeZ0 = canvas.sizeZ; innerPanel.setSize(canvas.sizeX*4,canvas.sizeZ*4); //4倍の領域確保 innerPanel.add(canvas); //スクロールパネルレイアウト Panel scr = new Panel(); scr.setLayout(new BorderLayout()); scrpanel = new SkyScroll(innerPanel); vert = new Scrollbar(Scrollbar.VERTICAL, 1, 0, 1, canvas.sizeZ); horz = new Scrollbar(Scrollbar.HORIZONTAL, 1, 0, 1, canvas.sizeX); vert.setLineIncrement(50); //スクロールバーインクリメント 1→50 horz.setLineIncrement(50); //スクロールバーインクリメント 1→50 scr.add("Center", scrpanel); scr.add("East", vert); scr.add("South", horz); //全体画面レイアウト setLayout(new BorderLayout()); add("Center", scr); add("North", status = new SkyStatus(canvas)); add("South", controls = new SkyControls(canvas)); } public boolean handleEvent(Event e) { if (e.target instanceof Scrollbar) { scrpanel.transxy(horz.getValue(), vert.getValue()); return true; } return super.handleEvent(e); } public static void get_nowDate(int year,int mon, int day, int hour, int min) { year = now.get(Calendar.YEAR); mon = now.get(Calendar.MONTH)+1; day = now.get(Calendar.DAY_OF_MONTH); hour = now.get(Calendar.HOUR_OF_DAY); min = now.get(Calendar.MINUTE); canvas.DATE = year+"/"+mon+"/"+day; //日付(ローカル) canvas.HOUR = (min <10)? hour+":0"+min : hour+":"+min; //時刻(ローカル) } public void destroy() { remove(canvas); remove(status); remove(controls); } public void start() { canvas.setEnabled(true); status.setEnabled(true); controls.setEnabled(true); } public void stop() { canvas.setEnabled(false); status.setEnabled(false); controls.setEnabled(false); } public void processEvent(AWTEvent evt) { if (evt.getID() == Event.WINDOW_DESTROY) { System.exit(0); } } /* public static void main(String args[]) { Frame f = new Frame("SkyWatching"); SkyWatching watch = new SkyWatching(); watch.init(); watch.start(); f.add("Center", watch); f.show(); } */ public String getAppletInfo() { return "星空ウォッチング(プラネタリウム)\nby「菊池さん」 "; } } //end of SkyWatching /************************************************************************** * 描画キャンパス * ***************************************************************************/ class SkyCanvas extends Canvas implements Runnable { SkyData data; //観測地、星データ SkyStatus status; //ステータスパネル static int cityNo,DIR; static String EW,LNG,NS,LAT,TD,SHAPE; static int R,R0; //天球の半径 static double CNT; //日周運動カウント static String cityName; //観測地名 static int sizeX0,sizeZ0; //描画部初期画面サイズ static int sizeX,sizeZ; //描画部現画面サイズ //初期値設定 static int offsetX = 20; //描画部横両サイドのりしろ static int offsetZ = 20; //描画部縦両サイドのりしろ static int msize = 12; //表示文字のサイズ(px) static int bcol[] = new int[2]; //天球・背景色コード増減量 static int SPD = 120; //日周運動時間増分(sec) static int INV = 5; //日周運動描画間隔 static String dirH = ""; static String dirV = "北天"; //方角バー(天頂) String direction[] = {"西","北","東",""}; //方角バー(横方向) static double planetAZ,planetEL; //惑星の方位角、高度 static String DATE,HOUR; //日付・時刻(ローカル) static String JDATE,JHOUR; //日付・時刻(現在) //判定フラグ boolean bool_Star = false; //星名表示(将来はパラメータ指定に) boolean bool_Seiza = true; //星座表示(将来はパラメータ指定に) boolean bool_Planet = false; //惑星表示(将来はパラメータ指定に) static boolean bool_City = false; //観測地選択 static boolean bool_LngLat = false; //緯経度入力 static boolean bool_Move = false; //日週運動 static boolean bool_Trace = false; //航跡表示 static Thread thread_Trace = null; //航跡スレッド Image offs; //ダブルバッファリング用イメージバッファ(チラツキ防止用) Graphics grf; //イメージバッファ描画用Graphicsオブジェクト //========================================================================= // 日周運動 //========================================================================= public void init() { } public void destroy() { } public void start() { if(thread_Trace == null){ thread_Trace = new Thread(this); thread_Trace.start(); } } public void stop() { if(thread_Trace != null){ thread_Trace.stop(); thread_Trace = null; } } public void run() { //カレンダーに現時刻をセット SkyWatching.now.set(SkyCalculate.YY,SkyCalculate.MM-1,SkyCalculate.DD,SkyCalculate.HH,SkyCalculate.MI,SkyCalculate.SS); while(thread_Trace != null) { for (CNT=1; CNT<10000000; CNT++) { SkyWatching.now.add(Calendar.SECOND,SPD); //カレンダーの秒に日周運動時間増分加算 SkyWatching.get_nowDate(SkyWatching.year,SkyWatching.mon,SkyWatching.day,SkyWatching.hour,SkyWatching.min); // System.out.println(CNT+" SPD "+SPD+"HOUR "+HOUR+"INV "+INV); if (CNT%INV ==1) repaint(); try{ Thread.sleep(80);} catch (InterruptedException e) { } } } } //========================================================================= // 描画部品定義 //========================================================================= public void set_Color(double Dn,double Sr, double Ss, int bcol[]) { // System.out.println("Dn "+Dn+" K "+SkyCalculate.K); if (Dn < Sr-0.035) { bcol[0] = 128; bcol[1] = 0; } else if (Dn < Sr-0.028) { bcol[0] = 170; bcol[1] = 64; } else if (Dn < Sr-0.021) { bcol[0] = 191; bcol[1] = 96; } else if (Dn < Sr-0.014) { bcol[0] = 212; bcol[1] = 128; } else if (Dn < Sr-0.007) { bcol[0] = 233; bcol[1] = 160; } else if (Dn < Ss-0.007) { bcol[0] = 255; bcol[1] = 192; } else if (Dn < Ss) { bcol[0] = 233; bcol[1] = 160; } else if (Dn < Ss+0.007) { bcol[0] = 212; bcol[1] = 128; } else if (Dn < Ss+0.014) { bcol[0] = 191; bcol[1] = 96; } else if (Dn < Ss+0.021) { bcol[0] = 170; bcol[1] = 64; } else { bcol[0] = 128; bcol[1] = 0; } } public void paintSky(Graphics g) { //天球 //innerPanelサイズ設定 sizeX = R+offsetX*2; if(SHAPE.equals("半球")) sizeZ = R/2+offsetZ*2; else sizeZ = R+offsetZ*2; // SkyWatching.innerPanel.setSize(sizeX,sizeZ); //画面領域クリア g.setColor(Color.white); if (sizeX < sizeX0) { g.fillRect(0,0,sizeX0,sizeZ0); } else { g.fillRect(0,0,sizeX,sizeZ); } //天球描画 set_Color(SkyCalculate.Dn,SkyCalculate.Sr,SkyCalculate.Ss,bcol); g.setColor(new Color(0,0,bcol[0])); g.fillRect(0,0,sizeX,sizeZ); g.setColor(new Color(0,0,bcol[1])); if (SHAPE.equals("半球")) g.fillArc(offsetX,offsetZ,R,R,0,180); else g.fillArc(offsetX,offsetZ,R,R,0,360); } public void paintStar(Graphics g) { //星 int ls,le,Xls,Zls,Xle,Zle; double ANG = 0; double WID = 0; double starAZ,starEL; double pol[] = new double[3]; //極座標値 double xyz[] = new double[3]; //xyz座標値 for (int i = 0; i < data.star.length; i++) { int SMs[] = new int[21]; //星の光度(大きさ) Color SCs[] = new Color[21]; //星のスペクトル(色) double Xs[] = new double[21]; //星のX座標値 double Zs[] = new double[21]; //星のZ座標値 String NMs[] = new String[21]; //星名 for (int j = 2; j < data.star[i].length; j++) { //星データ1行抽出 SkyCalculate.starData[0] = data.star[i][j][0]; SkyCalculate.starData[1] = data.star[i][j][1]; SkyCalculate.starData[2] = data.star[i][j][2]; SkyCalculate.starData[3] = data.star[i][j][3]; NMs[j-2] = data.star[i][j][4]; //星の光度、色、赤経、赤緯計算 SkyCalculate.calc_Star(); //現在時刻の方位角、高度計算 starAZ = SkyCalculate.calc_AZ(SkyCalculate.starLNG,SkyCalculate.starLAT,SkyCalculate.Theta,SkyCalculate.cityLAT); //方位角 starEL = SkyCalculate.calc_EL(SkyCalculate.starLNG,SkyCalculate.starLAT,SkyCalculate.Theta,SkyCalculate.cityLAT); //高度 //半球&東西南北の場合は地平線下はプロットしない if (SHAPE.equals("半球") && starEL < 0.0) continue; //半球&北(南)天の場合は南(北)半球はプロットしない if (DIR == 4 && SHAPE.equals("半球") && (starAZ > 90.0 && starAZ < 270.0)) continue; if (DIR == 5 && SHAPE.equals("半球") && (starAZ < 90.0 || starAZ > 270.0)) continue; //距離、方位角、高度 -> XY座標値 pol[0] = R/2.0; pol[1] = 90.0 - starAZ; pol[2] = 90.0 - starEL; //方角毎のcos、sin値による象限判定とプロット判断 double cosAZ = Math.cos(SkyCalculate.pai * starAZ); double sinAZ = Math.sin(SkyCalculate.pai * starAZ); double cosEL = Math.cos(SkyCalculate.pai * starEL); double sinEL = Math.sin(SkyCalculate.pai * starEL); if (DIR == 0) { if (cosAZ < 0.0) continue; } else if (DIR == 1) { pol[1] += 90.0; if (sinAZ < 0.0) continue; } else if (DIR == 2) { pol[1] += 180.0; if (cosAZ > 0.0) continue; } else if (DIR == 3) { pol[1] += 270.0; if (sinAZ > 0.0) continue; } else if (DIR == 4) { if (sinEL < 0.0) continue; } else if (DIR == 5) { if (sinEL < 0.0) continue; } // System.out.println(i+" "+" "+DIR+" starLNG/LAT "+Math.round(SkyCalculate.starLNG*10.0)/10.0+" "+Math.round(SkyCalculate.starLAT*10.0)/10.0+" AZ/EL "+Math.round(starAZ*10.0)/10.0+" "+Math.round(starEL*10.0)/10.0+" pol "+Math.round(pol[1]*10.0)/10.0+" "+Math.round(pol[2]*10.0)/10.0); //極座標 -> 直交座標変換 SkyCalculate.AZEL2XYZ(pol,xyz); // System.out.println("starLNG/LAT "+Math.round(SkyCalculate.starLNG*10.0)/10.0+" "+Math.round(SkyCalculate.starLAT*10.0)/10.0+" X/Y/Z "+xyz[0]+" "+xyz[1]+" "+xyz[2]); //表示する星データ(星座単位)を配列に一時記録 SMs[j-2] = SkyCalculate.SM; SCs[j-2] = SkyCalculate.SC; if (DIR == 4) { //北天のときはXY面 Xs[j-2] = xyz[0]; Zs[j-2] = xyz[1]; } else if (DIR == 5) { //南天のときはX(-Y)面 Xs[j-2] = xyz[0]; Zs[j-2] = -xyz[1]; } else { //それ以外はXZ面 Xs[j-2] = xyz[0]; Zs[j-2] = xyz[2]; } // System.out.println(j-2+" Xs "+Xs[j-2]+" Zs "+Zs[j-2]+" "+NMs[j-2]); } // for (int j = 0; j < Xs.length; j++) System.out.println(j+" Xs "+Xs[j]+" Zs "+Zs[j]+" "+NMs[j]); //星座表示 if (bool_Seiza) { //星座線 g.setColor(Color.blue); for (int k = 0; k < data.star[i][1].length; k +=2) { ls = Integer.parseInt(data.star[i][1][k]); le = Integer.parseInt(data.star[i][1][k+1]); if (Xs[ls] == 0.0 || Xs[le] == 0.0) continue; //星座線のプロット判断 Xls = (int)Math.round(Xs[ls]); Zls = (int)Math.round(Zs[ls]); Xle = (int)Math.round(Xs[le]); Zle = (int)Math.round(Zs[le]); // System.out.println(i+" "+k+" "+ls+" "+le+" Xls/Zls "+Xls+" "+Zls+" Xle/Zle "+Xle+" "+Zle); g.drawLine(Xls,-Zls,Xle,-Zle); } //星座名 g.setColor(Color.pink); ls = Integer.parseInt(data.star[i][0][1]); if (Xs[ls] != 0.0) { //星座名のプロット判断 Xls = (int)Xs[ls]+5; Zls = (int)Zs[ls]+5; g.drawString(data.star[i][0][0],Xls,-Zls); } } //星表示 for (int k = 0; k < data.star[i].length-2; k++) { //星 if (Xs[k] == 0.0) continue; //星のプロット判断 g.setColor(SCs[k]); Xls = (int)Math.round(Xs[k]); Zls = (int)Math.round(Zs[k]); g.fillOval(Xls,-Zls,SMs[k],SMs[k]); //星名 if (bool_Star && !NMs[k].equals("")) { // System.out.println(i+" "+k+" "+Xs.length+" "+NMs[k]); g.setColor(Color.lightGray); g.drawString(NMs[k],Xls,-Zls-3); } } } //end of i } //end of paintStar public void paintPlanet(Graphics g) { //惑星 int Xls,Zls; int sno; //惑星番号 int pM[] = {7,7,5,6,5,5,5,3,3,3}; Color pC[] = {new Color(255,215,0),Color.white,Color.cyan,Color.yellow,Color.red,Color.yellow,Color.yellow,Color.green,Color.magenta,Color.yellow}; String pNM[] = {"太陽","月","水星","金星","火星","木星","土星","天王星","海王星","冥王星"}; double pol[] = new double[3]; //極座標値 double xyz[] = new double[3]; //xyz座標値 for (sno = 0; sno < 10; sno++) { //現在時刻の惑星の方位角、高度計算 SkyCalculate.calc_Planet(sno); //半球&東西南北の場合は地平線下はプロットしない if (!(SHAPE.equals("半球") && planetEL < 0.0)) //半球&北(南)天の場合は南(北)半球はプロットしない if (!(DIR == 4 && SHAPE.equals("半球") && (planetAZ > 90.0 && planetAZ < 270.0))) if (!(DIR == 5 && SHAPE.equals("半球") && (planetAZ < 90.0 || planetAZ > 270.0))) { //距離、方位角、高度 -> XY座標値 pol[0] = R/2.0; pol[1] = 90.0 - planetAZ; pol[2] = 90.0 - planetEL; //方角毎のcos、sin値による象限判定とプロット判断 double cosAZ = Math.cos(SkyCalculate.pai * planetAZ); double sinAZ = Math.sin(SkyCalculate.pai * planetAZ); double cosEL = Math.cos(SkyCalculate.pai * planetEL); double sinEL = Math.sin(SkyCalculate.pai * planetEL); if (!(DIR == 0 && cosAZ < 0.0)) if (!(DIR == 1 && sinAZ < 0.0)) if (!(DIR == 2 && cosAZ > 0.0)) if (!(DIR == 3 && sinAZ > 0.0)) if (!(DIR == 4 && sinEL < 0.0)) if (!(DIR == 5 && sinEL < 0.0)) { if (DIR == 1) { pol[1] += 90.0; } if (DIR == 2) { pol[1] += 180.0; } if (DIR == 3) { pol[1] += 270.0; } //極座標 -> 直交座標変換 SkyCalculate.AZEL2XYZ(pol,xyz); if (DIR == 4) { //北天のときはXY面 Xls = (int)Math.round(xyz[0]); Zls = (int)Math.round(xyz[1]); } else if (DIR == 5) { //南天のときはX(-Y)面 Xls = (int)Math.round(xyz[0]); Zls = -(int)Math.round(xyz[1]); } else { //それ以外はXZ面 Xls = (int)Math.round(xyz[0]); Zls = (int)Math.round(xyz[2]); } g.setColor(pC[sno]); g.fillOval(Xls,-Zls,pM[sno],pM[sno]); g.setColor(new Color(50,205,50)); g.drawString(pNM[sno],Xls,-Zls-3); } } } } //end of paintPlanet public void paintBar(Graphics g) { //方角バー //方角バー表示設定 if (DIR == 0) { direction[0]="西"; direction[1]="北"; direction[2]="東"; direction[3]=dirV; } else if (DIR == 1) { direction[0]="北"; direction[1]="東"; direction[2]="南"; direction[3]=dirV; } else if (DIR == 2) { direction[0]="東"; direction[1]="南"; direction[2]="西"; direction[3]=dirV; } else if (DIR == 3) { direction[0]="南"; direction[1]="西"; direction[2]="北"; direction[3]=dirV; } else if (DIR == 4) { direction[0]="西"; direction[1]=dirH; direction[2]="東"; direction[3]="北"; } else if (DIR == 5) { direction[0]="西"; direction[1]=dirH; direction[2]="東"; direction[3]="南"; } g.setColor(Color.gray); g.drawLine(offsetX,R/2+offsetX,R+offsetX,R/2+offsetX); g.setColor(Color.red); g.drawString(direction[0],offsetX-msize,R/2+offsetZ+msize-2); g.drawString(direction[1],R/2+offsetX-msize/2,R/2+offsetZ+msize+2); g.drawString(direction[2],R+offsetX,R/2+offsetZ+msize-2); g.drawString(direction[3],R/2+offsetX-msize,offsetZ-2); } //========================================================================= // 描画 //========================================================================= public void paint(Graphics g) { //画面サイズと同サイズのオフスクリーンバッファ作成 offs = createImage(sizeX,sizeZ); //イメージクラスのグラフィックメソッド呼び出し grf = offs.getGraphics(); //ダブルバッファリングによるアニメーション表示 //方角判定 switch(DIR) { case 0: dirH = "北"; dirV = (NS.equals("N"))? "北天" : "南天"; break; case 1: dirH = "東"; dirV = (NS.equals("N"))? "北天" : "南天"; break; case 2: dirH = "南"; dirV = (NS.equals("N"))? "北天" : "南天"; break; case 3: dirH = "西"; dirV = (NS.equals("N"))? "北天" : "南天"; break; case 4: dirH = "北天"; break; case 5: dirH = "南天"; break; } //日付時刻、観測地緯経度、時差計算 SkyCalculate.calc_DateCity(); //YY年MM月DD日0時(時差I)までの経過ユリウス世紀 SkyCalculate.K = SkyCalculate.calc_K((double)SkyCalculate.DD); //本日0時から現在時刻までの経過日数(0.xxx日) SkyCalculate.Dn = SkyCalculate.HH/24.0 + SkyCalculate.MI/1440.0 + SkyCalculate.SS/86400.0; //YY年MM月DD日0時(時差I)から現在時刻までの経過ユリウス世紀 SkyCalculate.T = SkyCalculate.K + SkyCalculate.Dn/36525.0; //地方恒星時の計算 SkyCalculate.Theta = SkyCalculate.calc_Theta(SkyCalculate.cityLNG,SkyCalculate.T,SkyCalculate.Dn); //太陽出没計算 SkyCalculate.calc_SunRiseSet(0); //月出没計算 SkyCalculate.calc_MoonRiseSet(1); //月齢計算 SkyCalculate.Mage = SkyCalculate.calc_Mage(SkyCalculate.DD); //描画 paintSky(grf); paintBar(grf); grf.translate(R/2+offsetX,R/2+offsetZ); //描画原点を天球中心に移動 if (bool_Planet) paintPlanet(grf); paintStar(grf); grf.translate(-(R/2+offsetX),-(R/2+offsetZ)); //描画原点を左上に復帰 grf.setColor(Color.white); grf.drawString(JDATE+" "+JHOUR+"JST",15,20); grf.setColor(new Color(192,192,192)); grf.drawLine(15,22,145,22); grf.setColor(Color.white); grf.drawString("観測地: ",15,44); grf.setColor(Color.cyan); grf.drawString(data.city[cityNo][0],60,44); grf.setColor(Color.white); grf.drawString("・日時: "+DATE,15,56); grf.drawString("・時刻: "+HOUR,15,68); grf.drawString("・時差: "+TD,15,80); grf.drawString("・"+EW+" "+LNG,15,92); grf.drawString("・"+NS+" "+LAT,15,104); grf.drawString("方角: "+dirH,15,116); grf.drawString("倍率: "+Math.round((double)sizeX/sizeX0*10.0)/10.0,15,128); grf.drawString("日出: "+SkyCalculate.num2jifun(SkyCalculate.Sr*24.0),sizeX-75,20); grf.drawString("日没: "+SkyCalculate.num2jifun(SkyCalculate.Ss*24.0),sizeX-75,32); if (SkyCalculate.Mr != 99.0) { grf.drawString("月出: "+SkyCalculate.num2jifun(SkyCalculate.Mr*24.0),sizeX-75,44); } else { grf.drawString("月出: --:--",sizeX-75,44); } if (SkyCalculate.Ms != 99.0) { grf.drawString("月没: "+SkyCalculate.num2jifun(SkyCalculate.Ms*24.0),sizeX-75,56); } else { grf.drawString("月没: --:--",sizeX-75,56); } grf.drawString("月齢: "+SkyCalculate.Mage,sizeX-75,68); //オフスクリーン上のイメージを画面上にコピー g.drawImage(offs,0,0,this); grf.dispose(); //Graphicsオブジェクトgrfの破棄 } public void update(Graphics g) { //チラツキ防止 paint(g); } } //end of SkyCanvas /************************************************************************** * ステータスパネル * ***************************************************************************/ class SkyStatus extends Panel implements ActionListener, ItemListener { SkyData data; //観測地、星データ SkyCanvas canvas; //描画キャンパス SkyCalculate calculate; //描画キャンパス Choice choice_Direction = new Choice(); Choice choice_City = new Choice(); static Choice choice_Sign_lng; static Choice choice_Sign_lat; Button button_help = new Button("ヘルプ"); Button button_redraw = new Button("再描画"); static TextField textfield_lng = new TextField(10); static TextField textfield_lat = new TextField(10); static TextField textfield_date = new TextField(10); static TextField textfield_hour = new TextField(10); Frame window = new SkyHelp("星空ウォッチング(プラネタリウム)について"); //========================================================================= // ステータスパネル作成 //========================================================================= public SkyStatus(SkyCanvas canvas) { this.canvas = canvas; choice_Sign_lng = new Choice(); choice_Sign_lat = new Choice(); //ヘルプウインドウ設定 window.setSize(335, 255); //ウインドウサイズ window.setLocation(180, 100); //ウインドウ表示位置 //初期画面ではボタン操作不可にする choice_Sign_lng.setEnabled(false); choice_Sign_lat.setEnabled(false); textfield_lng.setEnabled(false); textfield_lat.setEnabled(false); //ステータスパネル作成 setLayout(new GridLayout(2,1)); setBackground(new Color(192,192,192)); //上段 add(new Label("観測地:",Label.RIGHT)); for (int i = 0; i < data.city.length; i++) choice_City.addItem(data.city[i][0]); add(choice_City); choice_City.addItemListener(this); //観測地初期値セット for (int i = 0; i < data.city.length; i++) { if (choice_City.getItem(i).equals(canvas.cityName)) { choice_City.select(i); canvas.cityNo = i; canvas.EW = data.city[i][1]; //東/西経 canvas.LNG = data.city[i][2]; //観測地経度 canvas.NS = data.city[i][3]; //北/南緯 canvas.LAT = data.city[i][4]; //観測地緯度 canvas.TD = data.city[i][5]; //観測地時差 //観測地経緯度テキストフィールド初期値セット textfield_lng.setText(canvas.LNG); textfield_lat.setText(canvas.LAT); break; } } add(new Label("経度:",Label.RIGHT)); choice_Sign_lng.addItem("E"); choice_Sign_lng.addItem("W"); add(choice_Sign_lng); choice_Sign_lng.addItemListener(this); add(textfield_lng); add(new Label("ローカル日時:",Label.RIGHT)); add(textfield_date); add(button_help); button_help.addActionListener(this); //下段 add(new Label("方角:",Label.RIGHT)); choice_Direction.addItem("北"); choice_Direction.addItem("東"); choice_Direction.addItem("南"); choice_Direction.addItem("西"); choice_Direction.addItem("天頂"); add(choice_Direction); choice_Direction.addItemListener(this); add(new Label("緯度:",Label.RIGHT)); choice_Sign_lat.addItem("N"); choice_Sign_lat.addItem("S"); add(choice_Sign_lat); choice_Sign_lat.addItemListener(this); add(textfield_lat); add(new Label("ローカル時刻:",Label.RIGHT)); add(textfield_hour); // button_redraw.setFont(new Font("MS ゴチック",Font.BOLD,12)); button_redraw.setBackground(new Color(0,139,139)); button_redraw.setForeground(Color.white); add(button_redraw); button_redraw.addActionListener(this); } //========================================================================= // ボタンイベント //========================================================================= public void actionPerformed(ActionEvent evt) { Object src = evt.getSource(); //イベント種類 String arg = evt.getActionCommand(); //イベント文字列 //再描画 if (src == button_redraw) { canvas.LNG = textfield_lng.getText().trim(); canvas.LAT = textfield_lat.getText().trim(); canvas.DATE = textfield_date.getText().trim(); canvas.HOUR = textfield_hour.getText().trim(); canvas.repaint(); } //ヘルプ if (src == button_help) { if (arg.equals("ヘルプ")) { button_help.setLabel("閉じる"); window.show(); } if (arg.equals("閉じる")) { button_help.setLabel("ヘルプ"); window.dispose(); } } } //end of actionPerformed //========================================================================= // ポップアップメニューイベント //========================================================================= public void itemStateChanged(ItemEvent evt) { Object src = evt.getSource(); String arg = (String)evt.getItem(); //観測地 if (src == choice_City) { for (int i = 0; i < data.city.length; i++) { if (arg.equals(data.city[i][0])) { choice_Sign_lng.setEnabled(false); //ボタン操作不可にする choice_Sign_lat.setEnabled(false); textfield_lng.setEnabled(false); textfield_lat.setEnabled(false); canvas.EW = data.city[i][1]; //規定値セット canvas.NS = data.city[i][3]; canvas.TD = data.city[i][5]; for (int j = 0; j < 2; j++) { //EW選択値に表示切替 if (choice_Sign_lng.getItem(j).equals(canvas.EW)) choice_Sign_lng.select(j); } for (int j = 0; j < 2; j++) { //NS選択値に表示切替 if (choice_Sign_lat.getItem(j).equals(canvas.NS)) choice_Sign_lat.select(j); } textfield_lng.setText(data.city[i][2]); textfield_lat.setText(data.city[i][4]); canvas.cityNo = i; canvas.bool_City = true; canvas.bool_LngLat = false; if (arg.equals("緯経度入力")) { canvas.bool_LngLat = true; choice_Sign_lng.setEnabled(true); //ボタン操作可にする choice_Sign_lat.setEnabled(true); textfield_lng.setEnabled(true); textfield_lat.setEnabled(true); canvas.EW = choice_Sign_lng.getSelectedItem(); //入力値セット canvas.NS = choice_Sign_lat.getSelectedItem(); } //観測地経緯度をセット canvas.LNG = textfield_lng.getText().trim(); canvas.LAT = textfield_lat.getText().trim(); //北緯の時は北を南緯の時は南を初期表示する if (canvas.NS.equals("N") && canvas.DIR != 0) { canvas.DIR = 0; choice_Direction.select(0); } if (canvas.NS.equals("S") && canvas.DIR != 2) { canvas.DIR = 2; choice_Direction.select(2); } //天頂が選択されてる場合北緯/南緯による方角表示切り替え if (canvas.NS.equals("N") && canvas.DIR == 5) canvas.DIR = 4; //北天 if (canvas.NS.equals("S") && canvas.DIR == 4) canvas.DIR = 5; //南天 break; } } } //方角 if (src == choice_Direction) { //方角選択判定 if (arg.equals("北")) canvas.DIR = 0; else if (arg.equals("東")) canvas.DIR = 1; else if (arg.equals("南")) canvas.DIR = 2; else if (arg.equals("西")) canvas.DIR = 3; else if (arg.equals("天頂")) if (canvas.NS.equals("N")) canvas.DIR = 4; //北天 else canvas.DIR = 5; //南天 } //経度緯度記号 if (src == choice_Sign_lng) { if (arg.equals("E")) { canvas.EW="E"; } else if (arg.equals("W")) { canvas.EW="W"; } } if (src == choice_Sign_lat) { if (arg.equals("N")) { canvas.NS="N"; } else if (arg.equals("S")) { canvas.NS="S"; } //北緯の時は北を南緯の時は南を初期表示する if (canvas.NS.equals("N") && canvas.DIR != 0) { canvas.DIR = 0; choice_Direction.select(0); } if (canvas.NS.equals("S") && canvas.DIR != 2) { canvas.DIR = 2; choice_Direction.select(2); } //天頂が選択されてる場合北緯/南緯による方角表示切り替え if (canvas.NS.equals("N") && canvas.DIR == 5) canvas.DIR = 4; //北天 if (canvas.NS.equals("S") && canvas.DIR == 4) canvas.DIR = 5; //南天 } } //end of itemStateChanged } //end of SkyStatus /************************************************************************** * コントロールパネル * ***************************************************************************/ class SkyControls extends Panel implements ActionListener, ItemListener { SkyCanvas canvas; //描画キャンパス SkyStatus status; //ステータスパネル Button button_Motion = new Button("日周開始"); Choice choice_Trace = new Choice(); Choice choice_Speed = new Choice(); // Button button_Star = new Button("星名消去"); Button button_Star = new Button(); Button button_Seiza = new Button("星座消去"); Button button_Planet = new Button("惑星表示"); Button button_Zoomin = new Button("+"); Button button_Zoomout = new Button("−"); Button button_Reset = new Button("リセット"); //========================================================================= // コントロールパネル作成 //========================================================================= public SkyControls(SkyCanvas canvas) { this.canvas = canvas; setBackground(new Color(0,192,192)); add(button_Motion); button_Motion.addActionListener(this); choice_Trace.addItem("航跡無"); choice_Trace.addItem("航跡有"); // 星名、星座、惑星表示の初期値によりボタン表示と航跡可否切替 if (canvas.bool_Star) button_Star = new Button("星名消去"); else button_Star = new Button("星名表示"); if (canvas.bool_Seiza) button_Seiza = new Button("星座消去"); else button_Seiza = new Button("星座表示"); if (canvas.bool_Planet) button_Planet = new Button("惑星消去"); else button_Planet = new Button("惑星表示"); if (canvas.bool_Star || canvas.bool_Seiza || canvas.bool_Planet) { choice_Trace.setEnabled(false); } add(choice_Trace); choice_Trace.addItemListener(this); choice_Speed.addItem("超高"); choice_Speed.addItem("高速"); choice_Speed.addItem("中速"); choice_Speed.addItem("低速"); choice_Speed.addItem("超低"); add(choice_Speed); choice_Speed.addItemListener(this); choice_Speed.select(2); add(button_Star); button_Star.addActionListener(this); add(button_Seiza); button_Seiza.addActionListener(this); add(button_Planet); button_Planet.addActionListener(this); // add(new Label("ズーム:",Label.RIGHT)); add(button_Zoomin); button_Zoomin.addActionListener(this); add(button_Zoomout); button_Zoomout.addActionListener(this); add(button_Reset); button_Reset.addActionListener(this); } //========================================================================= // ボタンイベント //========================================================================= public void actionPerformed(ActionEvent evt) { Object src = evt.getSource(); //イベント種類 String arg = evt.getActionCommand(); //イベント文字列 //日周運動 if (src == button_Motion) { if (arg.equals("日周開始")) { button_Motion.setLabel("日周停止"); canvas.bool_Move = true; if (canvas.bool_LngLat) { status.choice_Sign_lng.setEnabled(false); //経度選択不可にする status.choice_Sign_lat.setEnabled(false); //緯度選択不可にする status.textfield_lng.setEnabled(false); //経度入力不可にする status.textfield_lat.setEnabled(false); //緯度入力不可にする } status.textfield_date.setEnabled(false); //日時入力不可にする status.textfield_hour.setEnabled(false); //時刻入力不可にする canvas.start(); } if (arg.equals("日周停止")) { button_Motion.setLabel("日周開始"); canvas.bool_Move = false; if (canvas.bool_LngLat) { status.choice_Sign_lng.setEnabled(true); //経度選択可にする status.choice_Sign_lat.setEnabled(true); //緯度選択可にする status.textfield_lng.setEnabled(true); //経度入力可にする status.textfield_lat.setEnabled(true); //緯度入力可にする } status.textfield_date.setEnabled(true); //日時入力可にする status.textfield_hour.setEnabled(true); //時刻入力可にする canvas.stop(); } } //星名 if (src == button_Star) { if (arg.equals("星名表示")) { button_Star.setLabel("星名消去"); canvas.bool_Star = true; choice_Trace.setEnabled(false); //航跡操作不可にする canvas.bool_Trace = false; canvas.repaint(); } if (arg.equals("星名消去")) { button_Star.setLabel("星名表示"); canvas.bool_Star = false; if (!canvas.bool_Seiza && !canvas.bool_Planet) choice_Trace.setEnabled(true); //航跡操作可にする canvas.repaint(); } } //星座名・星座線 if (src == button_Seiza) { if (arg.equals("星座表示")) { button_Seiza.setLabel("星座消去"); canvas.bool_Seiza = true; choice_Trace.setEnabled(false); //航跡操作不可にする canvas.bool_Trace = false; canvas.repaint(); } if (arg.equals("星座消去")) { button_Seiza.setLabel("星座表示"); canvas.bool_Seiza = false; if (!canvas.bool_Star && !canvas.bool_Planet) choice_Trace.setEnabled(true); //航跡操作可にする canvas.repaint(); } } //惑星名 if (src == button_Planet) { if (arg.equals("惑星表示")) { button_Planet.setLabel("惑星消去"); canvas.bool_Planet = true; choice_Trace.setEnabled(false); //航跡操作不可にする canvas.bool_Trace = false; canvas.repaint(); } if (arg.equals("惑星消去")) { button_Planet.setLabel("惑星表示"); canvas.bool_Planet = false; if (!canvas.bool_Star && !canvas.bool_Seiza) choice_Trace.setEnabled(true); //航跡操作可にする canvas.repaint(); } } //ズーム if (src == button_Zoomin) { canvas.R +=200; canvas.repaint(); } if (src == button_Zoomout) { canvas.R -=200; canvas.repaint(); } //リセット if (src == button_Reset) { canvas.DATE = status.textfield_date.getText().trim(); //日時リセット canvas.HOUR = status.textfield_hour.getText().trim(); //時刻リセット canvas.bool_Move = false; button_Motion.setLabel("日周開始"); if (canvas.bool_LngLat) { status.choice_Sign_lng.setEnabled(true); //経度選択可にする status.choice_Sign_lat.setEnabled(true); //緯度選択可にする status.textfield_lng.setEnabled(true); //経度入力可にする status.textfield_lat.setEnabled(true); //緯度入力可にする } status.textfield_date.setEnabled(true); //日時入力可にする status.textfield_hour.setEnabled(true); //時刻入力可にする canvas.stop(); choice_Trace.setEnabled(true); //航跡操作可にする canvas.bool_Star = false; button_Star.setLabel("星名表示"); canvas.bool_Seiza = false; button_Seiza.setLabel("星座表示"); canvas.bool_Planet = false; button_Planet.setLabel("惑星表示"); canvas.R = canvas.R0; //天球サイズリセット SkyWatching.vert.setValue(1); SkyWatching.horz.setValue(1); SkyWatching.scrpanel.transxy(SkyWatching.horz.getValue(), SkyWatching.vert.getValue()); canvas.repaint(); } } //end of actionPerformed //========================================================================= // ポップアップメニューイベント //========================================================================= public void itemStateChanged(ItemEvent evt) { Object src = evt.getSource(); String arg = (String)evt.getItem(); //航跡 if (src == choice_Trace) { if (arg.equals("航跡有")) { canvas.bool_Trace = true; button_Star.setEnabled(false); button_Seiza.setEnabled(false); button_Planet.setEnabled(false); } if (arg.equals("航跡無")) { canvas.bool_Trace = false; button_Star.setEnabled(true); button_Seiza.setEnabled(true); button_Planet.setEnabled(true); } // System.out.println("航跡 "+arg+" selected!"); } //速度 if (src == choice_Speed) { if (arg.equals("超高")) { canvas.SPD = 1200; canvas.INV = 2; } if (arg.equals("高速")) { canvas.SPD = 300; canvas.INV = 2; } if (arg.equals("中速")) { canvas.SPD = 120; canvas.INV = 5; } if (arg.equals("低速")) { canvas.SPD = 60; canvas.INV = 10; } if (arg.equals("超低")) { canvas.SPD = 30; canvas.INV = 20; } // System.out.println("速度 "+arg+" selected!"); } } //end of itemStateChanged } //end of SkyControls /************************************************************************** * ヘルプ ***************************************************************************/ class SkyHelp extends Frame { SkyHelp(String help) { super(help); setBackground(Color.white); } public boolean mouseDown(Event evt, int x, int y) { //バナーをクリックしたら「菊池さんの工作室」に移動する // System.out.println("X/Y "+x+" "+y); if (SkyWatching.area.inside(x, y)) { SkyWatching.context.showDocument(SkyWatching.anchor,"_blank"); } return true; } public void paint(Graphics g) { //ヘルプ表示 g.setColor(Color.red); g.setFont(new Font("Dialog",Font.BOLD,14)); g.drawString("星空ウォッチング(プラネタリウム)",10,40); g.setColor(Color.blue); g.setFont(new Font("Dialog",Font.PLAIN,12)); g.drawString("SkyWatching V1.0 by 「菊池さん」",25,55); g.drawString("http://kikuchisan.net/",25,70); g.drawString("(C)2001 Kikuchi-san's workshop. All rights reserved.",25,85); g.setColor(new Color(220,20,60)); g.drawString("SkyWatching(フリー)入手先→バナークリック",25,100); g.drawImage(SkyWatching.banner,220,42,this); g.setColor(Color.black); g.drawString("操作方法",10,125); g.drawString("1.観測地を選択し「再描画」を押します。",25,140); g.drawString("2.緯経度入力を選択すると任意地点の星空を見れます。",25,155); g.drawString("3.日時欄を変更すると指定日時の星空を表示をします。",25,170); g.drawString("4.日周運動、星/星座/惑星表示、拡大縮小が可能です。",25,185); g.drawString("5.画面リセットは「再描画」を押します。",25,200); g.drawString("6.この画面を閉じる時は「閉じる」を押します。",25,215); } } //end of SkyHelp /************************************************************************** * スクロール ***************************************************************************/ class SkyScroll extends Panel { int transx = 0; int transy = 0; Panel innerPanel; public SkyScroll(Panel p) { setLayout(null); innerPanel = p; add(innerPanel); } public void transxy(int x, int y) { transx = -x; transy = -y; innerPanel.move(transx, transy); } } //end of SkyScroll