SampleInpl.java
やはり、ニーズが高いのは「GRINEditを超動的プログラムにすること」ではなくて「使いやすいレイアウトエンジン」なのだと思います。GRINEditは、JythonでSWTを叩いてメニューを作る(実行時にメニューの追加もできちゃう)超動的プログラムへの道を進んでいるのですが、これをさらにマニアックに掘り下げることは市場のニーズに合わないと思います。誰かが作ったソフトウェアに組み込んでもらうことを考えて、使いやすいライブラリへの道を進もうと思います。そういうわけで今日はあっさりシンプルなものを一つ作ってみることにしました。
- Swing (JFrameとJButtonだけ)
- 整形の対象はJButtonそのもの(つまりVertexを継承させたりJButtonクラスに手を加えたりはしない。)
- 最小限(拡大縮小なし、平行移動なし、ドラッグによる頂点の移動なし、辺なし)
- 最初1個だけボタンがあり、クリックするとそのボタンが2つに増える。ボタンたちはお互いに反発しあう。
こういうシンプルなものを92行で書いてみました。
package test.hoge;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JButton;
import javax.swing.JFrame;
import org.nishiohirokazu.graph.Vertex;
import org.nishiohirokazu.grinEdit.Mediator;
public class SampleImpl extends JFrame implements ActionListener {
private Mediator med;
private ArrayList buttonList = new ArrayList();
private ArrayList vertexList = new ArrayList();
public static void main(String[] args) {
JFrame frame = new SampleImpl();
frame.setSize(300, 200);
frame.setVisible(true);
}
public SampleImpl() {
med = Mediator.getInstance();
med.repulsionK = 1;
med.repulsionRadius = 20;
addNewVertex(50.0, 50.0);
setLayout(null);
Timer t = new Timer();
TimerTask tt = new TimerTask() {
public void run() {
updateScreen();
}
};
t.schedule(tt, 0, 10);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent arg) {
if (arg.getActionCommand().equals("AddNewVertex")) {
JButton b = (JButton) arg.getSource();
Rectangle r = b.getBounds();
addNewVertex(r.x, r.y);
}
}
public void addNewVertex(double x, double y){
Random r = new Random();
JButton b = new JButton();
b.setActionCommand("AddNewVertex");
b.addActionListener(this);
b.setBounds(
(int)x,
(int)y,
10, 10);
getContentPane().add(b);
buttonList.add(b);
Vertex v = med.structure.addVertex();
double[] pos = {x + r.nextDouble(), (y + r.nextDouble())};
v.position = pos;
vertexList.add(v);
}
public void updateButtonPos(){
for(int i = 0; i < buttonList.size(); i++){
JButton b = (JButton) buttonList.get(i);
Vertex v = (Vertex) vertexList.get(i);
b.setBounds(
(int) v.position[0],
(int) v.position[1], 10, 10);
}
}
public void updateScreen() {
if (!med.pause) {
med.structure.layoutStep();
updateButtonPos();
}
}
}