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
Create original Tool for Processing 3.0.2
basically, how to create Processing 3.0.2 Tool is the same as 2.x
Environment
- Windows 10 (64 bit)
- Eclipse (Mars)
- Processing 3.0.2
- JDK 1.8 (Java SE 8)
- processing-tool-template(from GitHub)
Step
Download the zip: processing-tool-template (v3.0.2) https://github.com/processing/processing-tool-template/releases (version is 3.0.2 ...maybe go well !!!)
Eclipse: new Java Project ("testTools": my case) -> import archive file (zip)
Copy core.jar & pde.jar -> Paste in : {your project name}>src>processing-tool-templates-3.0.2>lib
- core.jar (Processing-3.0.2>core>library)
- pde.jar (Processing-3.0.2>lib)
right click on core.jar & pde.jar -> Build Path>Add to Build Path (seemed to move)
Edit build.properties (src>processing-tool-templates-3.0.2>resources)
path is my case- sketch book path (Default: ${user.home}\Documents\Processing)
- sketchbook.location=${user.home}\Documents\Processing3
- core.jar path
- classpath.local.location=${user.home}\Downloads\PROGRAM\Processing\processing-3.0.2\core\library
- libraies path (Default: ${sketchbook.location}/libraries)
- classpath.libraries.location=${sketchbook.location}/libraries
- java.target.version=1.8
- (if you want) other property: Tool name, Author, Your URL ...
- sketch book path (Default: ${user.home}\Documents\Processing)
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 in Ant tab -> close Processing (while building)
- push Run button in Ant tab -> watch console (build finished in about 5 sec)
- if (BUILD SUCCESSFUL) -> HelloTool is in Processing (PDE), else check build.properties and .jar file
- show Ant tab
Let's edit
HelloTool.java (src>processing-tool...>src>template>tool>HelloTool.java)
example : when you select the HelloTool, print all your code in PDE
package template.tool; import processing.app.Base; import processing.app.tools.Tool; import processing.app.ui.Editor; public class HelloTool implements Tool { // class name = project.name (build.properties) Base base; public void init(Base base) { this.base = base; // Store a reference to the Processing application itself } public String getMenuTitle() { // displayed with tools list return "##tool.name##"; } public void run() { Editor editor = base.getActiveEditor(); // Get the currently active Editor to run the Tool on it System.out.println("Hello Tool. ##tool.name## ##tool.prettyVersion## by ##author##"); // <- build.property for (int i = 0; i < editor.getLineCount(); i++){ String s = editor.getLineText(i); System.out.println(i + " : " + s); } } }