前にMode Template for Processing 2.xを使ってProcessing 3.0.2で使えるMode作ったけど,なぜか動かなくなってたのでこの際だから3.x用作った
基本は2.xのまま借りてきている
少し直したのと,前はEclipseで作ってたけどIntelliJが好きだから,移行してIntelliJでつくった
ここからメンテナンスするかと言われればたぶんしない
String.prepend, String.append, String.minusの話
小ネタだけど,String関係で便利なやつ第2弾
解説すると,String.prepend(String)で前に追加,String.append(String)で後に追加
String - IntでInt文字数分削除
下の例だと,文字”STRING”にprepend("pre")で"preSTRING"
そのあとappend("app")で"preSTRINGapp"
最後にs - 1で最後の1文字を削除して"preSTRINGap"
operator fun String.minus(num: Int) = this.substring(0, this.length - num) fun String.prepend(s: String) = this.javaClass.getDeclaredField("value").let { it.isAccessible = true it.set(this, s.toCharArray() + this.toCharArray()) this } fun String.append(s: String) = this.javaClass.getDeclaredField("value").let { it.isAccessible = true it.set(this, this.toCharArray() + s.toCharArray()) this } fun main(args: Array<String>) { val s = "STRING" s.prepend("pre").append("app") println(s - 1) // -> preSTRINGap }
Stringに掛け算の演算子オーバーロードしたら捗った
最近Kotlinのoperatorとかinfix触っててよかった話をひとつ.
Stringで+を使うと結合になるわけだけど,なぜか*がない
なのでString.timesを作った
String * Int, String *= Intって感じ
これでいちいちfor回したりがなくなるので結構便利
デフォルトに組み込んでほしい^~
fun main(args: Array<String>) { operator fun String.times(num: Int): String { var s = "" for (i in 0..num) s += this return s } println("hell, " * 2 + "hell)//hell, hell, hell }
ProcessingのTemplate Modeでビルドするときにスケッチ名とコードを取得する
JavaModeを継承しているTemplateModeでhandleLaunchメソッドをOverrideする
メインのコードはhandleLaunchメソッドの中で,こんな感じ
String sketchName = sketch.getName(); System.out.println("handleLaunch: " + sketchName); Editor editor = base.getActiveEditor(); String s = ""; for (int i = 0; i < editor.getLineCount(); i++){ s += editor.getLineText(i); } System.out.println(s);
TemplateMode全体
package com.mydomain.mymode; import java.io.File; import processing.app.*; import processing.app.ui.*; import processing.mode.java.*; import processing.mode.java.runner.Runner; public class TemplateMode extends JavaMode { public TemplateMode(Base base, File folder) { super(base, folder); } /** * Return the pretty/printable/menu name for this mode. This is separate * from the single word name of the folder that contains this mode. It could * even have spaces, though that might result in sheer madness or total * mayhem. */ @Override public String getTitle() { return "Template"; } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . // Create a new editor associated with this mode. // @Override // public Editor createEditor(Base base, String path, EditorState state) { // return null; // } // Returns the default extension for this editor setup. // @Override // public String getDefaultExtension() { // return null; // } // Returns a String[] array of proper extensions. // @Override // public String[] getExtensions() { // return null; // } // Get array of file/directory names that needn't be copied during "Save As". // @Override // public String[] getIgnorable() { // return null; // } /** * Retrieve the ClassLoader for JavaMode. This is used by Compiler to load * ECJ classes. Thanks to Ben Fry. * @return the class loader from java mode */ // @Override // public ClassLoader getClassLoader() { // for (Mode m : base.getModeList()) { // if (m.getClass() == JavaMode.class) { // JavaMode jMode = (JavaMode) m; // return jMode.getClassLoader(); // } // } // return null; // badness // } /** Handles the standard Java "Run" or "Present" */ @Override public Runner handleLaunch(Sketch sketch, RunnerListener listener, final boolean present) throws SketchException { String sketchName = sketch.getName(); System.out.println("handleLaunch: " + sketchName); Editor editor = base.getActiveEditor(); String s = ""; for (int i = 0; i < editor.getLineCount(); i++){ s += editor.getLineText(i); } System.out.println(s); JavaBuild build = new JavaBuild(sketch); String appletClassName = build.build(true); if (appletClassName != null) { final Runner runtime = new Runner(build, listener); new Thread(new Runnable() { public void run() { // these block until finished if (present) runtime.present(null); else runtime.launch(null); } }).start(); return runtime; } return null; } }
KotlinのAnyを引数に持つ同名関数の優先順位について
fun(Any) < fun(String)
Anyが引数になってる関数よりStringとか限定された方が優先されるっぽい?
fun main(args: Array<String>) { p("hell") // -> str p(10) // -> int p(10.0) // -> any } fun p(any: Any) = println("$any : any") fun p(i: Int) = println("$i : int") fun p(s: String) = println("$s : str")
Processing 3.0.2で動く自作ライブラリ(.jar)を作ろう
初めに
プロジェクト作成
Processing が3.0.2なので,JDKは1.8を使用
IDEA: File>New>ProjectでtestLibを作成
- その中のsrcにtestPackageを作成
- またその中にJavaClass.javaを作成
今回はPApppletを扱えるライブラリにしたいので, IDEA: File>Project Structure>Librariesで+を押してcore.jar(Processing3.0.2>core>library)を入れる
Project表示ではこんな感じ
JavaClass.javaを書いてみる
最初にProcessing側からPAppletをもらってきて,bgというメソッドが呼ばれたらPAppletのバックグラウンドの色を変えるというだけのクラス.
package testPackage; import processing.core.*; public class JavaClass { PApplet pa; public JavaClass(PApplet pa) { this.pa = pa; } public void bg(int color){ pa.background(color); } public static void main(String[] args) { } }
.jar 作り
- IDEA: File>Project Structure>Artifacts
- +押す>JAR >From modules with dependencies
- Main ClassにJavaClassを選択する main()がないとかクラスに不備があると表示されないことがある
- JavaClass.javaのエディット画面に戻り,IDEA: Build>Build Artifactsからビルド
- testLib>out>artifacts>testLib_jarファイルのなかにtestLib.jarができているはず
Processingで使用
できた.jarを自分のスケッチにドラッグ&ドロップして下のコードをProcessingで書くだけ
import testPackage.JavaClass; JavaClass j = new JavaClass(this); void setup() { size(300, 300); background(255); } void draw() { } void mousePressed() { j.bg(color(255, 0, 0)); }
ライブラリ作りの参考:
Processingのライブラリを作る - gutugutu3030
IntelliJ IDEAでの .jarの作り方の参考:
Create original Mode for Processing 3.0.2
Original Mode extends Java Mode (Default Mode)
similar when create Tool
refer: ProcessingのModeを作る - gutugutu3030
Environment
- Windows 10 (64 bit)
- Eclipse (Mars)
- Processing 3.0.2
- JDK 1.8 (Java SE 8)
- Mode Template for Processing 2.0 (for 2.0...)
Step
Download the zip
TemplateMode-master.zip (=archive file) from github
Create new project
Eclipse: new Java Project ("testMode": my case) -> import archive file (zip)
Copy jar files
Copy core.jar & pde.jar & many jar files(JavaMode.jar, jdi.jar, ...) -> Paste in : {your project name}>src>TemplateMode-master>lib - core.jar (Processing-3.0.2>core>library) - pde.jar (Processing-3.0.2>lib) - *.jar (Processing-3.0.2>modes>java>mode) = (18 jar files)
Add to Build Path
- select all jar files(TemplateMode-master>lib)
- right click
- Build Path>Add to Build Path (seemed to move)
Edit build.xml (src>TemplateMode-master)
path is my case
Edit at least
- JDK version
- core.jar path
- pde.jar path
- processing.exe path (Processing-3.0.2)
- (if you want) Mode name, Version ...
<!-- java version --> <property name="java.target.version" value="1.8" /> <!-- location of processing jars (core.jar, pde.jar, ..) --> <property name="processing.classes.core" location="${user.home}\\Downloads\\PROGRAM\\Processing\\processing-3.0.2\\core\\library" /> <property name="processing.classes.pde" location="${user.home}\\Downloads\\PROGRAM\\Processing\\processing-3.0.2\\lib" /> <!-- folder to install modes in (probably a folder called "modes" inside your sketchbook folder) --> <property name="processing.modes" location="${user.home}\\Documents\\Processing3\\modes"/> <!-- path to your processing executable. --> <property name="processing.executable" location="${user.home}\\Downloads\\PROGRAM\\Processing\\processing-3.0.2\\processing.exe"/>
Change import statements
Edit TemplateMode.java (src>TemplateMode-master>src>com>mydomain>mymode)
//package com.mydomain.mymode; import java.io.File; import processing.app.Base; //import processing.app.Editor; // 2.x import processing.app.ui.Editor; // 3.0.2 //import processing.app.EditorState; // 2.x import processing.app.ui.EditorState; // 3.0.2 import processing.app.Mode; import processing.mode.java.JavaMode; public class TemplateMode extends JavaMode { public TemplateMode(Base base, File folder) { super(base, folder); } /** * Return the pretty/printable/menu name for this mode. This is separate * from the single word name of the folder that contains this mode. It could * even have spaces, though that might result in sheer madness or total * mayhem. */ @Override public String getTitle() { return "Mode Template"; } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . // Create a new editor associated with this mode. // @Override // public Editor createEditor(Base base, String path, EditorState state) { // return null; // } // Returns the default extension for this editor setup. // @Override // public String getDefaultExtension() { // return null; // } // Returns a String[] array of proper extensions. // @Override // public String[] getExtensions() { // return null; // } // Get array of file/directory names that needn't be copied during "Save As". // @Override // public String[] getIgnorable() { // return null; // } /** * Retrieve the ClassLoader for JavaMode. This is used by Compiler to load * ECJ classes. Thanks to Ben Fry. * @return the class loader from java mode */ // @Override // public ClassLoader getClassLoader() { // for (Mode m : base.getModeList()) { // if (m.getClass() == JavaMode.class) { // JavaMode jMode = (JavaMode) m; // return jMode.getClassLoader(); // } // } // return null; // badness // } }
Ant build (Eclipse)
- show Ant tab
- Eclipse: Window>show View>other -> click Ant -> Ant tab appear (int the lower window)
- build.xml (src>resources) -> drag & drop on Ant tab -> close Processing (while building)
- push Run button in Ant tab -> watch console (build finished in about 2 sec)
- if (BUILD SUCCESSFUL) -> Template Mode is in your Processing (PDE), else check build.xml and .jar file