teacup. [ 掲示板 ] [ 掲示板作成 ] [ 有料掲示板 ] [ ブログ ]

 投稿者
  題名
  内容 入力補助画像・ファイル<IMG>タグが利用可能です。(詳細)
    
 URL
[ ケータイで使う ] [ BBSティッカー ] [ 書込み通知 ] [ 検索 ]

スレッド一覧

  1. 足あと帳(0)
スレッド一覧(全1)  他のスレッドを探す  スレッド作成

*掲示板をお持ちでない方へ、まずは掲示板を作成しましょう。無料掲示板作成


Android プログラミング

 投稿者:amanojaku@管理人  投稿日:2016年 3月 9日(水)11時19分22秒
返信・引用 編集済
  もし、趣味でプログラミングしてみたいなら Android がオススメです。
Android 端末さえあれば自分の作ったプログラムを人に見せびらかせられるのでモチベーションが上がるんじゃないでしょうか?
ただし、みんなが普段 使ってるような「アプリ、ゲーム」などと比べて雲泥の差でショボイので、あまり良い反応は得られない場合が多々あるかもしれませんけど…。
ただし、普通の Java とは API が全く別物なので WEB で検索して勉強し下さい。

《参考》

Android プログラミングの基本の基本
http://8242.teacup.com/bremen1/bbs/8
アプリの多重起動
http://8242.teacup.com/bremen1/bbs/10
AppCompat 008
http://8242.teacup.com/bremen1/bbs/13
 
 

AppCompat 009

 投稿者:amanojaku@管理人  投稿日:2016年 3月 4日(金)15時20分6秒
返信・引用 編集済
  ActionBarActivity が非推奨になったので、チャントした(プログラム的に) Empty(空(から)) な AppCompatActivity を作ってみる。

以前は良くワカランかったが、「getSupportActionBar( )」で1歩前進したが、それでは Toolbar の「Logo(アイコン)」の表示ができなかったので、下記「OKWAVE」で「Logo(アイコン)、Icon」の表示方法を ご教授いただきました(詳細は下記「OKWAVE」ページ参照)。
Toolbar の Icon のイベントの取得は そんなに難しくないだろうと思って、イロイロ検索しても全然ダメでした。

OKWAVE
http://okwave.jp/qa/q9115191.html


「TextView」に関する設定は下記ページを参考。

TextViewに枠線を付ける&背景色を変更する - yokkongの日記
http://d.hatena.ne.jp/yokkong/20111116/1321425474

【Android開発】スタイルにborderがないけど枠線を表示したい
http://se-suganuma.blogspot.jp/2010/02/androidborder.html


とりあえず、[New Project]で(1ページ目)[Application name]:「AppCompat」、[Company domain]:[example.com]、[Project location]:「C:\Documents and Settings\<User名>\AndroidStudioProjects\<Application name>」と設定(<Application name>は[Application name]で設定した名前と全く同じにして下さい)、(2ページ目)[Phone and Tablet][Minimum SDK]:[API 8:Android 2.2]と設定、(3ページ目)(「Activity」とかもテキストで上書きしてしまうので)「Activity」の設定は とりあえず「Empty Activity」としておく。

「drawable-mdpi、drawable-hdpi」フォルダー(存在しない場合は作成してやる)内に「Android SDK」のデフォルト・アイコン「ic_menu_moreoverflow_normal_holo_light.png」をコピーする。
一応、アプリの Logo マークを Android のマスコット・キャラの「Droid君」にしている。
下の方に"drawable-hdpi"フォルダー用の画像ファイル(「48x48」Pixel)をアップしてあります。
"drawable-mdpi"フォルダー用は手抜きして作ってないが、解像度が低い端末でも自動的に その端末の解像度に合うように縮小して表示される。
その場合、当然 画質は悪くなるので画質を綺麗にしたい場合は手抜きせずにチャント"drawable-mdpi"フォルダー用の画像ファイル(「32x32」Pixel)を作成してやれば良い。
「Toolbar」の UI はスタンダードな「ActionBarActivity」のような感じになっている。
(合っているハズなのに)エラーが消えない場合は一旦 Project を閉じてから、ふたたび Project を開いてみて下さい。


『<Project名>→app→main→java→com.example.appcompat→MainActivity』(MainActivity.java)


package com.example.appcompat;

import android.os.Bundle;
import android.util.Log;
import android.app.Activity;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
// import android.widget.Toolbar;
import android.content.Context;

import android.view.View;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

import android.widget.TextView;
import android.view.KeyEvent;

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;

public class MainActivity extends AppCompatActivity
        implements View.OnClickListener {
    static final String fsDebugCrest = " 008";
    static final String tag = "LogCat.Debug"; // フィルタリング用タグ。
    // ↑ 分かりやすければ どんな文字列でも良い。
    static final boolean DEBUG = true; // false; //
    // ↑ この"DEBUG"は予約語では無い、"Java"において"final"(定数)の場合は
    // 全部 大文字で記述するの事が推奨されているようだ。
    // 「DEBUG=true」に設定すれば「if(DEBUG)Log.i(~)」によって"LogCat"に出力される事になる。
    MainActivity oMainApp;
    Context oBaseContext;
    Context oAppContext;
    Context oContext;
    ActionBar oActionBar;
    Menu oMainMenu;

    String vsPackageName;
    String vsVersionName;
    int iVersionCode;
    String vsToolbarTitle;
    static final int[] WIDGETS =
            new int[]{R.id.button1, R.id.checkBox1, R.id.toggleButton1, R.id.radioButton1};
    TextView ctvMessage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(DEBUG)Log.i(tag, "Activity.onCreate( );");
        setContentView(R.layout.activity_main);
        oMainApp = this;
// System 共通の Context:別の Application とやりとりするとき。
        oBaseContext = getBaseContext( );
// Application 固有の Context(Application ごとに Context が変化する):Application 共通のモノが対象。
        oAppContext = getApplicationContext( );
// Activity 固有の Context(Activity ごとに Context が変化する):Activity に依存モノが対象。
        oContext = this;

        vsPackageName = getPackageName( );
        try {
            PackageInfo packageInfo = this.getPackageManager( ).getPackageInfo(
                    this.getPackageName( ), PackageManager.GET_META_DATA );
            // 「<Project名>→app→build.gradle」ファイル内の
            // 「versionName、versionCode」の設定値を取得。
            vsVersionName = packageInfo.versionName;
            iVersionCode = packageInfo.versionCode;
        } catch (NameNotFoundException e) {
            // 例外処理
            e.printStackTrace( );
        }

        ctvMessage = (TextView)findViewById(R.id.message);
        ctvMessage.append(
                "PackageName=" + vsPackageName + ";\n" +
                        "VersionName=" + vsVersionName + ";\n" +
                        "BuildNo=" + String.valueOf(iVersionCode) + ";\n" +
                        "");

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        oActionBar = getSupportActionBar();

        // oActionBar.setIcon(R.drawable.ic_menu_info_details);
        oActionBar.setLogo(R.drawable.x_logo_android022);
        // ↑ 実際は Logo マークはアプリ固有の Icon にすべきモノです。
        // アプリ固有の Logo マークと言われてもイメージが湧かない方は
        // ブラウザの Icon(Logo マーク)をイメージしてみて下さい。
        // 下記サイトに主要ブラウザの Icon(Logo マーク)が掲載されています。
        // http://freesoft-100.com/pasokon/browser.html
        // ちなみに Toolbar に表示する Icon サイズのスタンダードは
        // "drawable-mdpi"フォルダー用は「32x32」、
        // "drawable-hdpi"フォルダー用は「48x48」だと思われます。

        vsToolbarTitle = "  "+getString(R.string.app_name)+
                fsDebugCrest+
                " V"+vsVersionName+ // Version.
                " R"+String.valueOf(iVersionCode); // Revision.
// ↑ Toolbar に Logo マークを表示させるとタイトルと Logo マークとの間に隙間がないので、
// タイトルの先頭に半角スペースを2つ入れている。
        oActionBar.setTitle(vsToolbarTitle);

        for (int iWgId : WIDGETS) {
            View cvw = findViewById(iWgId);
            cvw.setOnClickListener(this);
        }
    }

    @Override
    protected void onRestart( ) {
        super.onRestart();
        if(DEBUG)Log.i(tag, "Activity.onRestart( );");
    }

    @Override
    protected void onStart( ) {
        super.onStart();
        if(DEBUG)Log.i(tag, "Activity.onStart( );");
    }

    @Override
    protected void onResume( ) {
        super.onResume();
        if(DEBUG)Log.i(tag, "Activity.onResume( );");
    }

    @Override
    protected void onPause( ) {
        super.onPause();
        if(DEBUG)Log.i(tag, "Activity.onPause( );");
    }

    @Override
    protected void onStop( ) {
        super.onStop();
        if(DEBUG)Log.i(tag, "Activity.onStop( );");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(DEBUG)Log.i(tag, "Activity.onDestroy( );");
    }

    @Override
    public void onClick(View v) {
        // super.onClick(v);
        if(DEBUG) Log.i(tag,"Activity.onClick( );");
        switch(v.getId()) {
            case R.id.button1 :
                if (DEBUG) Log.i(tag, "button1");

                break;
            case R.id.checkBox1 :
                if (DEBUG) Log.i(tag, "checkBox1");

                break;
            case R.id.toggleButton1 :
                if (DEBUG) Log.i(tag, "toggleButton1");

                break;
            case R.id.radioButton1 :
                if (DEBUG) Log.i(tag, "radioButton1");

                break;
            default :
                if (DEBUG) Log.i(tag, "default");
                return;
        }
        return;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        // アクションバー内で使用する為のメニューアイテムを実体化
        MenuInflater inflater = getMenuInflater();
        // MenuInflater inflater = getSupportMenuInflater();
        inflater.inflate(R.menu.main, menu);
        // 「R.menu.main」の「menu.main」は 恐らく「res」からの「フォルダー名+ファイル名」
        oMainMenu = menu;
// 戻り値に true を返す事で Event が「消費された」事が通知され、
// 他の Event Listener の処理はキャンセルされます。
        return true; // false; //
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        super.onOptionsItemSelected(item);
        if(DEBUG) Log.i(tag,"Activity.onOptionsItemSelected( );");
        switch(item.getItemId()) {
            case R.id.menu_main_settings :
                if (DEBUG) Log.i(tag, "menu_main_settings");

                break;
            case R.id.menu_main_settings_item1 :
                if (DEBUG) Log.i(tag, "menu_main_settings_item1");

                break;
            case R.id.menu_main_settings_item2 :
                if (DEBUG) Log.i(tag, "menu_main_settings_item2");

                break;
            case R.id.menu_main_settings_item3 :
                if (DEBUG) Log.i(tag, "menu_main_settings_item3");

                break;
            default :
                if (DEBUG) Log.i(tag, "default");
// 戻り値に false を返す事で Event は「消費されてない」事が通知され、
// 他の Event Listener の処理は継続されます。
                return false; // true; //
        }
// 戻り値に true を返す事で Event が「消費された」事が通知され、
// 他の Event Listener の処理はキャンセルされます。
        return true; // false; //
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        super.dispatchKeyEvent(event);
        if(DEBUG) Log.i(tag,"Activity.dispatchKeyEvent( );");
        final int action = event.getAction();
        final int keyCode = event.getKeyCode();
        switch(keyCode) {
            case KeyEvent.KEYCODE_MENU :
                if(DEBUG) Log.i(tag,"KeyEvent.KEYCODE_MENU;");
                if ( action==KeyEvent.ACTION_UP ) {
                    if(DEBUG) Log.i(tag,"KeyEvent.ACTION_UP;");
                    if ( oMainMenu!=null ) {
                        if(DEBUG) Log.i(tag,"oMainMenu.performIdentifierAction( );");
                        oMainMenu.performIdentifierAction(R.id.menu_main_settings, 0);
                    }
// 戻り値に true を返す事で Event が「消費された」事が通知され、
// 他の Event Listener の処理はキャンセルされます。
                    return true; // false; //
                }
                break;

            default :
                if (DEBUG) Log.i(tag, "KeyEvent:Default");

                break;
        }
// 戻り値に false を返す事で Event は「消費されてない」事が通知され、
// 他の Event Listener の処理は継続されます。
        return false; // true; //
    }

}



『<Project名>→app→main→res→drawable→border.xml(ファイルを作成)』
※「TextView」の枠として使っている。


<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffff" />
    <padding android:top="3dp" android:bottom="3dp"
        android:left="7dp" android:right="7dp" />
    <stroke android:width="1px" android:color="#000000" />
    <corners android:radius="5dp" />
</shape>



『<Project名>→app→main→res→layout→activity_main.xml』


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ffffff"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        android:background="#9b7fff"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    <TextView
        android:id="@+id/message"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_margin = "7dp"
        android:background="@drawable/border"
        android:textSize="@dimen/abc_text_size_medium_material"
        android:layout_weight="1" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 1"
        android:id="@+id/button1"
        android:layout_gravity="center_horizontal" />

    <ToggleButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ToggleButton 1"
        android:id="@+id/toggleButton1"
        android:layout_gravity="center_horizontal" />

    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CheckBox 1"
        android:id="@+id/checkBox1"
        android:layout_gravity="center_horizontal" />

    <RadioButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="RadioButton 1"
        android:id="@+id/radioButton1"
        android:layout_gravity="center_horizontal" />

</LinearLayout>



『<Project名>→app→src→main→res→menu→main.xml(フォルダーとファイルを作成)』


<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">

    <item android:id="@+id/menu_main_settings"
        android:title="Settings"
        android:icon="@drawable/ic_menu_moreoverflow_normal_holo_light"
        app:showAsAction="always">
        <!-- ↑ showAsAction:Toolbar に対する表示設定。 -->
        <!-- "always":常に表示、"never":常に表示しない、"ifRoom":表示する余裕があれば表示。 -->
        <menu>
            <item android:id="@+id/menu_main_settings_item1"
                android:title="item1">
            </item>

            <item android:id="@+id/menu_main_settings_item2"
                android:title="item2">
            </item>

            <item android:id="@+id/menu_main_settings_item3"
                android:title="item3">
            </item>
        </menu>
    </item>

</menu>



『<Project名>→app→src→main→res→values→styles.xml』


<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>



『<Project名>→app→main→AndroidManifest.xml』


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.appcompat" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".MainActivity"
            android:launchMode="singleInstance" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
 

系統図

 投稿者:amanojaku@管理人  投稿日:2016年 1月15日(金)12時36分19秒
返信・引用 編集済
  真実のように言われている進化論は実は怪しいモノなのです…

 

Empty (改)

 投稿者:amanojaku@管理人  投稿日:2016年 1月12日(火)14時56分58秒
返信・引用
  「Empty」を ほんの少し修正しました。

ActionBarActivity が非推奨になったので、チャントした(プログラム的に) Empty(空(から)) な Activity を作ってみる。
AppCompatActivity が推奨されているようだが、(デフォルトだと Toolbar が2個表示されてしまうので) ActionBar を非表示にしなければならないが、そうすると(showAsAction="always"設定されている)オプション・メニューが表示されなくなってしまう。
なにか設定が有るのだろうけど、ワカランので"Activity"を継承する事にする。
今回はオプション・メニューの下端が切れる事無く上手(うま)く表示された。

とりあえず、[New Project]で(1ページ目)[Application name]:「Empty」、[Company domain]:[com.example]、[Project location]:「C:\Documents and Settings\<ユーザー名>\AndroidStudioProjects\Empty」と設定、(2ページ目)[Phone and Tablet][Minimum SDK]:[API 8:Android 2.2]と設定、(3ページ目)(「Activity」とかもテキストで上書きしてしまうので)「Activity」の設定は とりあえず「Empty Activity」としておく。
「drawable-mdpi、drawable-hdpi」フォルダー(存在しない場合は作成してやる)内に「Android SDK」のデフォルト・アイコン「ic_menu_info_details.png、ic_menu_moreoverflow_normal_holo_light.png」をコピーする。
「Toolbar」の UI はスタンダードな「ActionBarActivity」のような感じになっている。
(合っているハズなのに)エラーが消えない場合は一旦 Project を閉じてから、ふたたび Project を開いてみて下さい。


『<Project名>→app→main→java→example.com.empty→MainActivity』(MainActivity.java)


package example.com.empty;

import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.MenuItem;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity implements View.OnClickListener {
    MainActivity oMainApp;
    String vsToolbarTitle;
    static final String tag = "LogCat.Debug"; // フィルタリング用タグ。
    // ↑ 分かりやすければ どんな文字列でも良い。
    static final boolean DEBUG = true; // false; //
    // ↑ この"DEBUG"は予約語では無い、"Java"において"final"(定数)の場合は
    // 全部 大文字で記述するの事が推奨されているようだ。
    // 「DEBUG=true」に設定すれば「if(DEBUG)Log.i(~)」によって"LogCat"に出力される事になる。

    String vsVersionName;
    int iVersionCode;
    static final int[] WIDGETS =
            new int[]{R.id.button1, R.id.checkBox1, R.id.toggleButton1, R.id.radioButton1};
    TextView ctvMessage;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(DEBUG)Log.i(tag, "Activity.onCreate( );");
        setContentView(R.layout.activity_main);
        oMainApp = this;

        try {
            PackageInfo packageInfo = this.getPackageManager( ).getPackageInfo(
                    this.getPackageName( ), PackageManager.GET_META_DATA );
            // 「<Project名>→app→build.gradle」ファイル内の
            // 「versionName、versionCode」の設定値を取得。
            vsVersionName = packageInfo.versionName;
            iVersionCode = packageInfo.versionCode;
        } catch (NameNotFoundException e) {
            // 例外処理
            e.printStackTrace( );
        }

        ctvMessage = (TextView)findViewById(R.id.message);
        ctvMessage.append(
            "VersionName=" + vsVersionName + ";\n" +
            "BuildNo=" + String.valueOf(iVersionCode) + ";\n" +
            "");

        Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
        vsToolbarTitle = getString(R.string.app_name)+" V"+vsVersionName+
                " F"+String.valueOf(iVersionCode);
        // Toolbar のタイトルを設定
        toolbar.setTitle(vsToolbarTitle);
        // ナビゲーションアイコンの設定、クリック処理
        toolbar.setNavigationIcon(R.drawable.ic_menu_info_details);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // ナビゲーションアイコンクリック時の処理
                if(DEBUG) Log.i(tag,"toolbar.NavigationIcon.onClick( );");
            }
        });
        // メニューのインフレート、メニューアイテムのクリック処理
        toolbar.inflateMenu(R.menu.main);
        toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                // メニューのクリック処理
                if (DEBUG) Log.i(tag, "toolbar.onMenuItemClick( );");
                return oMainApp.onOptionsItemSelected(item);
            }
        });

        for (int iWgId : WIDGETS) {
            View cvw = findViewById(iWgId);
            cvw.setOnClickListener(this);
        }
    }

    @Override
    protected void onRestart( ) {
        super.onRestart( );
        if(DEBUG)Log.i(tag, "Activity.onRestart( );");
    }

    @Override
    protected void onStart( ) {
        super.onStart();
        if(DEBUG)Log.i(tag, "Activity.onStart( );");
    }

    @Override
    protected void onResume( ) {
        super.onResume();
        if(DEBUG)Log.i(tag, "Activity.onResume( );");
    }

    @Override
    protected void onPause( ) {
        super.onPause();
        if(DEBUG)Log.i(tag, "Activity.onPause( );");
    }

    @Override
    protected void onStop( ) {
        super.onStop();
        if(DEBUG)Log.i(tag, "Activity.onStop( );");
    }

    @Override
    protected void onDestroy( ) {
        super.onDestroy();
        if(DEBUG)Log.i(tag, "Activity.onDestroy( );");
    }

    @Override
    public void onClick(View v) {
        if(DEBUG) Log.i(tag,"Activity.onClick( );");
        switch(v.getId()) {
            case R.id.button1 :
                if (DEBUG) Log.i(tag, "button1");

                break;
            case R.id.checkBox1 :
                if (DEBUG) Log.i(tag, "checkBox1");

                break;
            case R.id.toggleButton1 :
                if (DEBUG) Log.i(tag, "toggleButton1");

                break;
            case R.id.radioButton1 :
                if (DEBUG) Log.i(tag, "radioButton1");

                break;
            default :
                if (DEBUG) Log.i(tag, "default");
                return;
        }
        return;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(DEBUG) Log.i(tag,"Activity.onOptionsItemSelected( );");
        switch(item.getItemId()) {
            case R.id.menu_main_settings :
                if (DEBUG) Log.i(tag, "menu_main_settings");

                break;
            case R.id.menu_main_settings_item1 :
                if (DEBUG) Log.i(tag, "menu_main_settings_item1");

                break;
            case R.id.menu_main_settings_item2 :
                if (DEBUG) Log.i(tag, "menu_main_settings_item2");

                break;
            case R.id.menu_main_settings_item3 :
                if (DEBUG) Log.i(tag, "menu_main_settings_item3");

                break;
            default :
                if (DEBUG) Log.i(tag, "default");
                return false; // true; //
        }
        return true; // false; //
    }

}



『<Project名>→app→main→res→drawable→border.xml(ファイルを作成)』
※「TextView」の枠として使っている。


<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffff" />
    <padding android:top="3dp" android:bottom="3dp"
        android:left="7dp" android:right="7dp" />
    <stroke android:width="1px" android:color="#000000" />
    <corners android:radius="5dp" />
</shape>



『<Project名>→app→main→res→layout→activity_main.xml』


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ffffff"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        android:minHeight="?attr/actionBarSize"
        android:background="#9b7fff"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    <TextView
        android:id="@+id/message"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_margin = "7dp"
        android:background="@drawable/border"
        android:textSize="@dimen/abc_text_size_medium_material"
        android:layout_weight="1" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 1"
        android:id="@+id/button1"
        android:layout_gravity="center_horizontal" />

    <ToggleButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ToggleButton 1"
        android:id="@+id/toggleButton1"
        android:layout_gravity="center_horizontal" />

    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CheckBox 1"
        android:id="@+id/checkBox1"
        android:layout_gravity="center_horizontal" />

    <RadioButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="RadioButton 1"
        android:id="@+id/radioButton1"
        android:layout_gravity="center_horizontal" />

</LinearLayout>



『<Project名>→app→src→main→res→menu→main.xml(フォルダーとファイルを作成)』


<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <item android:id="@+id/menu_main_settings"
        android:title="Settings"
        android:icon="@drawable/ic_menu_moreoverflow_normal_holo_light"
        app:showAsAction="always">
        <!-- ↑ showAsAction:Toolbar に対する表示設定。 -->
        <!-- "always":常に表示、"never":常に表示しない、"ifRoom":表示する余裕があれば表示。 -->
        <menu>
            <item android:id="@+id/menu_main_settings_item1"
                android:title="item1">
            </item>

            <item android:id="@+id/menu_main_settings_item2"
                android:title="item2">
            </item>

            <item android:id="@+id/menu_main_settings_item3"
                android:title="item3">
            </item>
        </menu>
    </item>

</menu>



『<Project名>→app→main→AndroidManifest.xml』


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="example.com.empty">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".MainActivity"
            android:launchMode="singleInstance" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
 

アプリの多重起動

 投稿者:amanojaku@管理人  投稿日:2016年 1月11日(月)11時17分28秒
返信・引用
  Android アプリでは[Home]キーを押した場合"Stop"待機状態になるようなのだが、(Android 2.2 エミュレータでは そのような問題は起こらなかったのだが)問題は(Android 4.3 の実機で)[Home]キーを押した後 そのアプリを再実行すると前のタスクとは別の さらに新しいタスクが加えられて行くようだ(下記サイト参照)。

図で理解するActivityのスタック
http://techblog.qoncept.jp/?p=102

launchMode="singleInstance"に設定することで起動するインスタンスを1つに限定できる。

『AndroidManifest.xml』の下記の部分を変更する、「<application」ではなく「<activity」である事に注意。

>         <activity
>             android:name=".MainActivity"
>             android:label="@string/app_name" >

下記が変更後、最後の行の末尾の">"(グレーターザン:大なり)記号が付け替えられてる事に注意。

>         <activity
>             android:name=".MainActivity"
>             android:label="@string/app_name"
>             android:launchMode="singleInstance" >
 

プログラム的に Empty な Activity

 投稿者:amanojaku@管理人  投稿日:2016年 1月11日(月)09時37分0秒
返信・引用
  ActionBarActivity が非推奨になったので、チャントした(プログラム的に) Empty(空(から)) な Activity を作ってみる。
AppCompatActivity が推奨されているようだが、(デフォルトだと Toolbar が2個表示されてしまうので) ActionBar を非表示にしなければならないが、そうすると(showAsAction="always"設定されている)オプション・メニューが表示されなくなってしまう。
なにか設定が有るのだろうけど、ワカランので"Activity"を継承する事にする。
今回はオプション・メニューの下端が切れる事無く上手(うま)く表示された。

とりあえず、[New Project]で(1ページ目)[Application name]:「Empty」、[Company domain]:[com.example]、[Project location]:「C:\Documents and Settings\<ユーザー名>\AndroidStudioProjects\Empty」と設定、(2ページ目)[Phone and Tablet][Minimum SDK]:[API 8:Android 2.2]と設定、(3ページ目)(「Activity」とかもテキストで上書きしてしまうので)「Activity」の設定は とりあえず「Empty Activity」としておく。
「drawable-mdpi、drawable-hdpi」フォルダー(存在しない場合は作成してやる)内に「Android SDK」のデフォルト・アイコン「ic_menu_info_details.png、ic_menu_moreoverflow_normal_holo_light.png」をコピーする。
「Toolbar」の UI はスタンダードな「ActionBarActivity」のような感じになっている。
(合っているハズなのに)エラーが消えない場合は一旦 Project を閉じてから、ふたたび Project を開いてみて下さい。


『Empty→app→main→java→example.com.empty→MainActivity』(MainActivity.java)


package example.com.empty;

import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.MenuItem;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity implements View.OnClickListener {
    MainActivity oMainApp;
    String vsToolbarTitle = "Empty";
    static final String tag = "LogCat.Debug"; // フィルタリング用タグ。
    // ↑ 分かりやすければ どんな文字列でも良い。
    static final boolean DEBUG = true; // false; //
    // ↑ この"DEBUG"は予約語では無い、"Java"において"final"(定数)の場合は
    // 全部 大文字で記述するの事が推奨されているようだ。
    // 「DEBUG=true」に設定すれば「if(DEBUG)Log.i(~)」によって"LogCat"に出力される事になる。

    String versionName;
    int versionCode;
    static final int[] WIDGETS =
            new int[]{R.id.button1, R.id.checkBox1, R.id.toggleButton1, R.id.radioButton1};
    TextView ctvMessage;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(DEBUG)Log.i(tag, "Activity.onCreate( );");
        setContentView(R.layout.activity_main);
        oMainApp = this;

        Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
        // Toolbar のタイトルを設定
        toolbar.setTitle(vsToolbarTitle);
        // ナビゲーションアイコンの設定、クリック処理
        toolbar.setNavigationIcon(R.drawable.ic_menu_info_details);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // ナビゲーションアイコンクリック時の処理
                if(DEBUG) Log.i(tag,"toolbar.NavigationIcon.onClick( );");
            }
        });
        // メニューのインフレート、メニューアイテムのクリック処理
        toolbar.inflateMenu(R.menu.main);
        toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                // メニューのクリック処理
                if(DEBUG) Log.i(tag,"toolbar.onMenuItemClick( );");
                return oMainApp.onOptionsItemSelected(item);
            }
        });

        try {
            PackageInfo packageInfo = this.getPackageManager( ).getPackageInfo(
                this.getPackageName( ), PackageManager.GET_META_DATA );
            // 「<Project名>→app→build.gradle」ファイル内の
            // 「versionName、versionCode」の設定値を取得。
            versionCode = packageInfo.versionCode;
            versionName = packageInfo.versionName;
        } catch (NameNotFoundException e) {
            // 例外処理
            e.printStackTrace( );
        }

        ctvMessage = (TextView)findViewById(R.id.message);
        ctvMessage.setText(
            "VersionName="+String.valueOf(versionName)+"; "+
            "BuildNo="+String.valueOf(versionCode)+"; "+
            "");

        for (int iWgId : WIDGETS) {
            View cvw = findViewById(iWgId);
            cvw.setOnClickListener(this);
        }
    }

    @Override
    protected void onRestart( ) {
        super.onRestart( );
        if(DEBUG)Log.i(tag, "Activity.onRestart( );");
    }

    @Override
    protected void onStart( ) {
        super.onStart();
        if(DEBUG)Log.i(tag, "Activity.onStart( );");
    }

    @Override
    protected void onResume( ) {
        super.onResume();
        if(DEBUG)Log.i(tag, "Activity.onResume( );");
    }

    @Override
    protected void onPause( ) {
        super.onPause();
        if(DEBUG)Log.i(tag, "Activity.onPause( );");
    }

    @Override
    protected void onStop( ) {
        super.onStop();
        if(DEBUG)Log.i(tag, "Activity.onStop( );");
    }

    @Override
    protected void onDestroy( ) {
        super.onDestroy();
        if(DEBUG)Log.i(tag, "Activity.onDestroy( );");
    }

    @Override
    public void onClick(View v) {
        if(DEBUG) Log.i(tag,"Activity.onClick( );");
        switch(v.getId()) {
            case R.id.button1 :
                if (DEBUG) Log.i(tag, "button1");

                break;
            case R.id.checkBox1 :
                if (DEBUG) Log.i(tag, "checkBox1");

                break;
            case R.id.toggleButton1 :
                if (DEBUG) Log.i(tag, "toggleButton1");

                break;
            case R.id.radioButton1 :
                if (DEBUG) Log.i(tag, "radioButton1");

                break;
            default :
                if (DEBUG) Log.i(tag, "default");
                return;
        }
        return;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(DEBUG) Log.i(tag,"Activity.onOptionsItemSelected( );");
        switch(item.getItemId()) {
            case R.id.menu_main_settings :
                if (DEBUG) Log.i(tag, "menu_main_settings");

                break;
            case R.id.menu_main_settings_item1 :
                if (DEBUG) Log.i(tag, "menu_main_settings_item1");

                break;
            case R.id.menu_main_settings_item2 :
                if (DEBUG) Log.i(tag, "menu_main_settings_item2");

                break;
            case R.id.menu_main_settings_item3 :
                if (DEBUG) Log.i(tag, "menu_main_settings_item3");

                break;
            default :
                if (DEBUG) Log.i(tag, "default");
                return false; // true; //
        }
        return true; // false; //
    }

}



『Empty→app→main→res→drawable→border.xml(ファイルを作成)』
※今回「TextView」の枠として使っている。


<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffff" />
    <padding android:top="3dp" android:bottom="3dp"
        android:left="7dp" android:right="7dp" />
    <stroke android:width="1px" android:color="#000000" />
    <corners android:radius="5dp" />
    <margin android:left="7dp" android:top="7dp"
        android:right="7dp" android:bottom="7dp" />
</shape>



『Empty→app→main→res→layout→activity_main.xml』


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ffffff"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        android:minHeight="?attr/actionBarSize"
        android:background="#9b7fff"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    <TextView
        android:id="@+id/message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_margin = "3dp"
        android:background="@drawable/border"
        android:textSize="@dimen/abc_text_size_medium_material"
        android:layout_weight="1" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 1"
        android:id="@+id/button1"
        android:layout_gravity="center_horizontal" />

    <ToggleButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ToggleButton 1"
        android:id="@+id/toggleButton1"
        android:layout_gravity="center_horizontal" />

    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CheckBox 1"
        android:id="@+id/checkBox1"
        android:layout_gravity="center_horizontal" />

    <RadioButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="RadioButton 1"
        android:id="@+id/radioButton1"
        android:layout_gravity="center_horizontal" />

</LinearLayout>



『Empty→app→src→main→res→menu→main.xml(フォルダーとファイルを作成)』


