[Work/Class/Java with Processing/4_SwingInProcessing]

アート系学生のためのJAVA with Processing - その4-6 Processingのウィンドウをもう一つ作り,そちらをメイン表示にする.

導入

前項でコントーラを分離したので,今度は表示部分を別のProcessingのWindow,つまりPAppletを継承したクラスによって定義する.

注意点はsize関数である.(Processing3以降)PAppletを継承したクラスを定義すると,void setup()中でウィンドウサイズを指定するsize()関数が使えないので,別にpublic void settings()という関数を用意し,その中でsize()関数を実行する.

それ以外通常void setup()関数内で実行する関数は普通に使うことができる.

コード

//SwingInProcessing_YATP5Window
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

String actionCommand;
boolean inStopMode;

// インナークラスとして定義するProcessing第2のウィンドウ
YATP5Window yatP5Window;
// 前項と同じくインナークラスとして定義するコントロールウィンドウ
ControllWindow controllWindow;

void setup(){
  // not use this PApplet Class
  // 本来のProcessingのメインウィンドウであるこの大元のPAppletを継承したクラスは使わない

  // PAppletを起動するのに必要な引数Stringの配列を指定.ここではウィンドウの名前だけ
  String[] args = {"Child Window"};
  
  // PAppletを継承したクラス,Processing第2のウィンドウのオブジェクトインスタンスを生成
  yatP5Window = new YATP5Window();

  // Static Method of PApplet Class 
  // to run child window as sketch
  // PAppletを継承したクラスのオブジェクトインスタンス化後の初期化する静的メソッド
  // ここでは名前とオブジェクトインスタンスを渡す
  PApplet.runSketch(args, yatP5Window);
  
  // 前項と同じくコントローラウィンドウの生成
  controllWindow = new ControllWindow(this);
  inStopMode = true;
  
  // Only Initialize Child Windows 
  // in this Parent Window setup()

  // Processing本来のウィンドウのsetup()では他に何もしない
}

void draw(){
  // Nothing to Draw in Parent Window
  // draw()でも何もしない
}

void eventsCalledFromControllWindow(){
  // コントーラがイベントを検知した時に呼ぶ関数
  if(actionCommand.equals("startButton_Pushed"))
    inStopMode = false;
  else if(actionCommand.equals("stopButton_Pushed"))
    inStopMode = true;
}

class YATP5Window extends PApplet{
  // Processingの第2のウィンドウ PAppletを継承して作る
  int xPos, yPos;

  YATP5Window(){
    // Constructor
    // コンストラクタ
    super();

    // 親クラスのコンストラクタを呼ぶだけならば,
    // コンストラクタの定義は実は必要がない
    // 配列等,プリミティブ型の変数以外のインスタンス化を伴う場合,コンストラクタが必要
  }
  
  @Override
  public void settings(){
    // For second PApplet window
    // not write size() in "void setup()"
    // write into "public void settings()"
    // PAppletやそれを継承したクラスのオブジェクトが複数存在する場合,
    // ウィンドウサイズを指定するsize()関数だけは,本来のsetup()内ではなく,
    // settings()内に書かなければならない.
    // 複数PAppletウィンドウがある場合,
    // 元のメインスケッチクラスでも,settings()内でthis.size()を実行しなければならない
    this.size(640, 480);
  }
  
  @Override
  void setup(){
    //それ以外は通常のProcessingのsetup関数を書く
    this.colorMode(RGB, 255);
    this.background(255, 255, 255);
    this.frameRate(10);
    inStopMode = true;
  }
  
  @Override
  void draw(){
    this.fill(255, 255, 255, 60);
    this.rect(0, 0, this.width, this.height);
    
    this.fill(60, 60, 60, 0);
    this.ellipse(this.xPos, this.yPos, 30, 30);
    if(!inStopMode){
     this.xPos += 10;
     this.yPos += 10;
    }
  }
}

class ControllWindow extends JFrame implements ActionListener{
  // 前項のコントローラウィンドウのまま
  JButton startButton, stopButton;
  JTextField textField;
  Container contentPane; 

  SwingInProcessing_YATP5Window parentWindow;
  
  ControllWindow(SwingInProcessing_YATP5Window parentWindow){
   //Constructor 
   super("Controll window");
   // Set the Parent Window
   this.parentWindow = parentWindow;
   
   this.setSize(320, 240);
   contentPane = this.getContentPane();
   startButton = new JButton("Start");
   startButton.setActionCommand("startButton_Pushed");
   startButton.addActionListener(this);
   contentPane.add(startButton, BorderLayout.NORTH);
   JButton stopButton = new JButton("Stop");
   stopButton.setActionCommand("stopButton_Pushed");
   stopButton.addActionListener(this);
   contentPane.add(stopButton, BorderLayout.SOUTH);
   textField = new JTextField("Controll Panel Text Field");
   contentPane.add(textField, BorderLayout.CENTER);
  
   this.setVisible(true);
  }
  
  @Override
  public void actionPerformed(ActionEvent e){
    actionCommand = e.getActionCommand();
    textField.setText(actionCommand);
    parentWindow.eventsCalledFromControllWindow();
  }
}
SwingInProcessing_YATP5Window.pdeの実行結果.前項で作ったコントロール用のウィンドウに加え,Processingの2番目のウィンドウが表示され,そこに描画されている.

前項で作ったコントロール用のウィンドウに加え,PAppletクラスを継承して作ったProcessingの2番目のウィンドウが表示され,そこにアニメーションが表示される.本来のProcessingで作られるウィンドウには何も表示しない.

(Processingは大元のmain関数がPAppletであり,main関数が入っているウィンドウを消すのにはさらなる手間が必要であるため,とりあえず表示させておく)