/******************************************************************************
* 星空ウォッチング(プラネタリウム) *
* 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