<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <item android:id="@+id/menu_main_settings"
        android:title="Settings"
        android:icon="@drawable/ic_menu_moreoverflow_normal_holo_light"
        app:showAsAction="always">
        <!-- ↑ showAsAction:Toolbar に対する表示設定。 -->
        <!-- "always":常に表示、"never":常に表示しない、"ifRoom":表示する余裕があれば表示。 -->
        <menu>
            <item android:id="@+id/menu_main_settings_item1"
                android:title="item1">
            </item>

            <item android:id="@+id/menu_main_settings_item2"
                android:title="item2">
            </item>

            <item android:id="@+id/menu_main_settings_item3"
                android:title="item3">
            </item>
        </menu>
    </item>

</menu>



『Empty→app→main→AndroidManifest.xml』


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="example.com.empty">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".MainActivity"
            android:launchMode="singleInstance" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
 

Android プログラミングの基本の基本

 投稿者:amanojaku@管理人  投稿日:2016年 1月11日(月)09時19分15秒
返信・引用 編集済
  ここは実行可能なファイルをダウンロードできるようになっていると記事が削除されてしまうので本来の僕の掲示板は提示できない(別スレで PC 用の実行可能な jar ファイルがアップされている)ので、残念ですが こちらの掲示板でカキコしています。

[Android] Android Studio のインストール Windows アンドロイド開発環境設定
https://akira-watson.com/android/adt-windows.html

Android StudioにおけるAndroidSDKやJDKのパス設定
http://qiita.com/hidekuro/items/d2aadb907c617a4554db

Android Studioで実機デバッグするには? | iDEA CLOUD/dev
http://idea-cloud.com/dev/android_developer_option.html

↑当方ではエミュレータが正常に起動できなかったので、実機でデバッグする事にした、[開発]→[USBデバッグ]→"ON"の方法は機種ごとに設定が違うので、各自 ネットで検索して下さい。
(実機でのデバッグは非常に簡単なので)Android OS 2.2 以上の端末があるなら、エミュレータよりも実機でのデバッグをオススメします。

エミュレーター/実機の画面キャプチャ(スクリーンショット)を撮るには
http://www.adakoda.com/android/000243.html

【Eclipse】targetSdkVersionとビルド・ターゲットの違い
http://nvtrlab.jp/blog/penco/%E3%80%90eclipse%E3%80%91appcompat.html

AndroidアプリのAPIレベルはどれを設定すべきか?
http://itexp.hateblo.jp/entry/android-api-level

minSdkVersionとtargetSdkVersionの関係
http://qiita.com/tksmaru/items/5aac90f06c15e2d2536e

Android dp(dip)とspについて 【Android TIPS】
http://www.sakc.jp/blog/archives/28529

TextView の setTextSize() は sp 単位だよ! - Y.A.M の 雑記帳 Android
http://y-anz-m.blogspot.jp/2012/02/androidtextview-settextsize-sp.html

Android Supoprt Library 22.1がリリースされたので変更点など
http://qiita.com/yshrsmz@github/items/afac02fad7d54e8dca3b

ActionBarActivityが非推奨になったようなので、その代わりに新しく出たAppCompatActivityについて調べてみた
http://tiro105.hateblo.jp/entry/2015/07/18/121414

40歳から始めるブログ: GoogleサンプルでAndroidアプリを学ぶ(ActionBarCompat-Styled)
http://takashin10mura.blogspot.jp/2015/06/googleandroidactionbarcompat-styled.html

アクティビティのライフサイクル
http://www.javadrive.jp/android/activity/index2.html

[Android] Hello world アプリをAndroid Studioで作成
https://akira-watson.com/android/helloworld.html

第7回 Android Studioのキホンのキ ─UIについて
http://gihyo.jp/dev/serial/01/android_studio/0007?page=3

↑とりあえず、当方は「ツール・ウインドウ」内の左上(下記の画像の赤い枠で囲った部分)は「Project」に設定している、この設定で(見た目の)フォルダー構造とか(見た目の)ファイルの位置が変わってくるので注意が必要。
プロジェクトごとにウインドウが作られるようだ、プロジェクト・ウインドウを閉じたい場合は(メニュー・バー)[File]→[Close project]、閉じたプロジェクト・ウインドウを開きたい場合は(メニュー・バー)[File]→[Reopen]→<プロジェクト名>。
良く分からないがプロジェクトは削除できないようだ、恐らくプロジェクトを削除したい場合は その(削除したいプロジェクトの)プロジェクト・ウインドウを閉じてから「C:\Documents and Settings\<ユーザー名>\AndroidStudioProjects」フォルダー内のプロジェクト・フォルダーを削除すれば良いと思われる。
(現時点の「Android Studio 1.5」において)「Android SDK Manager」のウインドウで[元に戻す]でウインドウ・サイズが元に戻らない場合は、「元に戻す」を実行してからウインドウ上部のタイトルバーをマウスの右クリック→(ショートカット・メニュー)[移動]で実際にウインドウを移動してから、マウスでウインドウ・サイズを変更してやる。

build.gradleに設定するAndroid SDKやbuildTools,versionCode等について
http://qiita.com/tomoima525/items/870ac52ce3256e785c4c

↑現在は「minSdkVersion、targetSdkVersion、versionCode、versionName」は「<プロジェクト名>→app→build.gradle」で設定しなければならないようだ(これらを「AndroidManifest.xml」で指定しても無視されるようだ)、「build.gradle」は同名のファイルが他にもあるようなので間違えないように注意が必要。
ちなみに「compileSdkVersion、buildToolsVersion」などは開発環境側(Android Studio 側)によって設定されるデフォルト値のままにしておき変更するべきではないと思われる。

Android 開発ではデフォルトのiconを活用しよう
http://zonomasa.hatenablog.com/entry/android_default_icon

> /Applications/Android Studio.app/sdk/platforms/android-19/data/res/drawable-hdpi

↑(現時点の「Android Studio 1.5」において)Windows では「C:\Android\<sdk>\platforms\android-23\data\res」フォルダー内の「drawable-mdpi、drawable-hdpi」フォルダー内に(「Android SDK」の)デフォルト・アイコンが存在する(「Android Studio」のアップデートにより<sdk>のフォルダー名は変更される場合があるようだ)。
「<プロジェクト名>→app→main→res」フォルダー内の「drawable-mdpi、drawable-hdpi」フォルダー(存在しない場合は作成してやる)内に(無駄に容量を消費するべきではないので)必要なファイルだけをコピーしてやる。

AppCompat v21 でアプリにツールバーを取り入れたときにやったこと一覧と感想など
http://qiita.com/suzukihr/items/96b62d7ae758b09bcabc


「Android SDK Manager」には「API Level 8」(Android OS 2.2)未満は存在しない、これは「API Level 8」(Android OS 2.2)未満は非推奨である事を示唆していると思われる。
よって「minSdkVersion」には「API Level 8」以上が推奨されると思われる(「minSdkVersion」のデフォルト値も"8"(API Level 8)になっている)。
なお、「targetSdkVersion」はアプリ開発時の実行環境の「API Level」を設定しなければならないようだ。
ただし、「Android Studio」のレイアウト・エディターで GUI部品(Widget)のバージョンを指定できるが、「Android Studio」に「API Level 23」(Android OS 6.0)の SDK が(あくまで現時点においての話だが)デフォルトでインストールされており、(当然、使用には制限はあるだろうが)「minSdkVersion、targetSdkVersion」とは関係なく「API Level 23」(Android OS 6.0)の GUI部品(Widget)のバージョンを指定できるようで、その GUI部品(Widget)のバージョンによって見え方も違ってくる。
当方は(現時点の「Android Studio 1.5」において)レイアウト・エディターの GUI部品(Widget)のバージョンを「API Level 23」(Android OS 6.0)に設定している。

全然「Android Studio」を使ってなかったが、最近「Android Studio」を起動すると自動アップデートされたが、新規 Project 生成時の package名 の生成ルールが変更されたようです。
(ここのページでも、他のページでも) Android プログラムを参考にする場合は「MainActivity.java、AndroidManifest.xml」(もし「build.gradle」が記述されている場合は「build.gradle」なども)に記述されている package 名を、新規 Project 生成時の package名 に変更して下さい。
(合っているハズなのに)エラーが消えない場合は一旦 Project を閉じてから、ふたたび Project を開いてみて下さい。
 

Java2 Appletcation 10『Sin グラフを横スクロールさせる(6)』(改2)

 投稿者:amanojaku@管理人  投稿日:2016年 1月10日(日)21時13分17秒
返信・引用
  Sin グラフを横スクロールさせる、ComboBox で「波長の数、カラー」を指定して、[Make]ボタンで新しい Sin グラフを追加できます。
2つ以上の Sin グラフを表示すると、白色で合成波を表示します。
なお、SinGraph の Draw メソッドは使用していません。

「MainAppFrameObj」 からアプレット独自メソッドにアクセスする場合を想定すると、「MainAppFrameObj」はアプレット・クラス内に設置した方が良いだろう。
(アプリーケーションの初期実行用) main( ) メソッドで(MainAppFrameObjなどのような)クラス内クラスをインスタンス化したい場合(main( ) メソッド実行時には、まだアプレット自体のインスタンスが生成されておらず、通常のクラス内クラスではインスタンス化できないので) 、クラス内クラスには「static」修飾子を付与しなければならない(この場合、オブジェクトは1つだけしか作成できない)。

クリック時にマウス・カーソルが動いてしまった場合 mouseClicked イベントだとイベントが発生しない"仕様"になっているようなので、mouse イベントに関しては mouseReleased イベントを使用している。


『Appletcation.java』


import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
//Event を使う場合は、その Event に対応する「~Adapter、~Event」を import しなければならない。
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Appletcation extends JApplet{
    static String vsApplicationTitle = "Application SinGraph 6.";
    static Appletcation oMainApp;
    static boolean lApplication = false; // true;
    static MainAppFrameObj oMainAppFrame;

    int iLayoutX, iLayoutY;
    CanvasObj oCanvas;
    int iCanvasWidth,iCanvasHeight;
    JComboBox ccbSinGraph_WaveQnt;
    int iCbSinGraph_WaveQnt_Width,iCbSinGraph_WaveQnt_Height;
    JComboBox ccbSinGraph_Color;
    int iCbSinGraph_Color_Width,iCbSinGraph_Color_Height;
    Color[] d1oCbSinGraph_ColorSets;
    JButton cbtSinGraph_Make;
    int iBtSinGraph_Make_Width, iBtSinGraph_Make_Height;

    public static void main(String[] args) {
        oMainApp = new Appletcation( );
        lApplication = true; // false;
        oMainAppFrame =
            new MainAppFrameObj(vsApplicationTitle);
        oMainAppFrame.oAppThread.start();
        try{
            oMainAppFrame.oAppThread.join();
        }
        catch(InterruptedException e){ }
        System.exit(0);
    }
    public void init() {
        System.out.println("init( );");

        oMainApp = this;
        getContentPane().setLayout(null); // Layout 座標指定モード

        ccbSinGraph_WaveQnt = new JComboBox( );
        ccbSinGraph_WaveQnt.setModel(new DefaultComboBoxModel(new Object[] { " 1 ", "  2 ", " 3 " }));
        ccbSinGraph_WaveQnt.setDoubleBuffered(false);
        ccbSinGraph_WaveQnt.setBorder(null);
        System.out.println(
            "ccbSinGraph_WaveQnt.getWidth()="+Integer.toString(ccbSinGraph_WaveQnt.getWidth())+"; "+
            "ccbSinGraph_WaveQnt.getHeight()="+Integer.toString(ccbSinGraph_WaveQnt.getHeight())+"; "+
            "ccbSinGraph_WaveQnt.getMinimumSize().width="+Integer.toString(ccbSinGraph_WaveQnt.getMinimumSize().width)+"; "+
            "ccbSinGraph_WaveQnt.getMinimumSize().height="+Integer.toString(ccbSinGraph_WaveQnt.getMinimumSize().height)+"; "+
            "");
        iCbSinGraph_WaveQnt_Width = ccbSinGraph_WaveQnt.getMinimumSize().width;
        iCbSinGraph_WaveQnt_Height = ccbSinGraph_WaveQnt.getMinimumSize().height;

        d1oCbSinGraph_ColorSets = new Color[]{
            Color.GREEN, Color.PINK,
            Color.RED, Color.YELLOW,
        };
        ccbSinGraph_Color = new JComboBox( );
        ccbSinGraph_Color.setModel(new DefaultComboBoxModel(new Object[]
            { "グリーン", "ピンク", "赤", "黄色", }));
        ccbSinGraph_Color.setDoubleBuffered(false);
        ccbSinGraph_Color.setBorder(null);
        iCbSinGraph_Color_Width = ccbSinGraph_Color.getMinimumSize().width;
        iCbSinGraph_Color_Height = ccbSinGraph_Color.getMinimumSize().height;

        cbtSinGraph_Make = new JButton( );
        cbtSinGraph_Make.setText("Make");
        System.out.println(
            "cbtSinGraph_Make.getWidth()="+Integer.toString(cbtSinGraph_Make.getWidth())+"; "+
            "cbtSinGraph_Make.getHeight()="+Integer.toString(cbtSinGraph_Make.getHeight())+"; "+
            "cbtSinGraph_Make.getMinimumSize().width="+Integer.toString(cbtSinGraph_Make.getMinimumSize().width)+"; "+
            "cbtSinGraph_Make.getMinimumSize().height="+Integer.toString(cbtSinGraph_Make.getMinimumSize().height)+"; "+
            "");
        iBtSinGraph_Make_Width = cbtSinGraph_Make.getMinimumSize().width;
        iBtSinGraph_Make_Height = cbtSinGraph_Make.getMinimumSize().height;
        cbtSinGraph_Make.addMouseListener(new MouseAdapter() {
            public void mouseReleased(MouseEvent event) {
                if(null!=oCanvas){
                    oCanvas.SinGraph_Make( );
                }
            }
        });

        iCanvasWidth = 500;
        iCanvasHeight = 500;

        iLayoutX = 0; iLayoutY = 0;
        getContentPane().add(ccbSinGraph_WaveQnt);
        ccbSinGraph_WaveQnt.setBounds(iLayoutX,iLayoutY, iCbSinGraph_WaveQnt_Width, iCbSinGraph_WaveQnt_Height);

        iLayoutX = iLayoutX+iCbSinGraph_WaveQnt_Width; // iLayoutY = 0;
        getContentPane().add(ccbSinGraph_Color);
        ccbSinGraph_Color.setBounds(iLayoutX,iLayoutY, iCbSinGraph_Color_Width, iCbSinGraph_Color_Height);

        iLayoutX = iLayoutX+iCbSinGraph_Color_Width; // iLayoutY = 0;
        getContentPane().add(cbtSinGraph_Make);
        cbtSinGraph_Make.setBounds(iLayoutX,iLayoutY, iBtSinGraph_Make_Width, iBtSinGraph_Make_Height);

        iLayoutX = 0; iLayoutY = iLayoutY+iBtSinGraph_Make_Height;
        oCanvas = new CanvasObj(iLayoutX, iLayoutY, iCanvasWidth, iCanvasHeight);
        getContentPane().add(oCanvas);
        // oCanvas.setVisible(true);

        iLayoutX = iCanvasWidth; iLayoutY = iLayoutY+iCanvasHeight;
        this.setSize(iLayoutX, iLayoutY);
        System.out.println(
            "this.getWidth()="+Integer.toString(this.getWidth())+"; "+
            "this.getHeight()="+Integer.toString(this.getHeight())+"; "+
            "this.getMinimumSize().width="+Integer.toString(this.getMinimumSize().width)+"; "+
            "this.getMinimumSize().height="+Integer.toString(this.getMinimumSize().height)+"; "+
            "");

        if( lApplication ){
            System.out.println("if(lApplication)");
            oMainAppFrame.SetPreSize(this);
            System.out.println("PanelWidth="+oCanvas.getSize( ).getWidth());
            System.out.println("PanelHeight="+oCanvas.getSize( ).getHeight());
        }
        System.out.println("AppletWidth="+getSize( ).getWidth());
        System.out.println("AppletHeight="+getSize( ).getHeight());
    }
    public void start(){
        System.out.println("start( );");

        repaint();

    }
    public void stop(){
        System.out.println("stop( );");
    }
    public void destroy(){
        System.out.println("destroy( );");
    }

    class SinGraph {

        CanvasObj oCanvas;
        // int iWidth,  iHeight;
        int iMoveStride = 3;
        // volatile:最適化の抑制.
        volatile int iMoveDistance = 0;
        int iWaveQnt = 1;
        double vdWaveHeightRate = iWaveQnt;
        int iGraphXStep = 0;
        int iWaveWidth;
        int iWaveHeight;
        Color oColor = Color.BLUE;
        double vdRadian;
        double vdWaveWidth, vdWaveHeight;
        double vdGraphX1, vdGraphX2;
        double vdGraphY1, vdGraphY2;
        double vdWaveY1, vdWaveY2;
        double vdRate, vdRateInt;

        SinGraph( CanvasObj ccv, int iWQ, Color oC ){
            // コンストラクター自体には synchronized 修飾子を付与できないので、
            // synchronized ブロックで囲う。
            synchronized(this){
                // iMoveDistance に対する競合(描画中の変更)を回避する。
                // 対象は SinGraph("自分")内の変数です。
                oCanvas = ccv;
                iWaveQnt = iWQ;
                vdWaveHeightRate = iWaveQnt; // sin グラフの高さの調整。
                oColor = oC;
            }
        }

        synchronized void Draw(Graphics oGraphic){
            // iMoveDistance に対する競合(描画中の変更)を回避する。
            // 対象は SinGraph("自分")内の変数です。
            Graphics2D oGraphic2D = (Graphics2D)oGraphic;

            vdGraphX1 = -1; vdGraphX2 = -1;

            oGraphic2D.setColor(oColor);
            vdWaveWidth = (double)oCanvas.iWidth/iWaveQnt;
            vdWaveHeight = vdWaveWidth/(2*Math.PI)*vdWaveHeightRate;
            iGraphXStep = 0;
            while( iGraphXStep<oCanvas.iWidth ){ // true / false
                DrawBullet(oGraphic, iGraphXStep);
                iGraphXStep++;
            }
        }


        void DrawBullet(Graphics oGraphic, int iBulletGraphXStep){
            Graphics2D oGraphic2D = (Graphics2D)oGraphic;

            oGraphic2D.setColor(oColor);

            if( 0==iBulletGraphXStep ){
                vdGraphX1 = -1;
                vdGraphX2 = -1;
            }
            vdWaveWidth = (double)oCanvas.iWidth/iWaveQnt;
            vdWaveHeight = vdWaveWidth/(2*Math.PI)*vdWaveHeightRate;

            vdGraphX1 = vdGraphX2;
            vdGraphY1 = vdGraphY2;
            vdWaveY1 = vdWaveY2;
            vdRate = (double)
                (iBulletGraphXStep+oCanvas.iWidth-iMoveDistance)/oCanvas.iWidth*iWaveQnt;
            vdRateInt = Math.floor(vdRate);
            vdRate = vdRate-vdRateInt;
            vdGraphX2 = iBulletGraphXStep;
            vdRadian = 2*Math.PI*vdRate;
            vdWaveY2 = Math.sin(vdRadian)*vdWaveHeight;
            vdGraphY2 = oCanvas.iHeight/2-vdWaveY2;
            if(0<=vdGraphX1){
                oGraphic2D.drawLine(
                    (int)Math.round(vdGraphX1), (int)Math.round(vdGraphY1),
                    (int)Math.round(vdGraphX2), (int)Math.round(vdGraphY2));
                // oCanvas.vdGraphX1 = oCanvas.vdGraphX1+vdGraphX1;
                // oCanvas.vdGraphX2 = oCanvas.vdGraphX2+vdGraphX2;
                oCanvas.vdWaveY1 = oCanvas.vdWaveY1+vdWaveY1;
                oCanvas.vdWaveY2 = oCanvas.vdWaveY2+vdWaveY2;
            }
        }

    }

    class CanvasObj extends JPanel {
        // Java2 には JCanvas は存在しないので、
        // グラフィックの描画には JPanel を継承して Canvas の代わりに使う。
        Thread oThread;
        // SinGraph oSinGraph;
        int iWidth;
        int iHeight;
        ArrayList<SinGraph> dl1oSinGraph = new ArrayList<SinGraph>( );
        int iGraphXStep;
        double vdGraphX1,vdGraphX2;
        double vdGraphY1,vdGraphY2;
        double vdWaveY1,vdWaveY2;
        double vdWaveYRate = 0.666; // 合成波のY軸の倍率。

        CanvasObj(int x, int y, int w, int h ) {
            super( );
            System.out.println("oApplet:CanvasObj:");

            setBounds(x, y, w, h);
            iWidth = getWidth( );
            iHeight = getHeight( );
            SinGraph_Make( );

            oThread = new Thread( ){
                @Override
                public void run( ){
                    while( true ){ // true / false
                        repaint();
                        try {
                            Thread.sleep(50); // ←50ミリ秒の sleep。
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        synchronized(CanvasObj.this) {
                            // SinGraph内の iMoveDistance変数に対する競合(描画中の変更)を回避する。
                            // 対象は SinGraph内の変数なのだが、
                            // (CanvasObj の) paint内のループ全体の処理を1つと見なす必要があるので
                            // 実際の対象は CanvasObj とする必要がある。
                            for( SinGraph oSinGraph : dl1oSinGraph.toArray(new SinGraph[0])){
                                // ↑この「new SinGraph[0]」の部分は要素がゼロ個の配列を指定しなければならないらしい。
                                // それにより指定された型と同一の型が返されるらしい。
                                oSinGraph.iMoveDistance = oSinGraph.iMoveDistance+oSinGraph.iMoveStride;
                                if( iWidth<=oSinGraph.iMoveDistance ){ oSinGraph.iMoveDistance = oSinGraph.iMoveDistance-iWidth; }
                            }
                        }
                    }
                }
            };
            oThread.start( );
        }

        void SinGraph_Make( ){
            dl1oSinGraph.add(new SinGraph(this,
               ccbSinGraph_WaveQnt.getSelectedIndex( )+1,
               d1oCbSinGraph_ColorSets[ccbSinGraph_Color.getSelectedIndex( )]));
        }

        @Override
        public synchronized void paint(Graphics oGraphic){
            Graphics2D oGraphic2D = (Graphics2D)oGraphic;
            // ↑(JPanel を継承しているので)ここの Graphics の実態は Graphics2D となるから、
            // キャストしてやれば Graphics2D が使える.

            oGraphic2D.setBackground(Color.BLACK);
            oGraphic2D.clearRect(0, 0, iWidth, iHeight);

            oGraphic2D.setColor(Color.WHITE);
            oGraphic2D.drawLine(0, iHeight/2, iWidth, iHeight/2);

            iGraphXStep = 0;
            vdGraphX1 = 0; vdGraphX2 = 0;
            while( iGraphXStep<iWidth ){ // true / false
                vdWaveY1 = 0; vdWaveY2 = 0;
                vdGraphX1 = vdGraphX2;
                for( SinGraph oSinGraph : dl1oSinGraph.toArray(new SinGraph[0])){
                    // ↑この「new SinGraph[0]」の部分は要素がゼロ個の配列を指定しなければならないらしい。
                    // それにより指定された型と同一の型が返されるらしい。
                    oSinGraph.DrawBullet(oGraphic, iGraphXStep);
                }
                vdGraphX2 = iGraphXStep;
                if( 2<=dl1oSinGraph.size( ) && 0<iGraphXStep ){
                    vdGraphY1 = iHeight/2-vdWaveY1*vdWaveYRate;
                    vdGraphY2 = iHeight/2-vdWaveY2*vdWaveYRate;
                    oGraphic2D.setColor(Color.WHITE);
                    oGraphic2D.drawLine(
                        (int)Math.round(vdGraphX1), (int)Math.round(vdGraphY1),
                        (int)Math.round(vdGraphX2), (int)Math.round(vdGraphY2));
                }
                iGraphXStep++;
            }
        }
         @Override
         public void update(Graphics oGraphic){
             System.out.println("updat( );");
             // Java のバージョンによって違うかもしれないが、
             // 動的なグラフィック表示をする場合は
             // update メソッドが存在しないと表示のチラツキの原因になる場合がある.
            paint(oGraphic);
         }
    }

    static class MainAppFrameObj extends JFrame implements Runnable {
        // JApplet oApplet;
        Thread oAppThread;
        public MainAppFrameObj(String vsAppTitle) {
           super(vsAppTitle);
           //setVisible(false);
           System.out.println("MainAppFrameObj:Construct:Application frame window.");

           // oApplet = oEntApplet; // new JAppletcation();

           addWindowListener(
               new WindowAdapter(){
                   public void windowClosing(WindowEvent event){
                       // ユーザーがウインドウを閉じようとした時].
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowClosing.");
                           Close();
                       }
                   }
               }
           );
           addWindowListener(
               new WindowAdapter(){
                   public void windowClosed(WindowEvent event){
                       // ウインドウが閉じた時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowClosed.");

                       }
                   }
               }
           );
           addWindowListener(
               new WindowAdapter(){
                   public void windowDeiconified(WindowEvent event){
                       // ウィンドウが最小化された状態から通常の状態に変更された時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowDeiconified.");

                           oMainApp.repaint();
                       }
                   }
               }
           );
           addComponentListener(
               new ComponentAdapter(){
                   public void componentResized(ComponentEvent event){
                       // コンポーネントのサイズが変更された時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:ComponentEvent:componentResized.");

                           System.out.println("MainAppFrameObj: "+
                           "width="+Integer.toString(MainAppFrameObj.this.getSize( ).width)+"; "+
                           "Height="+Integer.toString(MainAppFrameObj.this.getSize( ).height)+"; "+
                               "");
                           oMainApp.repaint();
                       }
                   }
               }
           );
           getContentPane().add(oMainApp,"Center");

           oAppThread = new Thread(this);

        }
        public synchronized void SetPreSize(Component oComponent){
            System.out.println("MainAppFrameObj:SetPreSize.");
            // dispose();
            System.out.println(
                "oComponent.getWidth( )="+Integer.toString(oComponent.getWidth())+"; "+
                "oComponent.getHeight( )="+Integer.toString(oComponent.getHeight())+"; "+
                "oComponent.getSize( ).width="+Integer.toString(oComponent.getSize( ).width)+"; "+
                "oComponent.getSize( ).height="+Integer.toString(oComponent.getSize( ).height)+"; "+
                "oComponent.getMinimumSize( ).width="+Integer.toString(oComponent.getMinimumSize().width)+"; "+
                "oComponent.getMinimumSize( ).height="+Integer.toString(oComponent.getMinimumSize().height)+"; "+
                "");
            getContentPane( ).setPreferredSize(
                new Dimension(Math.max(oComponent.getSize( ).width, oComponent.getMinimumSize( ).width),
                Math.max(oComponent.getSize( ).height, oComponent.getMinimumSize( ).height)));
            pack( );
            setVisible(true);
            requestFocus( );
        }
        public synchronized void run(){
            System.out.println("MainAppFrameObj:run.");
            oMainApp.init();
            oMainApp.start();
            oMainApp.repaint();
            try{
                wait();
            }
            catch(InterruptedException e){
                e.printStackTrace();
            }
            oMainApp.stop();
            oMainApp.destroy();
            oAppThread = null;
        }
        public synchronized void Close(){
            System.out.println("MainAppFrameObj:Close:Application frame window.");
            dispose();
            notify();
        }
    }
}
 

Java2 Appletcation 10『Sin グラフを横スクロールさせる(6)』(改)

 投稿者:amanojaku@管理人  投稿日:2016年 1月10日(日)19時01分15秒
返信・引用
  Sin グラフを横スクロールさせる、ComboBox で「波長の数、カラー」を指定して、[Make]ボタンで新しい Sin グラフを追加できます。
2つ以上の Sin グラフを表示すると、白色で合成波を表示します。
なお、SinGraph の Draw メソッドは使用していません。

「MainAppFrameObj」 からアプレット独自メソッドにアクセスする場合を想定すると、「MainAppFrameObj」はアプレット・クラス内に設置した方が良いだろう。
(アプリーケーションの初期実行用) main( ) メソッドで(MainAppFrameObjなどのような)クラス内クラスをインスタンス化したい場合(main( ) メソッド実行時には、まだアプレット自体のインスタンスが生成されておらず、通常のクラス内クラスではインスタンス化できないので) 、クラス内クラスには「static」修飾子を付与しなければならない(この場合、オブジェクトは1つだけしか作成できない)。

クリック時にマウス・カーソルが動いてしまった場合 mouseClicked イベントだとイベントが発生しない"仕様"になっているようなので、mouse イベントに関しては mouseReleased イベントを使用している。


『Appletcation.java』


import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
//Event を使う場合は、その Event に対応する「~Adapter、~Event」を import しなければならない。
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Appletcation extends JApplet{
    static String vsApplicationTitle = "Application SinGraph 6.";
    static Appletcation oMainApp;
    static boolean lApplication = false; // true;
    static MainAppFrameObj oMainAppFrame;

    int iLayoutX, iLayoutY;
    CanvasObj oCanvas;
    int iCanvasWidth,iCanvasHeight;
    JComboBox ccbSinGraph_WaveQnt;
    int iCbSinGraph_WaveQnt_Width,iCbSinGraph_WaveQnt_Height;
    JComboBox ccbSinGraph_Color;
    int iCbSinGraph_Color_Width,iCbSinGraph_Color_Height;
    Color[] d1oCbSinGraph_ColorSets;
    JButton cbtSinGraph_Make;
    int iBtSinGraph_Make_Width, iBtSinGraph_Make_Height;

    public static void main(String[] args) {
        oMainApp = new Appletcation( );
        lApplication = true; // false;
        oMainAppFrame =
            new MainAppFrameObj(vsApplicationTitle);
        oMainAppFrame.oAppThread.start();
        try{
            oMainAppFrame.oAppThread.join();
        }
        catch(InterruptedException e){ }
        System.exit(0);
    }
    public void init() {
        System.out.println("init( );");

        oMainApp = this;
        getContentPane().setLayout(null); // Layout 座標指定モード

        ccbSinGraph_WaveQnt = new JComboBox( );
        ccbSinGraph_WaveQnt.setModel(new DefaultComboBoxModel(new Object[] { " 1 ", "  2 ", " 3 " }));
        ccbSinGraph_WaveQnt.setDoubleBuffered(false);
        ccbSinGraph_WaveQnt.setBorder(null);
        System.out.println(
            "ccbSinGraph_WaveQnt.getWidth()="+Integer.toString(ccbSinGraph_WaveQnt.getWidth())+"; "+
            "ccbSinGraph_WaveQnt.getHeight()="+Integer.toString(ccbSinGraph_WaveQnt.getHeight())+"; "+
            "ccbSinGraph_WaveQnt.getMinimumSize().width="+Integer.toString(ccbSinGraph_WaveQnt.getMinimumSize().width)+"; "+
            "ccbSinGraph_WaveQnt.getMinimumSize().height="+Integer.toString(ccbSinGraph_WaveQnt.getMinimumSize().height)+"; "+
            "");
        iCbSinGraph_WaveQnt_Width = ccbSinGraph_WaveQnt.getMinimumSize().width;
        iCbSinGraph_WaveQnt_Height = ccbSinGraph_WaveQnt.getMinimumSize().height;

        d1oCbSinGraph_ColorSets = new Color[]{
            Color.GREEN, Color.PINK,
            Color.RED, Color.YELLOW,
        };
        ccbSinGraph_Color = new JComboBox( );
        ccbSinGraph_Color.setModel(new DefaultComboBoxModel(new Object[]
            { "グリーン", "ピンク", "赤", "黄色", }));
        ccbSinGraph_Color.setDoubleBuffered(false);
        ccbSinGraph_Color.setBorder(null);
        iCbSinGraph_Color_Width = ccbSinGraph_Color.getMinimumSize().width;
        iCbSinGraph_Color_Height = ccbSinGraph_Color.getMinimumSize().height;

        cbtSinGraph_Make = new JButton( );
        cbtSinGraph_Make.setText("Make");
        System.out.println(
            "cbtSinGraph_Make.getWidth()="+Integer.toString(cbtSinGraph_Make.getWidth())+"; "+
            "cbtSinGraph_Make.getHeight()="+Integer.toString(cbtSinGraph_Make.getHeight())+"; "+
            "cbtSinGraph_Make.getMinimumSize().width="+Integer.toString(cbtSinGraph_Make.getMinimumSize().width)+"; "+
            "cbtSinGraph_Make.getMinimumSize().height="+Integer.toString(cbtSinGraph_Make.getMinimumSize().height)+"; "+
            "");
        iBtSinGraph_Make_Width = cbtSinGraph_Make.getMinimumSize().width;
        iBtSinGraph_Make_Height = cbtSinGraph_Make.getMinimumSize().height;
        cbtSinGraph_Make.addMouseListener(new MouseAdapter() {
            public void mouseReleased(MouseEvent event) {
                if(null!=oCanvas){
                    oCanvas.SinGraph_Make( );
                }
            }
        });

        iCanvasWidth = 500;
        iCanvasHeight = 500;

        iLayoutX = 0; iLayoutY = 0;
        getContentPane().add(ccbSinGraph_WaveQnt);
        ccbSinGraph_WaveQnt.setBounds(iLayoutX,iLayoutY, iCbSinGraph_WaveQnt_Width, iCbSinGraph_WaveQnt_Height);

        iLayoutX = iLayoutX+iCbSinGraph_WaveQnt_Width; // iLayoutY = 0;
        getContentPane().add(ccbSinGraph_Color);
        ccbSinGraph_Color.setBounds(iLayoutX,iLayoutY, iCbSinGraph_Color_Width, iCbSinGraph_Color_Height);

        iLayoutX = iLayoutX+iCbSinGraph_Color_Width; // iLayoutY = 0;
        getContentPane().add(cbtSinGraph_Make);
        cbtSinGraph_Make.setBounds(iLayoutX,iLayoutY, iBtSinGraph_Make_Width, iBtSinGraph_Make_Height);

        iLayoutX = 0; iLayoutY = iLayoutY+iBtSinGraph_Make_Height;
        oCanvas = new CanvasObj(iLayoutX, iLayoutY, iCanvasWidth, iCanvasHeight);
        getContentPane().add(oCanvas);
        // oCanvas.setVisible(true);

        iLayoutX = iCanvasWidth; iLayoutY = iLayoutY+iCanvasHeight;
        this.setSize(iLayoutX, iLayoutY);
        System.out.println(
            "this.getWidth()="+Integer.toString(this.getWidth())+"; "+
            "this.getHeight()="+Integer.toString(this.getHeight())+"; "+
            "this.getMinimumSize().width="+Integer.toString(this.getMinimumSize().width)+"; "+
            "this.getMinimumSize().height="+Integer.toString(this.getMinimumSize().height)+"; "+
            "");

        if( lApplication ){
            System.out.println("if(lApplication)");
            oMainAppFrame.SetPreSize(this);
            System.out.println("PanelWidth="+oCanvas.getSize( ).getWidth());
            System.out.println("PanelHeight="+oCanvas.getSize( ).getHeight());
        }
        System.out.println("AppletWidth="+getSize( ).getWidth());
        System.out.println("AppletHeight="+getSize( ).getHeight());
    }
    public void start(){
        System.out.println("start( );");

        repaint();

    }
    public void stop(){
        System.out.println("stop( );");
    }
    public void destroy(){
        System.out.println("destroy( );");
    }

    class SinGraph {

        CanvasObj oCanvas;
        // int iWidth,  iHeight;
        int iMoveStride = 3;
        // volatile:最適化の抑制.
        volatile int iMoveDistance = 0;
        int iWaveQnt = 1;
        double vdWaveHeightRate = iWaveQnt;
        int iGraphXStep = 0;
        int iWaveWidth;
        int iWaveHeight;
        Color oColor = Color.BLUE;
        double vdRadian;
        double vdWaveWidth, vdWaveHeight;
        double vdGraphX1, vdGraphX2;
        double vdGraphY1, vdGraphY2;
        double vdWaveY1, vdWaveY2;
        double vdRate, vdRateInt;

        SinGraph( CanvasObj ccv, int iWQ, Color oC ){
            // コンストラクター自体には synchronized 修飾子を付与できないので、
            // synchronized ブロックで囲う。
            synchronized(this){
                // iMoveDistance に対する競合(描画中の変更)を回避する。
                // 対象は SinGraph("自分")内の変数です。
                oCanvas = ccv;
                iWaveQnt = iWQ;
                vdWaveHeightRate = iWaveQnt; // sin グラフの高さの調整。
                oColor = oC;
            }
        }

        synchronized void Draw(Graphics oGraphic){
            // iMoveDistance に対する競合(描画中の変更)を回避する。
            // 対象は SinGraph("自分")内の変数です。
            Graphics2D oGraphic2D = (Graphics2D)oGraphic;

            vdGraphX1 = -1; vdGraphX2 = -1;

            oGraphic2D.setColor(oColor);
            vdWaveWidth = (double)oCanvas.iWidth/iWaveQnt;
            vdWaveHeight = vdWaveWidth/(2*Math.PI)*vdWaveHeightRate;
            iGraphXStep = 0;
            while( iGraphXStep<oCanvas.iWidth ){ // true / false
                DrawBullet(oGraphic, iGraphXStep);
                iGraphXStep++;
            }
        }


        synchronized void DrawBullet(Graphics oGraphic, int iBulletGraphYStep){
            Graphics2D oGraphic2D = (Graphics2D)oGraphic;

            oGraphic2D.setColor(oColor);

            if( 0==iBulletGraphYStep ){
                vdGraphX1 = -1;
                vdGraphX2 = -1;
            }
            vdWaveWidth = (double)oCanvas.iWidth/iWaveQnt;
            vdWaveHeight = vdWaveWidth/(2*Math.PI)*vdWaveHeightRate;

            vdGraphX1 = vdGraphX2;
            vdGraphY1 = vdGraphY2;
            vdWaveY1 = vdWaveY2;
            vdRate = (double)
                (iBulletGraphYStep+oCanvas.iWidth-iMoveDistance)/oCanvas.iWidth*iWaveQnt;
            vdRateInt = Math.floor(vdRate);
            vdRate = vdRate-vdRateInt;
            vdGraphX2 = iBulletGraphYStep;
            vdRadian = 2*Math.PI*vdRate;
            vdWaveY2 = Math.sin(vdRadian)*vdWaveHeight;
            vdGraphY2 = oCanvas.iHeight/2-vdWaveY2;
            if(0<=vdGraphX1){
                oGraphic2D.drawLine(
                    (int)Math.round(vdGraphX1), (int)Math.round(vdGraphY1),
                    (int)Math.round(vdGraphX2), (int)Math.round(vdGraphY2));
                // oCanvas.vdGraphX1 = oCanvas.vdGraphX1+vdGraphX1;
                // oCanvas.vdGraphX2 = oCanvas.vdGraphX2+vdGraphX2;
                oCanvas.vdWaveY1 = oCanvas.vdWaveY1+vdWaveY1;
                oCanvas.vdWaveY2 = oCanvas.vdWaveY2+vdWaveY2;
            }
        }

    }

    class CanvasObj extends JPanel {
        // Java2 には JCanvas は存在しないので、
        // グラフィックの描画には JPanel を継承して Canvas の代わりに使う。
        Thread oThread;
        // SinGraph oSinGraph;
        int iWidth;
        int iHeight;
        ArrayList<SinGraph> dl1oSinGraph = new ArrayList<SinGraph>( );
        int iGraphXStep;
        double vdGraphX1,vdGraphX2;
        double vdGraphY1,vdGraphY2;
        double vdWaveY1,vdWaveY2;
        double vdWaveYRate = 0.666; // 合成波のY軸の倍率。

        CanvasObj(int x, int y, int w, int h ) {
            super( );
            System.out.println("oApplet:CanvasObj:");

            setBounds(x, y, w, h);
            iWidth = getWidth( );
            iHeight = getHeight( );
            SinGraph_Make( );

            oThread = new Thread( ){
                @Override
                public void run( ){
                    while( true ){ // true / false
                        repaint();
                        try {
                            Thread.sleep(50); // ←50ミリ秒の sleep。
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        synchronized(CanvasObj.this) {
                            // SinGraph内の iMoveDistance変数に対する競合(描画中の変更)を回避する。
                            // 対象は SinGraph内の変数なのだが、
                            // (CanvasObj の) paint内のループ全体の処理を1つと見なす必要があるので
                            // 実際の対象は CanvasObj とする必要がある。
                            for( SinGraph oSinGraph : dl1oSinGraph.toArray(new SinGraph[0])){
                                // ↑この「new SinGraph[0]」の部分は要素がゼロ個の配列を指定しなければならないらしい。
                                // それにより指定された型と同一の型が返されるらしい。
                                oSinGraph.iMoveDistance = oSinGraph.iMoveDistance+oSinGraph.iMoveStride;
                                if( iWidth<=oSinGraph.iMoveDistance ){ oSinGraph.iMoveDistance = oSinGraph.iMoveDistance-iWidth; }
                            }
                        }
                    }
                }
            };
            oThread.start( );
        }

        void SinGraph_Make( ){
            dl1oSinGraph.add(new SinGraph(this,
               ccbSinGraph_WaveQnt.getSelectedIndex( )+1,
               d1oCbSinGraph_ColorSets[ccbSinGraph_Color.getSelectedIndex( )]));
        }

        @Override
        public synchronized void paint(Graphics oGraphic){
            Graphics2D oGraphic2D = (Graphics2D)oGraphic;
            // ↑(JPanel を継承しているので)ここの Graphics の実態は Graphics2D となるから、
            // キャストしてやれば Graphics2D が使える.

            oGraphic2D.setBackground(Color.BLACK);
            oGraphic2D.clearRect(0, 0, iWidth, iHeight);

            oGraphic2D.setColor(Color.WHITE);
            oGraphic2D.drawLine(0, iHeight/2, iWidth, iHeight/2);

            iGraphXStep = 0;
            vdGraphX1 = 0; vdGraphX2 = 0;
            while( iGraphXStep<iWidth ){ // true / false
                vdWaveY1 = 0; vdWaveY2 = 0;
                vdGraphX1 = vdGraphX2;
                for( SinGraph oSinGraph : dl1oSinGraph.toArray(new SinGraph[0])){
                    // ↑この「new SinGraph[0]」の部分は要素がゼロ個の配列を指定しなければならないらしい。
                    // それにより指定された型と同一の型が返されるらしい。
                    oSinGraph.DrawBullet(oGraphic, iGraphXStep);
                }
                vdGraphX2 = iGraphXStep;
                if( 2<=dl1oSinGraph.size( ) && 0<iGraphXStep ){
                    vdGraphY1 = iHeight/2-vdWaveY1*vdWaveYRate;
                    vdGraphY2 = iHeight/2-vdWaveY2*vdWaveYRate;
                    oGraphic2D.setColor(Color.WHITE);
                    oGraphic2D.drawLine(
                        (int)Math.round(vdGraphX1), (int)Math.round(vdGraphY1),
                        (int)Math.round(vdGraphX2), (int)Math.round(vdGraphY2));
                }
                iGraphXStep++;
            }
        }
         @Override
         public void update(Graphics oGraphic){
             System.out.println("updat( );");
             // Java のバージョンによって違うかもしれないが、
             // 動的なグラフィック表示をする場合は
             // update メソッドが存在しないと表示のチラツキの原因になる場合がある.
            paint(oGraphic);
         }
    }

    static class MainAppFrameObj extends JFrame implements Runnable {
        // JApplet oApplet;
        Thread oAppThread;
        public MainAppFrameObj(String vsAppTitle) {
           super(vsAppTitle);
           //setVisible(false);
           System.out.println("MainAppFrameObj:Construct:Application frame window.");

           // oApplet = oEntApplet; // new JAppletcation();

           addWindowListener(
               new WindowAdapter(){
                   public void windowClosing(WindowEvent event){
                       // ユーザーがウインドウを閉じようとした時].
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowClosing.");
                           Close();
                       }
                   }
               }
           );
           addWindowListener(
               new WindowAdapter(){
                   public void windowClosed(WindowEvent event){
                       // ウインドウが閉じた時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowClosed.");

                       }
                   }
               }
           );
           addWindowListener(
               new WindowAdapter(){
                   public void windowDeiconified(WindowEvent event){
                       // ウィンドウが最小化された状態から通常の状態に変更された時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowDeiconified.");

                           oMainApp.repaint();
                       }
                   }
               }
           );
           addComponentListener(
               new ComponentAdapter(){
                   public void componentResized(ComponentEvent event){
                       // コンポーネントのサイズが変更された時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:ComponentEvent:componentResized.");

                           System.out.println("MainAppFrameObj: "+
                           "width="+Integer.toString(MainAppFrameObj.this.getSize( ).width)+"; "+
                           "Height="+Integer.toString(MainAppFrameObj.this.getSize( ).height)+"; "+
                               "");
                           oMainApp.repaint();
                       }
                   }
               }
           );
           getContentPane().add(oMainApp,"Center");

           oAppThread = new Thread(this);

        }
        public synchronized void SetPreSize(Component oComponent){
            System.out.println("MainAppFrameObj:SetPreSize.");
            // dispose();
            System.out.println(
                "oComponent.getWidth( )="+Integer.toString(oComponent.getWidth())+"; "+
                "oComponent.getHeight( )="+Integer.toString(oComponent.getHeight())+"; "+
                "oComponent.getSize( ).width="+Integer.toString(oComponent.getSize( ).width)+"; "+
                "oComponent.getSize( ).height="+Integer.toString(oComponent.getSize( ).height)+"; "+
                "oComponent.getMinimumSize( ).width="+Integer.toString(oComponent.getMinimumSize().width)+"; "+
                "oComponent.getMinimumSize( ).height="+Integer.toString(oComponent.getMinimumSize().height)+"; "+
                "");
            getContentPane( ).setPreferredSize(
                new Dimension(Math.max(oComponent.getSize( ).width, oComponent.getMinimumSize( ).width),
                Math.max(oComponent.getSize( ).height, oComponent.getMinimumSize( ).height)));
            pack( );
            setVisible(true);
            requestFocus( );
        }
        public synchronized void run(){
            System.out.println("MainAppFrameObj:run.");
            oMainApp.init();
            oMainApp.start();
            oMainApp.repaint();
            try{
                wait();
            }
            catch(InterruptedException e){
                e.printStackTrace();
            }
            oMainApp.stop();
            oMainApp.destroy();
            oAppThread = null;
        }
        public synchronized void Close(){
            System.out.println("MainAppFrameObj:Close:Application frame window.");
            dispose();
            notify();
        }
    }
}
 

Java2 Appletcation 10『Sin グラフを横スクロールさせる(6)』

 投稿者:amanojaku@管理人  投稿日:2016年 1月10日(日)18時22分48秒
返信・引用
  Sin グラフを横スクロールさせる、ComboBox で「波長の数、カラー」を指定して、[Make]ボタンで新しい Sin グラフを追加できます。
2つ以上の Sin グラフを表示すると、白色で合成波を表示します。
なお、SinGraph の Draw メソッドは使用していません。

「MainAppFrameObj」 からアプレット独自メソッドにアクセスする場合を想定すると、「MainAppFrameObj」はアプレット・クラス内に設置した方が良いだろう。
(アプリーケーションの初期実行用) main( ) メソッドで(MainAppFrameObjなどのような)クラス内クラスをインスタンス化したい場合(main( ) メソッド実行時には、まだアプレット自体のインスタンスが生成されておらず、通常のクラス内クラスではインスタンス化できないので) 、クラス内クラスには「static」修飾子を付与しなければならない(この場合、オブジェクトは1つだけしか作成できない)。

クリック時にマウス・カーソルが動いてしまった場合 mouseClicked イベントだとイベントが発生しない"仕様"になっているようなので、mouse イベントに関しては mouseReleased イベントを使用している。


『Appletcation.java』


import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
//Event を使う場合は、その Event に対応する「~Adapter、~Event」を import しなければならない。
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Appletcation extends JApplet{
    static String vsApplicationTitle = "Application SinGraph 6.";
    static Appletcation oMainApp;
    static boolean lApplication = false; // true;
    static MainAppFrameObj oMainAppFrame;

    int iLayoutX, iLayoutY;
    CanvasObj oCanvas;
    int iCanvasWidth,iCanvasHeight;
    JComboBox ccbSinGraph_WaveQnt;
    int iCbSinGraph_WaveQnt_Width,iCbSinGraph_WaveQnt_Height;
    JComboBox ccbSinGraph_Color;
    int iCbSinGraph_Color_Width,iCbSinGraph_Color_Height;
    Color[] d1oCbSinGraph_ColorSets;
    JButton cbtSinGraph_Make;
    int iBtSinGraph_Make_Width, iBtSinGraph_Make_Height;

    public static void main(String[] args) {
        oMainApp = new Appletcation( );
        lApplication = true; // false;
        oMainAppFrame =
            new MainAppFrameObj(vsApplicationTitle);
        oMainAppFrame.oAppThread.start();
        try{
            oMainAppFrame.oAppThread.join();
        }
        catch(InterruptedException e){ }
        System.exit(0);
    }
    public void init() {
        System.out.println("init( );");

        oMainApp = this;
        getContentPane().setLayout(null); // Layout 座標指定モード

        ccbSinGraph_WaveQnt = new JComboBox( );
        ccbSinGraph_WaveQnt.setModel(new DefaultComboBoxModel(new Object[] { " 1 ", "  2 ", " 3 " }));
        ccbSinGraph_WaveQnt.setDoubleBuffered(false);
        ccbSinGraph_WaveQnt.setBorder(null);
        System.out.println(
            "ccbSinGraph_WaveQnt.getWidth()="+Integer.toString(ccbSinGraph_WaveQnt.getWidth())+"; "+
            "ccbSinGraph_WaveQnt.getHeight()="+Integer.toString(ccbSinGraph_WaveQnt.getHeight())+"; "+
            "ccbSinGraph_WaveQnt.getMinimumSize().width="+Integer.toString(ccbSinGraph_WaveQnt.getMinimumSize().width)+"; "+
            "ccbSinGraph_WaveQnt.getMinimumSize().height="+Integer.toString(ccbSinGraph_WaveQnt.getMinimumSize().height)+"; "+
            "");
        iCbSinGraph_WaveQnt_Width = ccbSinGraph_WaveQnt.getMinimumSize().width;
        iCbSinGraph_WaveQnt_Height = ccbSinGraph_WaveQnt.getMinimumSize().height;

        d1oCbSinGraph_ColorSets = new Color[]{
            Color.GREEN, Color.PINK,
            Color.RED, Color.YELLOW,
        };
        ccbSinGraph_Color = new JComboBox( );
        ccbSinGraph_Color.setModel(new DefaultComboBoxModel(new Object[]
            { "グリーン", "ピンク", "赤", "黄色", }));
        ccbSinGraph_Color.setDoubleBuffered(false);
        ccbSinGraph_Color.setBorder(null);
        iCbSinGraph_Color_Width = ccbSinGraph_Color.getMinimumSize().width;
        iCbSinGraph_Color_Height = ccbSinGraph_Color.getMinimumSize().height;

        cbtSinGraph_Make = new JButton( );
        cbtSinGraph_Make.setText("Make");
        System.out.println(
            "cbtSinGraph_Make.getWidth()="+Integer.toString(cbtSinGraph_Make.getWidth())+"; "+
            "cbtSinGraph_Make.getHeight()="+Integer.toString(cbtSinGraph_Make.getHeight())+"; "+
            "cbtSinGraph_Make.getMinimumSize().width="+Integer.toString(cbtSinGraph_Make.getMinimumSize().width)+"; "+
            "cbtSinGraph_Make.getMinimumSize().height="+Integer.toString(cbtSinGraph_Make.getMinimumSize().height)+"; "+
            "");
        iBtSinGraph_Make_Width = cbtSinGraph_Make.getMinimumSize().width;
        iBtSinGraph_Make_Height = cbtSinGraph_Make.getMinimumSize().height;
        cbtSinGraph_Make.addMouseListener(new MouseAdapter() {
            public void mouseReleased(MouseEvent event) {
                if(null!=oCanvas){
                    oCanvas.SinGraph_Make( );
                }
            }
        });

        iCanvasWidth = 500;
        iCanvasHeight = 500;

        iLayoutX = 0; iLayoutY = 0;
        getContentPane().add(ccbSinGraph_WaveQnt);
        ccbSinGraph_WaveQnt.setBounds(iLayoutX,iLayoutY, iCbSinGraph_WaveQnt_Width, iCbSinGraph_WaveQnt_Height);

        iLayoutX = iLayoutX+iCbSinGraph_WaveQnt_Width; // iLayoutY = 0;
        getContentPane().add(ccbSinGraph_Color);
        ccbSinGraph_Color.setBounds(iLayoutX,iLayoutY, iCbSinGraph_Color_Width, iCbSinGraph_Color_Height);

        iLayoutX = iLayoutX+iCbSinGraph_Color_Width; // iLayoutY = 0;
        getContentPane().add(cbtSinGraph_Make);
        cbtSinGraph_Make.setBounds(iLayoutX,iLayoutY, iBtSinGraph_Make_Width, iBtSinGraph_Make_Height);

        iLayoutX = 0; iLayoutY = iLayoutY+iBtSinGraph_Make_Height;
        oCanvas = new CanvasObj(iLayoutX, iLayoutY, iCanvasWidth, iCanvasHeight);
        getContentPane().add(oCanvas);
        // oCanvas.setVisible(true);

        iLayoutX = iCanvasWidth; iLayoutY = iLayoutY+iCanvasHeight;
        this.setSize(iLayoutX, iLayoutY);
        System.out.println(
            "this.getWidth()="+Integer.toString(this.getWidth())+"; "+
            "this.getHeight()="+Integer.toString(this.getHeight())+"; "+
            "this.getMinimumSize().width="+Integer.toString(this.getMinimumSize().width)+"; "+
            "this.getMinimumSize().height="+Integer.toString(this.getMinimumSize().height)+"; "+
            "");

        if( lApplication ){
            System.out.println("if(lApplication)");
            oMainAppFrame.SetPreSize(this);
            System.out.println("PanelWidth="+oCanvas.getSize( ).getWidth());
            System.out.println("PanelHeight="+oCanvas.getSize( ).getHeight());
        }
        System.out.println("AppletWidth="+getSize( ).getWidth());
        System.out.println("AppletHeight="+getSize( ).getHeight());
    }
    public void start(){
        System.out.println("start( );");

        repaint();

    }
    public void stop(){
        System.out.println("stop( );");
    }
    public void destroy(){
        System.out.println("destroy( );");
    }

    class SinGraph {

        CanvasObj oCanvas;
        // int iWidth,  iHeight;
        int iMoveStride = 3;
        // volatile:最適化の抑制.
        volatile int iMoveDistance = 0;
        int iWaveQnt = 1;
        double vdWaveHeightRate = iWaveQnt;
        int iGraphXStep = 0;
        int iWaveWidth;
        int iWaveHeight;
        Color oColor = Color.BLUE;
        double vdRadian;
        double vdWaveWidth, vdWaveHeight;
        double vdGraphX1, vdGraphX2;
        double vdGraphY1, vdGraphY2;
        double vdWaveY1, vdWaveY2;
        double vdRate, vdRateInt;

        SinGraph( CanvasObj ccv, int iWQ, Color oC ){
            // コンストラクター自体には synchronized 修飾子を付与できないので、
            // synchronized ブロックで囲う。
            synchronized(this){
                // iMoveDistance に対する競合(描画中の変更)を回避する。
                // 対象は SinGraph("自分")内の変数です。
                oCanvas = ccv;
                iWaveQnt = iWQ;
                vdWaveHeightRate = iWaveQnt; // sin グラフの高さの調整。
                oColor = oC;
            }
        }

        synchronized void Draw(Graphics oGraphic){
            // iMoveDistance に対する競合(描画中の変更)を回避する。
            // 対象は SinGraph("自分")内の変数です。
            Graphics2D oGraphic2D = (Graphics2D)oGraphic;

            vdGraphX1 = -1; vdGraphX2 = -1;

            oGraphic2D.setColor(oColor);
            vdWaveWidth = (double)oCanvas.iWidth/iWaveQnt;
            vdWaveHeight = vdWaveWidth/(2*Math.PI)*vdWaveHeightRate;
            iGraphXStep = 0;
            while( iGraphXStep<oCanvas.iWidth ){ // true / false
                DrawBullet(oGraphic, iGraphXStep);
                iGraphXStep++;
            }
        }


        synchronized void DrawBullet(Graphics oGraphic, int iBulletGraphYStep){
            Graphics2D oGraphic2D = (Graphics2D)oGraphic;

            oGraphic2D.setColor(oColor);

            if( 0==iBulletGraphYStep ){
                vdGraphX1 = -1;
                vdGraphX2 = -1;
            }
            vdWaveWidth = (double)oCanvas.iWidth/iWaveQnt;
            vdWaveHeight = vdWaveWidth/(2*Math.PI)*vdWaveHeightRate;

            vdGraphX1 = vdGraphX2;
            vdGraphY1 = vdGraphY2;
            vdWaveY1 = vdWaveY2;
            vdRate = (double)
                (iBulletGraphYStep+oCanvas.iWidth-iMoveDistance)/oCanvas.iWidth*iWaveQnt;
            vdRateInt = Math.floor(vdRate);
            vdRate = vdRate-vdRateInt;
            vdGraphX2 = iBulletGraphYStep;
            vdRadian = 2*Math.PI*vdRate;
            vdWaveY2 = Math.sin(vdRadian)*vdWaveHeight;
            vdGraphY2 = oCanvas.iHeight/2-vdWaveY2;
            if(0<=vdGraphX1){
                oGraphic2D.drawLine(
                    (int)Math.round(vdGraphX1), (int)Math.round(vdGraphY1),
                    (int)Math.round(vdGraphX2), (int)Math.round(vdGraphY2));
                // oCanvas.vdGraphX1 = oCanvas.vdGraphX1+vdGraphX1;
                // oCanvas.vdGraphX2 = oCanvas.vdGraphX2+vdGraphX2;
                oCanvas.vdWaveY1 = oCanvas.vdWaveY1+vdWaveY1;
                oCanvas.vdWaveY2 = oCanvas.vdWaveY2+vdWaveY2;
            }
        }

    }

    class CanvasObj extends JPanel {
        // Java2 には JCanvas は存在しないので、
        // グラフィックの描画には JPanel を継承して Canvas の代わりに使う。
        Thread oThread;
        // SinGraph oSinGraph;
        int iWidth;
        int iHeight;
        ArrayList<SinGraph> dl1oSinGraph = new ArrayList<SinGraph>( );
        int iGraphXStep;
        double vdGraphX1,vdGraphX2;
        double vdGraphY1,vdGraphY2;
        double vdWaveY1,vdWaveY2;
        double vdWaveYRate = 0.666; // 合成波のY軸の倍率。

        CanvasObj(int x, int y, int w, int h ) {
            super( );
            System.out.println("oApplet:CanvasObj:");

            setBounds(x, y, w, h);
            iWidth = getWidth( );
            iHeight = getHeight( );
            SinGraph_Make( );

            oThread = new Thread( ){
                @Override
                public void run( ){
                    while( true ){ // true / false
                        repaint();
                        try {
                            Thread.sleep(50); // ←50ミリ秒の sleep。
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        synchronized(CanvasObj.this) {
                            // SinGraph内の iMoveDistance変数に対する競合(描画中の変更)を回避する。
                            // 対象は SinGraph内の変数なのだが、
                            // (CanvasObj の) paint内のループ全体の処理を1つと見なす必要があるので
                            // 実際の対象は CanvasObj とする必要がある。
                            for( SinGraph oSinGraph : dl1oSinGraph.toArray(new SinGraph[0])){
                                // ↑この「new SinGraph[0]」の部分は要素がゼロ個の配列を指定しなければならないらしい。
                                // それにより指定された型と同一の型が返されるらしい。
                                oSinGraph.iMoveDistance = oSinGraph.iMoveDistance+oSinGraph.iMoveStride;
                                if( iWidth<=oSinGraph.iMoveDistance ){ oSinGraph.iMoveDistance = oSinGraph.iMoveDistance-iWidth; }
                            }
                        }
                    }
                }
            };
            oThread.start( );
        }

        void SinGraph_Make( ){
            dl1oSinGraph.add(new SinGraph(this,
               ccbSinGraph_WaveQnt.getSelectedIndex( )+1,
               d1oCbSinGraph_ColorSets[ccbSinGraph_Color.getSelectedIndex( )]));
        }

        @Override
        public synchronized void paint(Graphics oGraphic){
            Graphics2D oGraphic2D = (Graphics2D)oGraphic;
            // ↑(JPanel を継承しているので)ここの Graphics の実態は Graphics2D となるから、
            // キャストしてやれば Graphics2D が使える.

            oGraphic2D.setBackground(Color.BLACK);
            oGraphic2D.clearRect(0, 0, iWidth, iHeight);

            oGraphic2D.setColor(Color.WHITE);
            oGraphic2D.drawLine(0, iHeight/2, iWidth, iHeight/2);

            iGraphXStep = 0;
            vdGraphX1 = 0; vdGraphX2 = 0;
            while( iGraphXStep<iWidth ){ // true / false
                vdWaveY1 = 0; vdWaveY2 = 0;
                vdGraphX1 = vdGraphX2;
                for( SinGraph oSinGraph : dl1oSinGraph.toArray(new SinGraph[0])){
                    // ↑この「new SinGraph[0]」の部分は要素がゼロ個の配列を指定しなければならないらしい。
                    // それにより指定された型と同一の型が返されるらしい。
                    oSinGraph.DrawBullet(oGraphic, iGraphXStep);
                }
                if( 2<=dl1oSinGraph.size( ) && 0<iGraphXStep ){
                    vdGraphY1 = iHeight/2-vdWaveY1*vdWaveYRate;
                    vdGraphY2 = iHeight/2-vdWaveY2*vdWaveYRate;
                    oGraphic2D.setColor(Color.WHITE);
                    oGraphic2D.drawLine(
                        (int)Math.round(vdGraphX1), (int)Math.round(vdGraphY1),
                        (int)Math.round(vdGraphX2), (int)Math.round(vdGraphY2));
                }
                iGraphXStep++;
                vdGraphX2 = iGraphXStep;
            }
        }
         @Override
         public void update(Graphics oGraphic){
             System.out.println("updat( );");
             // Java のバージョンによって違うかもしれないが、
             // 動的なグラフィック表示をする場合は
             // update メソッドが存在しないと表示のチラツキの原因になる場合がある.
            paint(oGraphic);
         }
    }

    static class MainAppFrameObj extends JFrame implements Runnable {
        // JApplet oApplet;
        Thread oAppThread;
        public MainAppFrameObj(String vsAppTitle) {
           super(vsAppTitle);
           //setVisible(false);
           System.out.println("MainAppFrameObj:Construct:Application frame window.");

           // oApplet = oEntApplet; // new JAppletcation();

           addWindowListener(
               new WindowAdapter(){
                   public void windowClosing(WindowEvent event){
                       // ユーザーがウインドウを閉じようとした時].
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowClosing.");
                           Close();
                       }
                   }
               }
           );
           addWindowListener(
               new WindowAdapter(){
                   public void windowClosed(WindowEvent event){
                       // ウインドウが閉じた時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowClosed.");

                       }
                   }
               }
           );
           addWindowListener(
               new WindowAdapter(){
                   public void windowDeiconified(WindowEvent event){
                       // ウィンドウが最小化された状態から通常の状態に変更された時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowDeiconified.");

                           oMainApp.repaint();
                       }
                   }
               }
           );
           addComponentListener(
               new ComponentAdapter(){
                   public void componentResized(ComponentEvent event){
                       // コンポーネントのサイズが変更された時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:ComponentEvent:componentResized.");

                           System.out.println("MainAppFrameObj: "+
                           "width="+Integer.toString(MainAppFrameObj.this.getSize( ).width)+"; "+
                           "Height="+Integer.toString(MainAppFrameObj.this.getSize( ).height)+"; "+
                               "");
                           oMainApp.repaint();
                       }
                   }
               }
           );
           getContentPane().add(oMainApp,"Center");

           oAppThread = new Thread(this);

        }
        public synchronized void SetPreSize(Component oComponent){
            System.out.println("MainAppFrameObj:SetPreSize.");
            // dispose();
            System.out.println(
                "oComponent.getWidth( )="+Integer.toString(oComponent.getWidth())+"; "+
                "oComponent.getHeight( )="+Integer.toString(oComponent.getHeight())+"; "+
                "oComponent.getSize( ).width="+Integer.toString(oComponent.getSize( ).width)+"; "+
                "oComponent.getSize( ).height="+Integer.toString(oComponent.getSize( ).height)+"; "+
                "oComponent.getMinimumSize( ).width="+Integer.toString(oComponent.getMinimumSize().width)+"; "+
                "oComponent.getMinimumSize( ).height="+Integer.toString(oComponent.getMinimumSize().height)+"; "+
                "");
            getContentPane( ).setPreferredSize(
                new Dimension(Math.max(oComponent.getSize( ).width, oComponent.getMinimumSize( ).width),
                Math.max(oComponent.getSize( ).height, oComponent.getMinimumSize( ).height)));
            pack( );
            setVisible(true);
            requestFocus( );
        }
        public synchronized void run(){
            System.out.println("MainAppFrameObj:run.");
            oMainApp.init();
            oMainApp.start();
            oMainApp.repaint();
            try{
                wait();
            }
            catch(InterruptedException e){
                e.printStackTrace();
            }
            oMainApp.stop();
            oMainApp.destroy();
            oAppThread = null;
        }
        public synchronized void Close(){
            System.out.println("MainAppFrameObj:Close:Application frame window.");
            dispose();
            notify();
        }
    }
}
 

