プログラマメモ2 - programmer no memo2

[java]JTreeで、ノードハンドルのクリックのみで、ノードを開くようにする方法 2009/02/09

Javaです。swingです。JTreeです。

同僚の方が、ノードハンドルのクリックのみで、ノードを開く実装を考えていたので、それをヒントに、僕も実装してみました。
イベントは、mousePressed、treeWillExpand、を使います。そしてフラグを用意します。
ちょっといけてない感じがしますが。。。

余談:
別のアプローチとして、BasicTreeUIをごにょごにょすればできますね。
BasicTreeUIはHandlerという内部クラスをもっていましてその、handleSelectionメソッドに、checkForClickInExpandControl、selectPathForEventに対しての呼び出し部分があります。

ここの処理はTreeUIを自前で用意しないとちょっと処理を変更できないかなぁ。

package jtree.a;

import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.TreePath;

public class TestMain {

public static void main(String[] args) {

MyFrame myFrame = new MyFrame();
myFrame.setVisible(true);
}

}

class MyFrame extends JFrame {

private static final long serialVersionUID = 1L;
{

setSize(300, 200);
setLocation(300, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setAlwaysOnTop(true);
getContentPane().add(new JPanel() {

private static final long serialVersionUID = 1L;

{
add(new JTree() {

private static final long serialVersionUID = 1L;

{
setPreferredSize(new Dimension(300,200));
/*
* イベントの発生順序が、 ノードハンドルの場合(TreeExpansionEvent,
* MouseEvent[MOUSE_PRESSED])
* ノードの場合(MouseEvent[MOUSE_PRESSED], TreeExpansionEvent,
* MouseEvent[MOUSE_PRESSED])
* なので、最終的にmousePressedで、開くようにする。
*/
class MyMouseAndTreee extends MouseAdapter implements
TreeWillExpandListener {

boolean canOpen = false;
TreePath willExpand;

@Override
public void mousePressed(MouseEvent e) {
System.err.println("" + e);
if (willExpand == null)
return;

/*
* マウスがプレスされたロケーションで取得されたパス
*/
TreePath path = getPathForLocation(e.getX(), e
.getY());
System.out.println("*** =>" + path);
try {

/*
* マウスプレスで取得された。位置でTreePathが取得できるか。
*/
if (path == null) {
canOpen = true;// 開くフラグ
expandPath(willExpand);
return;
}

} finally {
willExpand = null;
}

}

@Override
public void treeWillCollapse(TreeExpansionEvent e)
throws ExpandVetoException {
}

@Override
public void treeWillExpand(TreeExpansionEvent e)
throws ExpandVetoException {

System.err.println("" + e);

if (canOpen) {
canOpen = false;
return;
}

willExpand = e.getPath();
throw new ExpandVetoException(e);// 例外で開かない
}

}
MyMouseAndTreee treee = new MyMouseAndTreee();
addMouseListener(treee);
addTreeWillExpandListener(treee);
}

});// end add
}
});// end add
}
}

: