« 星図描画 | メイン | Basic Activity 備忘録 »

java

java の interface(CallBack)備忘録

 C言語の関数ポインタを java で実装するパターン備忘録。
 親ウィンドウからダイアログを呼び出し、ダイアログから親ウィンドウへ値を返す、よくあるシチュエーション。

FrameMain.jarFrameMain.jar 15,218kB(ソース含む)

下記 どのSTEPでも同じ動作。...▼
●STEP1 最初は 1クラスファイルだけの無名クラスで構成した実装例。
FrameMain.java
import java.awt.*;

class FrameMain extends Frame{
	Label label= new Label( "Label of FrameMain", Label.CENTER );

	class DialogSample extends Dialog{
		class ScrollbarSample extends Scrollbar{
			ScrollbarSample(){
				super( Scrollbar.HORIZONTAL );
				addAdjustmentListener( new java.awt.event.AdjustmentListener(){
					@Override
					public void adjustmentValueChanged( java.awt.event.AdjustmentEvent e ){
						label.setText( String.valueOf( ScrollbarSample.this.getValue() ) );
					}
				} );
			}
		}

		DialogSample( Frame fOwner ){
			super( fOwner, true );//modal
			addWindowListener( new java.awt.event.WindowAdapter(){
				public void windowClosing( java.awt.event.WindowEvent e ){
					setVisible( false );
				}
			} );
			add( "Center", new ScrollbarSample() );
			setSize( 200, 60 );
			setVisible( true );
		}
	}

	class ButtonMain extends Button{
		ButtonMain( String s ){
			super( s );
			addActionListener( new java.awt.event.ActionListener(){
				@Override
				public void actionPerformed( java.awt.event.ActionEvent e ){
					new DialogSample( FrameMain.this );
				}
			} );
		}
	}

	FrameMain(){
		addWindowListener( new java.awt.event.WindowAdapter(){
			public void windowClosing( java.awt.event.WindowEvent e ){
				System.exit( 0 );
			}
		} );
		add( label );
		add( "South", new ButtonMain( "Dialog Sample Button" ) );
		setSize( 400 , 300 );
		setVisible( true );
	}

	public static void main( String[] args ){
		new FrameMain();
	}
}
●STEP2 ダイアログクラスファイルを分離した実装例。
 呼び先 DialogSample が呼び元 FrameMain の label を直接操作。呼び先が呼び元の操作対象を知っていなければならないので、呼び先を汎用的に再利用しにくい。
FrameMain.java
import java.awt.*;

class FrameMain extends Frame{
	public Label label= new Label( "Label of FrameMain", Label.CENTER );

	class ButtonMain extends Button{
		ButtonMain( String s ){
			super( s );
			addActionListener( new java.awt.event.ActionListener(){
				@Override
				public void actionPerformed( java.awt.event.ActionEvent e ){
					new DialogSample( FrameMain.this );
				}
			} );
		}
	}

	FrameMain(){
		addWindowListener( new java.awt.event.WindowAdapter(){
			public void windowClosing( java.awt.event.WindowEvent e ){
				System.exit( 0 );
			}
		} );
		add( label );
		add( "South", new ButtonMain( "Dialog Sample Button" ) );
		setSize( 400 , 300 );
		setVisible( true );
	}

	public static void main( String[] args ){
		new FrameMain();
	}
}
DialogSample.java
import java.awt.*;

class DialogSample extends Dialog{
	Frame fOwner;

	class ScrollbarSample extends Scrollbar{
		ScrollbarSample(){
			super( Scrollbar.HORIZONTAL );
			addAdjustmentListener( new java.awt.event.AdjustmentListener(){
				@Override
				public void adjustmentValueChanged( java.awt.event.AdjustmentEvent e ){
//▼▼▼
					((FrameMain)DialogSample.this.fOwner).label.setText( String.valueOf( ScrollbarSample.this.getValue() ) );
//▲▲▲
				}
			} );
		}
	}

	DialogSample( Frame fOwner ){
		super( fOwner, true );//modal
//▼▼▼
		this.fOwner= fOwner;
//▲▲▲
		addWindowListener( new java.awt.event.WindowAdapter(){
			public void windowClosing( java.awt.event.WindowEvent e ){
				setVisible( false );
			}
		} );
//▼▼▼
		add( "Center", new ScrollbarSample() );
//▲▲▲
		setSize( 200, 60 );
		setVisible( true );
	}
}
●STEP3 java の インターフェース(interface) を使った コールバック(callback)実装例。
呼び先 DialogSample のインターフェース CallBack の関数 onChange() を、 呼び元 FrameMain に実装(implements)させ これを呼び出すことで情報を返す。
FrameMain.java
import java.awt.*;

//▼▼▼
class FrameMain extends Frame implements DialogSample.CallBack{
	public void onChange( DialogSample dialogSample ){
		label.setText( String.valueOf( dialogSample.scrollbarSample.getValue() ) );
	}
//▲▲▲

	public Label label= new Label( "Label of FrameMain", Label.CENTER );

	class ButtonMain extends Button{
		ButtonMain( String s ){
			super( s );
			addActionListener( new java.awt.event.ActionListener(){
				public void actionPerformed( java.awt.event.ActionEvent e ){
					new DialogSample( FrameMain.this );
				}
			} );
		}
	}

	FrameMain(){
		addWindowListener( new java.awt.event.WindowAdapter(){
			public void windowClosing( java.awt.event.WindowEvent e ){
				System.exit( 0 );
			}
		} );
		add( label );
		add( "South", new ButtonMain( "Dialog Sample Button" ) );
		setSize( 400 , 300 );
		setVisible( true );
	}

	public static void main( String[] args ){
		new FrameMain();
	}
}
DialogSample.java
import java.awt.*;

class DialogSample extends Dialog{
//▼▼▼
	public interface CallBack{
		abstract void onChange( DialogSample d );
	}
	CallBack callBack= null;
//▲▲▲

//▼▼▼
	ScrollbarSample scrollbarSample= new ScrollbarSample();//呼び元から参照させる
//▲▲▲

	class ScrollbarSample extends Scrollbar{
		ScrollbarSample(){
			super( Scrollbar.HORIZONTAL );
			addAdjustmentListener( new java.awt.event.AdjustmentListener(){
				public void adjustmentValueChanged( java.awt.event.AdjustmentEvent e ){
//▼▼▼
					callBack.onChange( DialogSample.this );
//▲▲▲
				}
			} );
		}
	}

	DialogSample( Frame fOwner ){
		super( fOwner, true );//modal
//▼▼▼
		callBack= (CallBack)fOwner;//CallBack implemented Frame
//▲▲▲
		addWindowListener( new java.awt.event.WindowAdapter(){
			public void windowClosing( java.awt.event.WindowEvent e ){
				setVisible( false );
			}
		} );
//▼▼▼
		add( "Center", scrollbarSample );
//▲▲▲
		setSize( 200, 60 );
		setVisible( true );
	}
}
呼び先 DialogSample は、呼び元 FrameMain の label を参照せず(知らなくとも)情報を返すことを実現。DialogSample のインターフェースを実装さえすれば DialogSample を再利用可能に。lambda expression(ラムダ式)、annotation()アノテーション、swing(スウィング) すら使っていない基本形。

トラックバック

このエントリーのトラックバックURL:
https://www.remix.asia/cgi/mt/mt-tb.cgi/7748

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)