Java2 Appletcation 8『Sin グラフを横スクロールさせる(5)』

 投稿者:amanojaku@管理人  投稿日:2016年 1月10日(日)08時18分13秒
返信・引用
  import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
//Event を使う場合は、その Event に対応する「~Adapter、~Event」を import しなければならない。
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Appletcation extends JApplet{
    static Appletcation oMainApp;
    static boolean lApplication = false; // true;
    static MainAppFrameObj oMainAppFrame;

    int iLayoutX, iLayoutY;
    CanvasObj oCanvas;
    int iCanvasWidth,iCanvasHeight;
    JComboBox ccbSinGraph_WaveQnt;
    int iCbSinGraph_WaveQnt_Width,iCbSinGraph_WaveQnt_Height;
    JComboBox ccbSinGraph_Color;
    int iCbSinGraph_Color_Width,iCbSinGraph_Color_Height;
    Color[] d1oCbSinGraph_ColorSets;
    JButton cbtSinGraph_Make;
    int iBtSinGraph_Make_Width, iBtSinGraph_Make_Height;

    public static void main(String[] args) {
        oMainApp = new Appletcation( );
        lApplication = true; // false;
        oMainAppFrame =
            new MainAppFrameObj( );
        oMainAppFrame.oAppThread.start();
        try{
            oMainAppFrame.oAppThread.join();
        }
        catch(InterruptedException e){ }
        System.exit(0);
    }
    public void init() {
        System.out.println("init( );");

        oMainApp = this;
        getContentPane().setLayout(null); // Layout 座標指定モード

        ccbSinGraph_WaveQnt = new JComboBox( );
        ccbSinGraph_WaveQnt.setModel(new DefaultComboBoxModel(new Object[] { " 1 ", "  2 ", " 3 " }));
        ccbSinGraph_WaveQnt.setDoubleBuffered(false);
        ccbSinGraph_WaveQnt.setBorder(null);
        System.out.println(
            "ccbSinGraph_WaveQnt.getWidth()="+Integer.toString(ccbSinGraph_WaveQnt.getWidth())+"; "+
            "ccbSinGraph_WaveQnt.getHeight()="+Integer.toString(ccbSinGraph_WaveQnt.getHeight())+"; "+
            "ccbSinGraph_WaveQnt.getMinimumSize().width="+Integer.toString(ccbSinGraph_WaveQnt.getMinimumSize().width)+"; "+
            "ccbSinGraph_WaveQnt.getMinimumSize().height="+Integer.toString(ccbSinGraph_WaveQnt.getMinimumSize().height)+"; "+
            "");
        iCbSinGraph_WaveQnt_Width = ccbSinGraph_WaveQnt.getMinimumSize().width;
        iCbSinGraph_WaveQnt_Height = ccbSinGraph_WaveQnt.getMinimumSize().height;

        d1oCbSinGraph_ColorSets = new Color[]{
            Color.GREEN, Color.PINK,
            Color.RED, Color.YELLOW,
        };
        ccbSinGraph_Color = new JComboBox( );
        ccbSinGraph_Color.setModel(new DefaultComboBoxModel(new Object[]
            { "グリーン", "ピンク", "赤", "黄色", }));
        ccbSinGraph_Color.setDoubleBuffered(false);
        ccbSinGraph_Color.setBorder(null);
        iCbSinGraph_Color_Width = ccbSinGraph_Color.getMinimumSize().width;
        iCbSinGraph_Color_Height = ccbSinGraph_Color.getMinimumSize().height;

        cbtSinGraph_Make = new JButton( );
        cbtSinGraph_Make.setText("Make");
        System.out.println(
            "cbtSinGraph_Make.getWidth()="+Integer.toString(cbtSinGraph_Make.getWidth())+"; "+
            "cbtSinGraph_Make.getHeight()="+Integer.toString(cbtSinGraph_Make.getHeight())+"; "+
            "cbtSinGraph_Make.getMinimumSize().width="+Integer.toString(cbtSinGraph_Make.getMinimumSize().width)+"; "+
            "cbtSinGraph_Make.getMinimumSize().height="+Integer.toString(cbtSinGraph_Make.getMinimumSize().height)+"; "+
            "");
        iBtSinGraph_Make_Width = cbtSinGraph_Make.getMinimumSize().width;
        iBtSinGraph_Make_Height = cbtSinGraph_Make.getMinimumSize().height;
        cbtSinGraph_Make.addMouseListener(new MouseAdapter() {
            public void mouseReleased(MouseEvent event) {
                if(null!=oCanvas){
                    oCanvas.SinGraph_Make( );
                }
            }
        });

        iCanvasWidth = 500;
        iCanvasHeight = 300;

        iLayoutX = 0; iLayoutY = 0;
        getContentPane().add(ccbSinGraph_WaveQnt);
        ccbSinGraph_WaveQnt.setBounds(iLayoutX,iLayoutY, iCbSinGraph_WaveQnt_Width, iCbSinGraph_WaveQnt_Height);

        iLayoutX = iLayoutX+iCbSinGraph_WaveQnt_Width; // iLayoutY = 0;
        getContentPane().add(ccbSinGraph_Color);
        ccbSinGraph_Color.setBounds(iLayoutX,iLayoutY, iCbSinGraph_Color_Width, iCbSinGraph_Color_Height);

        iLayoutX = iLayoutX+iCbSinGraph_Color_Width; // iLayoutY = 0;
        getContentPane().add(cbtSinGraph_Make);
        cbtSinGraph_Make.setBounds(iLayoutX,iLayoutY, iBtSinGraph_Make_Width, iBtSinGraph_Make_Height);

        iLayoutX = 0; iLayoutY = iLayoutY+iBtSinGraph_Make_Height;
        oCanvas = new CanvasObj(iLayoutX, iLayoutY, iCanvasWidth, iCanvasHeight);
        getContentPane().add(oCanvas);
        // oCanvas.setVisible(true);

        iLayoutX = iCanvasWidth; iLayoutY = iLayoutY+iCanvasHeight;
        // this.setSize(iLayoutX, iLayoutY);
        System.out.println(
            "this.getWidth()="+Integer.toString(this.getWidth())+"; "+
            "this.getHeight()="+Integer.toString(this.getHeight())+"; "+
            "this.getMinimumSize().width="+Integer.toString(this.getMinimumSize().width)+"; "+
            "this.getMinimumSize().height="+Integer.toString(this.getMinimumSize().height)+"; "+
            "");

        if( lApplication ){
            System.out.println("if(lApplication)");
            oMainAppFrame.setPreSize(new Dimension(iLayoutX, iLayoutY));
            System.out.println("PanelWidth="+oCanvas.getSize( ).getWidth());
            System.out.println("PanelHeight="+oCanvas.getSize( ).getHeight());
        }
        System.out.println("AppletWidth="+getSize( ).getWidth());
        System.out.println("AppletHeight="+getSize( ).getHeight());
    }
    public void start(){
        System.out.println("start( );");

        repaint();

    }
    public void stop(){
        System.out.println("stop( );");
    }
    public void destroy(){
        System.out.println("destroy( );");
    }

    class SinGraph {

        int iWidth;
        int iHeight;
        int iMoveStride = 3;
        // volatile:最適化の抑制.
        volatile int iMoveDistance = 0;
        int iWaveQnt = 1;
        double vdWaveHeightRate = iWaveQnt;
        int iWaveStep = 0;
        int iWaveWidth;
        int iWaveHeight;
        Color oColor = Color.BLUE;
        double vdRadian;
        double vdWaveWidth,vdWaveHeight;
        double vdWaveX1,vdWaveX2;
        double vdWaveY1,vdWaveY2;
        double vdRate,vdRateInt;

        SinGraph( int iW, int iH, int iWQ, Color oC ){
            // コンストラクター自体には synchronized 修飾子を付与できないので、
            // synchronized ブロックで囲う。
            synchronized(this){
                // iMoveDistance に対する競合(描画中の変更)を回避する。
                // 対象は SinGraph("自分")内の変数です。
                iWidth = iW;
                iHeight = iH;
                iWaveQnt = iWQ;
                vdWaveHeightRate = iWaveQnt; // sin グラフの高さの調整。
                oColor = oC;
            }
        }

        synchronized void Draw(Graphics oGraphic){
            // iMoveDistance に対する競合(描画中の変更)を回避する。
            // 対象は SinGraph("自分")内の変数です。
            Graphics2D oGraphic2D = (Graphics2D)oGraphic;

            oGraphic2D.setColor(oColor);
            vdWaveWidth = (double)iWidth/iWaveQnt;
            vdWaveHeight = vdWaveWidth/(2*Math.PI)*vdWaveHeightRate;
            iWaveStep = 0;
            vdWaveX1 = -1; vdWaveX2 = -1;
            while( iWaveStep<iWidth ){ // true / false
                vdWaveX1 = vdWaveX2;
                vdWaveY1 = vdWaveY2;
                vdRate = (double)
                    (iWaveStep+iWidth-iMoveDistance)/iWidth*iWaveQnt;
                vdRateInt = Math.floor(vdRate);
                vdRate = vdRate-vdRateInt;
                vdWaveX2 = iWaveStep;
                vdRadian = 2*Math.PI*vdRate;
                vdWaveY2 = iHeight/2-Math.sin(vdRadian)*vdWaveHeight;
                iWaveStep++;
                if(0<=vdWaveX1){
                    oGraphic2D.drawLine(
                        (int)Math.round(vdWaveX1), (int)Math.round(vdWaveY1),
                        (int)Math.round(vdWaveX2), (int)Math.round(vdWaveY2));
                }
            }
        }

    }

    class CanvasObj extends JPanel {
        // Java2 には JCanvas は存在しないので、
        // グラフィックの描画には JPanel を継承して Canvas の代わりに使う。
        Thread oThread;
        // SinGraph oSinGraph;
        int iWidth;
        int iHeight;
        ArrayList<SinGraph> dl1oSinGraph = new ArrayList<SinGraph>( );

        CanvasObj(int x, int y, int w, int h ) {
            super( );
            System.out.println("oApplet:CanvasObj:");

            setBounds(x, y, w, h);
            iWidth = getWidth( );
            iHeight = getHeight( );
            SinGraph_Make( );

            oThread = new Thread( ){
                @Override
                public void run( ){
                    while( true ){ // true / false
                        repaint();
                        try {
                            Thread.sleep(50); // ←50ミリ秒の sleep。
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        for( SinGraph oSinGraph : dl1oSinGraph.toArray(new SinGraph[0])){
                            // ↑この「new SinGraph[0]」の部分は要素がゼロ個の配列を指定しなければならないらしい。
                            // それにより指定された型と同一の型が返されるらしい。
                            synchronized(oSinGraph) {
                                // SinGraph内の iMoveDistance変数に対する競合(描画中の変更)を回避する。
                                // 対象は SinGraph内の変数なので、当然 ここは"他人"となります。
                                oSinGraph.iMoveDistance = oSinGraph.iMoveDistance+oSinGraph.iMoveStride;
                                if( iWidth<=oSinGraph.iMoveDistance ){ oSinGraph.iMoveDistance = oSinGraph.iMoveDistance-iWidth; }
                            }
                        }

                    }

                }
            };
            oThread.start( );

        }

        void SinGraph_Make( ){
            dl1oSinGraph.add(new SinGraph(iWidth, iHeight,
               ccbSinGraph_WaveQnt.getSelectedIndex( )+1,
               d1oCbSinGraph_ColorSets[ccbSinGraph_Color.getSelectedIndex( )]));
        }

        @Override
        public void paint(Graphics oGraphic){
            Graphics2D oGraphic2D = (Graphics2D)oGraphic;
            // ↑(JPanel を継承しているので)ここの Graphics の実態は Graphics2D となるから、
            // キャストしてやれば Graphics2D が使える.

            oGraphic2D.setBackground(Color.BLACK);
            oGraphic2D.clearRect(0, 0, iWidth, iHeight);

            oGraphic2D.setColor(Color.WHITE);
            oGraphic2D.drawLine(0, iHeight/2, iWidth, iHeight/2);

            for( SinGraph oSinGraph : dl1oSinGraph.toArray(new SinGraph[0])){
                // ↑この「new SinGraph[0]」の部分は要素がゼロ個の配列を指定しなければならないらしい。
                // それにより指定された型と同一の型が返されるらしい。
                oSinGraph.Draw(oGraphic2D);
            }
        }
         @Override
         public void update(Graphics oGraphic){
             System.out.println("updat( );");
             // Java のバージョンによって違うかもしれないが、
             // 動的なグラフィック表示をする場合は
             // update メソッドが存在しないと表示のチラツキの原因になる場合がある.
            paint(oGraphic);
         }
    }

    static class MainAppFrameObj extends JFrame implements Runnable {
        // JApplet oApplet;
        Thread oAppThread;
        public MainAppFrameObj( ) {
           super("Application frame.");
           //setVisible(false);
           System.out.println("Construct:Application frame window.");

           // oApplet = oEntApplet; // new JAppletcation();

           addWindowListener(
               new WindowAdapter(){
                   public void windowClosing(WindowEvent event){
                       // ユーザーがウインドウを閉じようとした時].
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowClosing.");
                           Close();
                       }
                   }
               }
           );
           addWindowListener(
               new WindowAdapter(){
                   public void windowClosed(WindowEvent event){
                       // ウインドウが閉じた時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowClosed.");

                       }
                   }
               }
           );
           addWindowListener(
               new WindowAdapter(){
                   public void windowDeiconified(WindowEvent event){
                       // ウィンドウが最小化された状態から通常の状態に変更された時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowDeiconified.");

                           oMainApp.repaint();
                       }
                   }
               }
           );
           addComponentListener(
               new ComponentAdapter(){
                   public void componentResized(ComponentEvent event){
                       // コンポーネントのサイズが変更された時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("ComponentEvent:componentResized.");

                           System.out.println("MainAppFrameObj: "+
                           "width="+Integer.toString(MainAppFrameObj.this.getSize( ).width)+"; "+
                           "Height="+Integer.toString(MainAppFrameObj.this.getSize( ).height)+"; "+
                               "");
                           oMainApp.repaint();
                       }
                   }
               }
           );
           getContentPane().add(oMainApp,"Center");

           oAppThread = new Thread(this);

        }
        public synchronized void setPreSize(Dimension oSize){
            // dispose();
            getContentPane().setPreferredSize(oSize);
            pack();
            setVisible(true);
            requestFocus();
        }
        public synchronized void run(){
            System.out.println("Open:Application frame window.");
            oMainApp.init();
            oMainApp.start();
            oMainApp.repaint();
            try{
                wait();
            }
            catch(InterruptedException e){
                e.printStackTrace();
            }
            oMainApp.stop();
            oMainApp.destroy();
            oAppThread = null;

        }
        public synchronized void Close(){
            System.out.println("Close:Application frame window.");
            dispose();
            notify();
        }
    }

}
 

Java2 Appletcation 7『Sin グラフを横スクロールさせる(3)』

 投稿者:amanojaku@管理人  投稿日:2016年 1月10日(日)07時24分54秒
返信・引用
  Sin グラフを横スクロールさせる、ComboBox で「波長の数、カラー」を指定して、[Make]ボタンで新しい Sin グラフを追加できます。

「MainAppFrameObj」 からアプレット独自メソッドにアクセスする場合を想定すると、「MainAppFrameObj」はアプレット・クラス内に設置した方が良いだろう。
(アプリーケーションの初期実行用) main( ) メソッドで(MainAppFrameObjなどのような)クラス内クラスをインスタンス化したい場合(main( ) メソッド実行時には、まだアプレット自体のインスタンスが生成されておらず、通常のクラス内クラスではインスタンス化できないので) 、クラス内クラスには「static」修飾子を付与しなければならない(この場合、オブジェクトは1つだけしか作成できない)。

クリック時にマウス・カーソルが動いてしまった場合 mouseClicked イベントだとイベントが発生しない"仕様"になっているようなので、mouse イベントに関しては mouseReleased イベントを使用している。


『Appletcation.java』


import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
//Event を使う場合は、その Event に対応する「~Adapter、~Event」を import しなければならない。
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Appletcation extends JApplet{
    static Appletcation oMainApp;
    static boolean lApplication = false; // true;
    static MainAppFrameObj oMainAppFrame;

    int iLayoutX, iLayoutY;
    CanvasObj oCanvas;
    int iCanvasWidth,iCanvasHeight;
    JComboBox ccbSinGraph_WaveQnt;
    int iCbSinGraph_WaveQnt_Width,iCbSinGraph_WaveQnt_Height;
    JComboBox ccbSinGraph_Color;
    int iCbSinGraph_Color_Width,iCbSinGraph_Color_Height;
    Color[] d1oCbSinGraph_ColorSets;
    JButton cbtSinGraph_Make;
    int iBtSinGraph_Make_Width, iBtSinGraph_Make_Height;

    public static void main(String[] args) {
        oMainApp = new Appletcation( );
        lApplication = true; // false;
        oMainAppFrame =
            new MainAppFrameObj( );
        oMainAppFrame.oAppThread.start();
        try{
            oMainAppFrame.oAppThread.join();
        }
        catch(InterruptedException e){ }
        System.exit(0);
    }
    public void init() {
        System.out.println("init( );");

        oMainApp = this;
        getContentPane().setLayout(null); // Layout 座標指定モード

        ccbSinGraph_WaveQnt = new JComboBox( );
        ccbSinGraph_WaveQnt.setModel(new DefaultComboBoxModel(new Object[] { " 1 ", "  2 ", " 3 " }));
        ccbSinGraph_WaveQnt.setDoubleBuffered(false);
        ccbSinGraph_WaveQnt.setBorder(null);
        System.out.println(
            "ccbSinGraph_WaveQnt.getWidth()="+Integer.toString(ccbSinGraph_WaveQnt.getWidth())+"; "+
            "ccbSinGraph_WaveQnt.getHeight()="+Integer.toString(ccbSinGraph_WaveQnt.getHeight())+"; "+
            "ccbSinGraph_WaveQnt.getMinimumSize().width="+Integer.toString(ccbSinGraph_WaveQnt.getMinimumSize().width)+"; "+
            "ccbSinGraph_WaveQnt.getMinimumSize().height="+Integer.toString(ccbSinGraph_WaveQnt.getMinimumSize().height)+"; "+
            "");
        iCbSinGraph_WaveQnt_Width = ccbSinGraph_WaveQnt.getMinimumSize().width;
        iCbSinGraph_WaveQnt_Height = ccbSinGraph_WaveQnt.getMinimumSize().height;

        d1oCbSinGraph_ColorSets = new Color[]{
            Color.GREEN, Color.PINK,
            Color.RED, Color.YELLOW,
        };
        ccbSinGraph_Color = new JComboBox( );
        ccbSinGraph_Color.setModel(new DefaultComboBoxModel(new Object[]
            { "グリーン", "ピンク", "赤", "黄色", }));
        ccbSinGraph_Color.setDoubleBuffered(false);
        ccbSinGraph_Color.setBorder(null);
        iCbSinGraph_Color_Width = ccbSinGraph_Color.getMinimumSize().width;
        iCbSinGraph_Color_Height = ccbSinGraph_Color.getMinimumSize().height;

        cbtSinGraph_Make = new JButton( );
        cbtSinGraph_Make.setText("Make");
        System.out.println(
            "cbtSinGraph_Make.getWidth()="+Integer.toString(cbtSinGraph_Make.getWidth())+"; "+
            "cbtSinGraph_Make.getHeight()="+Integer.toString(cbtSinGraph_Make.getHeight())+"; "+
            "cbtSinGraph_Make.getMinimumSize().width="+Integer.toString(cbtSinGraph_Make.getMinimumSize().width)+"; "+
            "cbtSinGraph_Make.getMinimumSize().height="+Integer.toString(cbtSinGraph_Make.getMinimumSize().height)+"; "+
            "");
        iBtSinGraph_Make_Width = cbtSinGraph_Make.getMinimumSize().width;
        iBtSinGraph_Make_Height = cbtSinGraph_Make.getMinimumSize().height;
        cbtSinGraph_Make.addMouseListener(new MouseAdapter() {
            public void mouseReleased(MouseEvent event) {
                if(null!=oCanvas){
                    oCanvas.SinGraph_Make( );
                }
            }
        });

        iCanvasWidth = 500;
        iCanvasHeight = 300;

        iLayoutX = 0; iLayoutY = 0;
        getContentPane().add(ccbSinGraph_WaveQnt);
        ccbSinGraph_WaveQnt.setBounds(iLayoutX,iLayoutY, iCbSinGraph_WaveQnt_Width, iCbSinGraph_WaveQnt_Height);

        iLayoutX = iLayoutX+iCbSinGraph_WaveQnt_Width; // iLayoutY = 0;
        getContentPane().add(ccbSinGraph_Color);
        ccbSinGraph_Color.setBounds(iLayoutX,iLayoutY, iCbSinGraph_Color_Width, iCbSinGraph_Color_Height);

        iLayoutX = iLayoutX+iCbSinGraph_Color_Width; // iLayoutY = 0;
        getContentPane().add(cbtSinGraph_Make);
        cbtSinGraph_Make.setBounds(iLayoutX,iLayoutY, iBtSinGraph_Make_Width, iBtSinGraph_Make_Height);

        iLayoutX = 0; iLayoutY = iLayoutY+iBtSinGraph_Make_Height;
        oCanvas = new CanvasObj(iLayoutX, iLayoutY, iCanvasWidth, iCanvasHeight);
        getContentPane().add(oCanvas);
        // oCanvas.setVisible(true);

        this.setSize(iCanvasWidth, iBtSinGraph_Make_Height+iCanvasHeight);

        if( lApplication ){
            System.out.println("if(lApplication)");
            oMainAppFrame.setPreSize(oCanvas.getSize( ));
            System.out.println("PanelWidth="+oCanvas.getSize( ).getWidth());
            System.out.println("PanelHeight="+oCanvas.getSize( ).getHeight());
        }
        System.out.println("AppletWidth="+getSize( ).getWidth());
        System.out.println("AppletHeight="+getSize( ).getHeight());
    }
    public void start(){
        System.out.println("start( );");

        repaint();

    }
    public void stop(){
        System.out.println("stop( );");
    }
    public void destroy(){
        System.out.println("destroy( );");
    }

    class SinGraph {

        int iWidth;
        int iHeight;
        int iMoveStride = 3;
        // volatile:最適化の抑制.
        volatile int iMoveDistance = 0;
        int iWaveQnt = 1;
        double vdWaveHeightRate = iWaveQnt;
        int iWaveStep = 0;
        int iWaveWidth;
        int iWaveHeight;
        Color oColor = Color.BLUE;
        double vdRadian;
        double vdWaveWidth,vdWaveHeight;
        double vdWaveX1,vdWaveX2;
        double vdWaveY1,vdWaveY2;
        double vdRate,vdRateInt;

        SinGraph( int iW, int iH, int iWQ, Color oC ){
            // コンストラクター自体には synchronized 修飾子を付与できないので、
            // synchronized ブロックで囲う。
            synchronized(this){
                // iMoveDistance に対する競合(描画中の変更)を回避する。
                // 対象は SinGraph("自分")内の変数です。
                iWidth = iW;
                iHeight = iH;
                iWaveQnt = iWQ;
                vdWaveHeightRate = iWaveQnt; // sin グラフの高さの調整。
                oColor = oC;
            }
        }

        synchronized void Draw(Graphics oGraphic){
            // iMoveDistance に対する競合(描画中の変更)を回避する。
            // 対象は SinGraph("自分")内の変数です。
            Graphics2D oGraphic2D = (Graphics2D)oGraphic;

            oGraphic2D.setColor(oColor);
            vdWaveWidth = (double)iWidth/iWaveQnt;
            vdWaveHeight = vdWaveWidth/(2*Math.PI)*vdWaveHeightRate;
            iWaveStep = 0;
            vdWaveX1 = -1; vdWaveX2 = -1;
            while( iWaveStep<iWidth ){ // true / false
                vdWaveX1 = vdWaveX2;
                vdWaveY1 = vdWaveY2;
                vdRate = (double)
                    (iWaveStep+iWidth-iMoveDistance)/iWidth*iWaveQnt;
                vdRateInt = Math.floor(vdRate);
                vdRate = vdRate-vdRateInt;
                vdWaveX2 = iWaveStep;
                vdRadian = 2*Math.PI*vdRate;
                vdWaveY2 = iHeight/2-Math.sin(vdRadian)*vdWaveHeight;
                iWaveStep++;
                if(0<=vdWaveX1){
                    oGraphic2D.drawLine(
                        (int)Math.round(vdWaveX1), (int)Math.round(vdWaveY1),
                        (int)Math.round(vdWaveX2), (int)Math.round(vdWaveY2));
                }
            }
        }

    }

    class CanvasObj extends JPanel {
        // Java2 には JCanvas は存在しないので、
        // グラフィックの描画には JPanel を継承して Canvas の代わりに使う。
        Thread oThread;
        // SinGraph oSinGraph;
        int iWidth;
        int iHeight;
        ArrayList<SinGraph> dl1oSinGraph = new ArrayList<SinGraph>( );

        CanvasObj(int x, int y, int w, int h ) {
            super( );
            System.out.println("oApplet:CanvasObj:");

            setBounds(x, y, w, h);
            iWidth = getWidth( );
            iHeight = getHeight( );
            SinGraph_Make( );

            oThread = new Thread( ){
                @Override
                public void run( ){
                    while( true ){ // true / false
                        repaint();
                        try {
                            Thread.sleep(50); // ←50ミリ秒の sleep。
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        for( SinGraph oSinGraph : dl1oSinGraph.toArray(new SinGraph[0])){
                            // ↑この「new SinGraph[0]」の部分は要素がゼロ個の配列を指定しなければならないらしい。
                            // それにより指定された型と同一の型が返されるらしい。
                            synchronized(oSinGraph) {
                                // SinGraph内の iMoveDistance変数に対する競合(描画中の変更)を回避する。
                                // 対象は SinGraph内の変数なので、当然 ここは"他人"となります。
                                oSinGraph.iMoveDistance = oSinGraph.iMoveDistance+oSinGraph.iMoveStride;
                                if( iWidth<=oSinGraph.iMoveDistance ){ oSinGraph.iMoveDistance = oSinGraph.iMoveDistance-iWidth; }
                            }
                        }

                    }

                }
            };
            oThread.start( );

        }

        void SinGraph_Make( ){
            dl1oSinGraph.add(new SinGraph(iWidth, iHeight,
               ccbSinGraph_WaveQnt.getSelectedIndex( )+1,
               d1oCbSinGraph_ColorSets[ccbSinGraph_Color.getSelectedIndex( )]));
        }

        @Override
        public void paint(Graphics oGraphic){
            Graphics2D oGraphic2D = (Graphics2D)oGraphic;
            // ↑(JPanel を継承しているので)ここの Graphics の実態は Graphics2D となるから、
            // キャストしてやれば Graphics2D が使える.

            oGraphic2D.setBackground(Color.BLACK);
            oGraphic2D.clearRect(0, 0, iWidth, iHeight);

            oGraphic2D.setColor(Color.WHITE);
            oGraphic2D.drawLine(0, iHeight/2, iWidth, iHeight/2);

            for( SinGraph oSinGraph : dl1oSinGraph.toArray(new SinGraph[0])){
                // ↑この「new SinGraph[0]」の部分は要素がゼロ個の配列を指定しなければならないらしい。
                // それにより指定された型と同一の型が返されるらしい。
                oSinGraph.Draw(oGraphic2D);
            }
        }
         @Override
         public void update(Graphics oGraphic){
             System.out.println("updat( );");
             // Java のバージョンによって違うかもしれないが、
             // 動的なグラフィック表示をする場合は
             // update メソッドが存在しないと表示のチラツキの原因になる場合がある.
            paint(oGraphic);
         }
    }

    static class MainAppFrameObj extends JFrame implements Runnable {
        // JApplet oApplet;
        Thread oAppThread;
        public MainAppFrameObj( ) {
           super("Application frame.");
           //setVisible(false);
           System.out.println("Construct:Application frame window.");

           // oApplet = oEntApplet; // new JAppletcation();

           addWindowListener(
               new WindowAdapter(){
                   public void windowClosing(WindowEvent event){
                       // ユーザーがウインドウを閉じようとした時].
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowClosing.");
                           Close();
                       }
                   }
               }
           );
           addWindowListener(
               new WindowAdapter(){
                   public void windowClosed(WindowEvent event){
                       // ウインドウが閉じた時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowClosed.");

                       }
                   }
               }
           );
           addWindowListener(
               new WindowAdapter(){
                   public void windowDeiconified(WindowEvent event){
                       // ウィンドウが最小化された状態から通常の状態に変更された時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("MainAppFrameObj:WindowEvent:windowDeiconified.");

                           oMainApp.repaint();
                       }
                   }
               }
           );
           addComponentListener(
               new ComponentAdapter(){
                   public void componentResized(ComponentEvent event){
                       // コンポーネントのサイズが変更された時.
                       Object oSource = event.getSource();
                       if (oSource == MainAppFrameObj.this){
                           System.out.println("ComponentEvent:componentResized.");

                           System.out.println("MainAppFrameObj: "+
                           "width="+Integer.toString(MainAppFrameObj.this.getSize( ).width)+"; "+
                           "Height="+Integer.toString(MainAppFrameObj.this.getSize( ).height)+"; "+
                               "");
                           oMainApp.repaint();
                       }
                   }
               }
           );
           getContentPane().add(oMainApp,"Center");

           oAppThread = new Thread(this);

        }
        public synchronized void setPreSize(Dimension oSize){
            // dispose();
            getContentPane().setPreferredSize(oSize);
            pack();
            setVisible(true);
            requestFocus();
        }
        public synchronized void run(){
            System.out.println("Open:Application frame window.");
            oMainApp.init();
            oMainApp.start();
            oMainApp.repaint();
            try{
                wait();
            }
            catch(InterruptedException e){
                e.printStackTrace();
            }
            oMainApp.stop();
            oMainApp.destroy();
            oAppThread = null;

        }
        public synchronized void Close(){
            System.out.println("Close:Application frame window.");
            dispose();
            notify();
        }
    }

}
 

test

 投稿者:amanojaku  投稿日:2012年 2月23日(木)18時12分0秒
返信・引用
  test  

掲示板が完成しましたキラキラ

 投稿者:teacup.運営  投稿日:2012年 2月23日(木)18時02分8秒
返信・引用
  ご利用ありがとうございます。

teacup.掲示板は
ダイヤスレッド作り放題右上
ダイヤ画像・動画・音楽の投稿OK
ダイヤケータイ絵文字が使えるv▽v
ダイヤRSS対応ヒラメイタ!
ダイヤお絵描き機能付きえんぴつ
ダイヤかわいいケータイテンプレハートx2

足跡足あと帳はコチラ
スレッド内容は管理画面内「スレッドの管理」から編集できます。
 

レンタル掲示板
/1