正月休みが終わってから、毎日ちまちまとVisual Studio2008のC++でDirectXをいじってました。
Config Systemサンプルを改造して、ボールに色をつけたり、ボールが動いた後を表示してみました。
2月になったので、とりあえずテトリスを自作して遊んでみようと思います。
サンダルマンのブログ
ブログ アーカイブ
2008年2月3日日曜日
2008年1月3日木曜日
Java6 JTree クリップボードにコピー、切り取り、貼り付けテスト + ファイルドロップ、コピペ
package JTreeClipBoardTest2;
import java.awt.BorderLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.InputEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.TransferHandler;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
/**
* Java6 JTree ClipBoard Copy Cut Paste Test + File Drop Copy Paste
* Java6 JTree クリップボードにコピー、切り取り、貼り付けテスト + ファイルドロップ、コピペ
*
* サンプルなので1つのファイルに必要なクラスを全部詰め込んであります。
*
* 起動すると、JTreeが2枚表示されます。
* JTree間でコピペ、カトペ、ドラッグアンドドロップできます。
* 他のアプリケーションからドロップしようとしても禁止マークがでます。
* DnDでムーブ、Ctrl+DnDでコピーも有効です。
* ※JTreeDnDTest.javaをベースに作成したのですが、コピペ対応のために弄ってる間に、対応できちゃったようです。
*
* エクスプローラからのファイルのコピペ、DnDに対応します。
* 文字列のコピペ、DnDも対応してみました。
*
* 自分自身にドロップ禁止、子ノードにドロップ禁止してみた。
* canImportの中で判定するとうまくいかなかったので、ドロップ後に判定するようにしてみた。(canImport2)
* exportAsDragで、JTreeをクラス変数に設定して、exportDoneでクラス変数をnullに設定。
* importDataのJComponentと、クラス変数が同じ場合、ツリーパスの判定を行う。
*/
public class JTreeClipBoardTest2 {
/**
* @param args
*/
public static void main(String[] args) {
JFrame f = new JFrame();
JTree t = new MyTree3();
JTree t2 = new MyTree3();
f.add(t, BorderLayout.CENTER);
f.add(t2, BorderLayout.EAST);
f.setSize(200, 200);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
/**
* JTreeを継承して、初期化メソッドと、コピペ、DnD用のセッタゲッタを追加したクラス。
*/
class MyTree3 extends JTree {
public MyTree3() {
super();
init();
}
private void init() {
// ドラッグを許可します。
setDragEnabled(true);
// トランスファハンドラを設定します。
setTransferHandler(new TreePathTransferHandler("selectionPathsDnd"));
// ※selectionPathsDndは、内部でsetほにゃらら、getほにゃららのメソッド検索に使われます。
}
/**
* TransferHandlerのプロパティに対応するため、DnD、コピペ用のセッタゲッタを用意します。
* @return
*/
public TreePath[] getSelectionPathsDnd() {
return getSelectionPaths();
}
/**
* オブジェクトを受けとるインポートメソッド。
* ここからクラスを判定して個別のメソッドを実行します。
* 名前はDndついてますが、コピペでも同じメソッドが使われます。
* @param paths
* @return
*/
public boolean setSelectionPathsDnd(Object obj) {
System.out.println("setSelectionPathsDnd");
System.out.println("class = " + obj.getClass());
if (obj == null) {
return false;
}
if (obj instanceof TreePath[]) {
TreePath[] paths = (TreePath[])obj;
return setSelectionPathsDnd(paths);
}
if (obj instanceof List) {
List files = (List)obj;
return setSelectionPathsDnd(files);
}
if (obj instanceof String) {
String files = obj.toString();
return setSelectionPathsDnd(files);
}
return false;
}
/**
* ファイルリスト用インポートメソッド
*/
public boolean setSelectionPathsDnd(List files) {
if (files == null ) {
return false;
}
Listfiless = (List )files;
javax.swing.JTree.DropLocation loc = getDropLocation();
TreePath putPath = null;
if (loc != null) {
// ドロップしたパスを取得します。
putPath = loc.getPath();
} else {
// ドロップロケーションがnullだったら、貼り付けと判断して選択済みのパスを取得します。
putPath = getSelectionPath();
}
DefaultMutableTreeNode putNode = (DefaultMutableTreeNode)putPath.getLastPathComponent();
for (File file : filess) {
DefaultMutableTreeNode node = new DefaultMutableTreeNode(file.getName());
putNode.add(node);
((DefaultTreeModel)getModel()).reload(putNode);
}
return true;
}
/**
* ツリーパス用インポートメソッド
*/
public boolean setSelectionPathsDnd(TreePath[] paths) {
if (paths == null ) {
return false;
}
javax.swing.JTree.DropLocation loc = getDropLocation();
TreePath putPath = null;
if (loc != null) {
// ドロップしたパスを取得します。
putPath = loc.getPath();
} else {
// ドロップロケーションがnullだったら、貼り付けと判断して選択済みのパスを取得します。
putPath = getSelectionPath();
}
DefaultMutableTreeNode putNode = (DefaultMutableTreeNode)putPath.getLastPathComponent();
for (TreePath path : paths) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
putNode.add(node);
((DefaultTreeModel)getModel()).reload(putNode);
}
return true;
}
/**
* 文字列用インポートメソッド
*/
public boolean setSelectionPathsDnd(String str) {
if (str == null ) {
return false;
}
javax.swing.JTree.DropLocation loc = getDropLocation();
TreePath putPath = null;
if (loc != null) {
// ドロップしたパスを取得します。
putPath = loc.getPath();
} else {
// ドロップロケーションがnullだったら、貼り付けと判断して選択済みのパスを取得します。
putPath = getSelectionPath();
}
DefaultMutableTreeNode putNode = (DefaultMutableTreeNode)putPath.getLastPathComponent();
String[] strAry = str.split("\n");
for (String path : strAry) {
DefaultMutableTreeNode node = new DefaultMutableTreeNode(path);
putNode.add(node);
((DefaultTreeModel)getModel()).reload(putNode);
}
return true;
}
}
/**
* ツリーパストランスファハンドラ
*/
class TreePathTransferHandler extends TransferHandler {
JComponent comp;
/**
* コンストラクタ プロパティ設定なし
*/
public TreePathTransferHandler() {
super();
}
/**
* コンストラクタ プロパティ設定あり
*/
public TreePathTransferHandler(String property) {
super(property);
}
/**
* 転送データ作成処理。
*/
@Override
protected Transferable createTransferable(JComponent c){
if (c instanceof MyTree3) {
MyTree3 tree = (MyTree3)c;
Transferable tf = new TreePathTransferable(tree);
return tf;
}
return null;
}
@Override
public void exportAsDrag(JComponent comp, InputEvent e, int action) {
this.comp = comp;
super.exportAsDrag(comp, e, action);
}
/**
* アクションを返します。
*/
@Override
public int getSourceActions(JComponent c) {
// スーパークラスの戻り値がCOPYの場合、COPY_OR_MOVEに変換します。
// ※スーパークラスがCOPYかNONEしか返さないため。
int action = super.getSourceActions(c);
if (action == COPY) {
action = COPY_OR_MOVE;
}
return action;
}
@Override
public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
// 受け入れ可能かどうかを返します。
// ツリーパスフレーバとファイルフレーバ以外のフレーバを受け入れないようにします。
Transferable f = createTransferable(comp);
boolean flg = false;
for (DataFlavor df : transferFlavors) {
if (f.isDataFlavorSupported(df)) {
flg = true;
break;
}
}
return flg;
}
/**
* 出力側のドロップ完了処理。
* actionがMOVEの場合、ツリーを削除します。
* ※importDataがfalseを返した場合、actionはNONEになります。
*/
@Override
protected void exportDone(JComponent source, Transferable data,
int action) {
// 出力完了時にcompとnullに設定します。
comp = null;
if (!(source instanceof JTree)) {
return;
}
MyTree3 tree = (MyTree3)source;
if (action == MOVE) {
try {
for (DataFlavor df : data.getTransferDataFlavors()) {
Object obj = data.getTransferData(df);
// エクスポートの場合、処理するのはTreePathの場合だけでよい。
if (obj instanceof TreePath[]) {
TreePath[] patha = (TreePath[])obj;
TreePath path = patha[0];
Object oo = path.getLastPathComponent();
DefaultMutableTreeNode node = (DefaultMutableTreeNode)oo;
node.removeFromParent();
((DefaultTreeModel)tree.getModel()).reload(node);
}
if (obj instanceof List) {
super.exportDone(source, data, action);
}
}
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
} else {
super.exportDone(source, data, action);
}
}
/**
* 入力側のドロップ処理。
* ドロップされたノードに、ドラッグされたノードを追加します。
*/
@Override
public boolean importData(JComponent comp, Transferable t) {
if (!(comp instanceof MyTree3)) {
return false;
}
if (!canImport(comp, t.getTransferDataFlavors())) {
return false;
}
if (!canImport2(comp, t)) {
return false;
}
MyTree3 tree = (MyTree3)comp;
DataFlavor[] dfa = t.getTransferDataFlavors();
for (DataFlavor df : dfa) {
try {
if (tree.setSelectionPathsDnd(t.getTransferData(df))) {
return true;
}
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
return false;
}
private boolean canImport2(JComponent comp, Transferable t) {
boolean flg = true;
if (comp == this.comp) {
try {
// 同じJTreeにドロップする場合。
MyTree3 tree = (MyTree3)comp;
if (tree.getDropLocation() != null) {
TreePath dropPath = tree.getDropLocation().getPath();
TreePath[] paths = (TreePath[])t.getTransferData(TreePathDataFravor.treePathFlavor);
for (TreePath dragPath : paths) {
if (dragPath.getPathCount() > dropPath.getPathCount()) {
continue;
}
if (dropPath.equals(dragPath)) {
flg = false;
break;
}
Object[] dragPathObject = dragPath.getPath();
Object[] dropPathObject = dropPath.getPath();
boolean sameFlg = true;
for (int i = 0; i < dragPathObject.length; i++) {
if (!dragPathObject[i].toString().equals(dropPathObject[i].toString())) {
sameFlg = false;
break;
}
}
if (sameFlg == true) {
flg = false;
break;
}
}
} else {
flg = false;
}
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
System.out.println(flg);
return flg;
}
}
/**
* ツリーパスデータフレーバクラス。
* 作ったはいいけど、ツリーパスフレーバーの定数を保管しているだけである。
*/
class TreePathDataFravor extends DataFlavor {
public static final DataFlavor treePathFlavor = new DataFlavor(TreePath[].class, javaJVMLocalObjectMimeType);
}
/**
* ツリーパス用トランスファエイブル
* ツリーパスの配列と、データフレーバーの配列を持つ。
*/
class TreePathTransferable implements Transferable
{
TreePath[] paths;
// ツリーパスフレーバとファイルリストフレーバ
static final DataFlavor[] dflv = {
TreePathDataFravor.treePathFlavor, // ツリーパスフレーバ
TreePathDataFravor.javaFileListFlavor, // ファイルリストフレーバ
TreePathDataFravor.stringFlavor // 文字列フレーバ
};
public TreePathTransferable(TreePath[] paths){
this.paths = paths;
}
public TreePathTransferable(MyTree3 tree) {
this(tree.getSelectionPathsDnd());
}
/**
* オブジェクト取得メソッド。
* フレーバに対応したオブジェクトを返します。
*/
@Override
public Object getTransferData(DataFlavor flavor){
if (TreePathDataFravor.treePathFlavor.equals(flavor)) {
// ツリーパスフレーバの場合
return paths;
} else if (TreePathDataFravor.javaFileListFlavor.equals(flavor)) {
// ファイルリストフレーバの場合
// ※偶然ファイルが存在しない限り、何も転送できない筈です。
Listfiles = new ArrayList ();
for (TreePath path : paths) {
files.add(new File(path.getLastPathComponent().toString()));
}
return files;
} else if (TreePathDataFravor.stringFlavor.equals(flavor)) {
// 文字列フレーバの場合
StringBuffer sb = new StringBuffer();
for (TreePath path : paths) {
sb.append(path.getLastPathComponent().toString() + "\n");
}
return sb.toString();
}
return null;
}
@Override
public DataFlavor[] getTransferDataFlavors(){
return dflv;
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor){
DataFlavor[] flv = getTransferDataFlavors();
for(int i = 0 ; i < flv.length ; i++){
if(flv[i].equals(flavor)){
return true;
}
}
return false;
}
}
//
Java6 JTree クリップボードにコピー、切り取り、貼り付けテスト
package JTreeClipBoardTest;
import java.awt.BorderLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.TransferHandler;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
/**
* Java6 JTree ClipBoard Copy Cut Paste Test
* Java6 JTree クリップボードにコピー、切り取り、貼り付けテスト
*
* 起動すると、JTreeが2枚表示されます。
* JTree間でコピペ、カトペ、ドラッグアンドドロップできます。
* 他のアプリケーションからドロップしようとしても禁止マークがでます。
* DnDでムーブ、Ctrl+DnDでコピーも有効です。
* ※JTreeDnDTest.javaをベースに作成したのですが、コピペ対応のために弄ってる間に、対応できちゃったようです。
*/
public class JTreeClipBoardTest {
/**
* @param args
*/
public static void main(String[] args) {
JFrame f = new JFrame();
JTree t = new MyTree3();
JTree t2 = new MyTree3();
f.add(t, BorderLayout.CENTER);
f.add(t2, BorderLayout.EAST);
f.setSize(200, 200);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
/**
* JTreeを継承して、初期化メソッドと、コピペ、DnD用のセッタゲッタを追加したクラス。
*/
class MyTree3 extends JTree {
public MyTree3() {
super();
init();
}
private void init() {
// ドラッグを許可します。
setDragEnabled(true);
// トランスファハンドラを設定します。
setTransferHandler(new TreePathTransferHandler("selectionPathsDnd"));
// ※selectionPathsDndは、内部でsetほにゃらら、getほにゃららのメソッド検索に使われます。
}
/**
* TransferHandlerのプロパティに対応するため、DnD、コピペ用のセッタゲッタを用意します。
* @return
*/
public TreePath[] getSelectionPathsDnd() {
return getSelectionPaths();
}
/**
* 名前はDndついてますが、コピペでも同じメソッドが使われます。
* @param paths
* @return
*/
public boolean setSelectionPathsDnd(TreePath[] paths) {
if (paths == null ) {
return false;
}
javax.swing.JTree.DropLocation loc = getDropLocation();
TreePath putPath = null;
if (loc != null) {
// ドロップしたパスを取得します。
putPath = loc.getPath();
} else {
// ドロップロケーションがnullだったら、貼り付けと判断して選択済みのパスを取得します。
putPath = getSelectionPath();
}
DefaultMutableTreeNode putNode = (DefaultMutableTreeNode)putPath.getLastPathComponent();
for (TreePath path : paths) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
putNode.add(node);
((DefaultTreeModel)getModel()).reload();
}
return true;
}
}
/**
* ツリーパストランスファハンドラ
*/
class TreePathTransferHandler extends TransferHandler {
/**
* コンストラクタ プロパティ設定なし
*/
public TreePathTransferHandler() {
super();
}
/**
* コンストラクタ プロパティ設定あり
*/
public TreePathTransferHandler(String property) {
super(property);
}
/**
* 転送データ作成処理。
*/
@Override
protected Transferable createTransferable(JComponent c){
if (c instanceof MyTree3) {
MyTree3 tree = (MyTree3)c;
Transferable tf = new TreePathTransferable(tree);
return tf;
}
return super.createTransferable(c);
}
/**
* アクションを返します。
*/
@Override
public int getSourceActions(JComponent c) {
// スーパークラスの戻り値がCOPYの場合、COPY_OR_MOVEに変換します。
// ※スーパークラスがCOPYかNONEしか返さないため。
int action = super.getSourceActions(c);
if (action == COPY) {
action = COPY_OR_MOVE;
}
return action;
}
@Override
public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
// 受け入れ可能かどうかを返します。
// ツリーパスフレーバ以外のフレーバを受け入れないようにします。
for (DataFlavor df : transferFlavors) {
if (!df.equals(TreePathDataFravor.treePathFravor)) {
return false;
}
}
return true;
}
/**
* 出力側のドロップ完了処理。
* actionがMOVEの場合、ツリーを削除します。
* ※importDataがfalseを返した場合、actionはNONEになります。
*/
@Override
protected void exportDone(JComponent source, Transferable data,
int action) {
if (!(source instanceof JTree)) {
return;
}
MyTree3 tree = (MyTree3)source;
if (action == MOVE) {
try {
for (DataFlavor df : data.getTransferDataFlavors()) {
TreePath[] patha = (TreePath[]) data.getTransferData(df);
TreePath path = patha[0];
Object oo = path.getLastPathComponent();
DefaultMutableTreeNode node = (DefaultMutableTreeNode)oo;
node.removeFromParent();
((DefaultTreeModel)tree.getModel()).reload();
}
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
} else {
super.exportDone(source, data, action);
}
}
/**
* 入力側のドロップ処理。
* ドロップされたノードに、ドラッグされたノードを追加します。
*/
@Override
public boolean importData(JComponent comp, Transferable t) {
if (!(comp instanceof MyTree3)) {
return false;
}
if (!canImport(comp, t.getTransferDataFlavors())) {
return false;
}
MyTree3 tree = (MyTree3)comp;
DataFlavor[] dfa = t.getTransferDataFlavors();
for (DataFlavor df : dfa) {
try {
TreePath[] orgPathA = (TreePath[])t.getTransferData(df);
return tree.setSelectionPathsDnd(orgPathA);
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
return false;
}
}
/**
* ツリーパスデータフレーバクラス。
* 作ったはいいけど、ツリーパスフレーバーの定数を保管しているだけである。
*/
class TreePathDataFravor extends DataFlavor {
public static final DataFlavor treePathFravor = new DataFlavor(TreePath[].class, javaJVMLocalObjectMimeType);
}
/**
* ツリーパス用トランスファエイブル
* ツリーパスの配列と、データフレーバーの配列を持つ。
*/
class TreePathTransferable implements Transferable
{
TreePath[] paths;
// データフレーバ(フレーバ=食品への風味付け)
static final DataFlavor[] dflv = {TreePathDataFravor.treePathFravor};
public TreePathTransferable(TreePath[] paths){
this.paths = paths;
}
public TreePathTransferable(MyTree3 tree) {
this(tree.getSelectionPathsDnd());
}
@Override
public Object getTransferData(DataFlavor flavor){
for (DataFlavor df : dflv) {
if (df.equals(flavor)){
return paths;
}
}
return null;
}
@Override
public DataFlavor[] getTransferDataFlavors(){
return dflv;
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor){
DataFlavor[] flv = getTransferDataFlavors();
for(int i = 0 ; i < flv.length ; i++){
if(flv[i].equals(flavor)){
return true;
}
}
return false;
}
}
2008年1月2日水曜日
Java6 JTree DnD Test(ドラッグアンドドロップテスト)
※ugnagさんの解説を元に作成しました。
1.ドラッグを許可します。
2.トランスファハンドラを設定します。
3.転送データを作成します。
4.アクションを返します。
5.ドロップ可能かどうかを返します。
6.ドロップされたデータを受け取ります。
7.ドロップ完了後の処理をします。
1.ドラッグを許可します。
2.トランスファハンドラを設定します。
3.転送データを作成します。
ドラッグ操作を契機に呼び出されます。
4.アクションを返します。
NONE,COPY,MOVE,COPY_OR_MOVE,LINKの5種類があります。
NONE,COPY,MOVEまではいいとして、COPY_OR_MOVE,LINKが謎です。
5.ドロップ可能かどうかを返します。
ドロップ可能な場合TRUE。ドロップ不可の場合FALSEを返します。
FALSEを返すと、マウスカーソルが車両通行止めになります。
6.ドロップされたデータを受け取ります。
3.で作成したデータを受け取ります。
JTree.getDropLocation().getPath()で、どのツリーパスにドロップされたかが分ります。
今回はドラッグしたツリーを、ドロップされたツリーに追加しています。
7.ドロップ完了後の処理をします。
6.でFALSEを返すと、パラメータのアクションがNONEになります。
今回は、MOVEの場合だけ、ドラッグしたツリーを削除しています。
1.ドラッグを許可します。
2.トランスファハンドラを設定します。
3.転送データを作成します。
4.アクションを返します。
5.ドロップ可能かどうかを返します。
6.ドロップされたデータを受け取ります。
7.ドロップ完了後の処理をします。
import java.awt.BorderLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.TransferHandler;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
/**
* Java6 JTree DnD Test
* Java6 JTree ドラッグアンドドロップテスト
* http://ugnag.lar.jp/pgm/java/dd/index.html
* ※ugnagさんの解説を元に作成しました。
*/
public class JTreeDnDTest {
/**
* @param args
*/
public static void main(String[] args) {
JFrame f = new JFrame();
JTree t = new MyTree3();
JTree t2 = new MyTree3();
f.add(t, BorderLayout.CENTER);
f.add(t2, BorderLayout.EAST);
f.setSize(200, 200);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
class MyTree3 extends JTree {
public MyTree3() {
super();
init();
}
private void init() {
// 1.ドラッグを許可します。
setDragEnabled(true);
// 2.トランスファハンドラを設定します。
setTransferHandler(new TreePathTransferHandler());
}
}
/**
* ツリーパストランスファハンドラ
*
*/
class TreePathTransferHandler extends TransferHandler {
@Override
protected Transferable createTransferable(JComponent c){
// 3.転送データを作成します。
if (c instanceof JTree) {
JTree tree = (JTree)c;
TreePath[] paths = tree.getSelectionPaths();
return new TreePathTransferable(paths);
}
return null;
}
@Override
public int getSourceActions(JComponent c) {
// 4.アクションを返します。
// 今回は無条件にMOVEとする。
return MOVE;
}
@Override
public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
// 5.ドロップ可能かどうかを返します。
// 受け入れ判定をせずに、無条件でTRUE。FALSEを返すと、UIでドロップ禁止となる。
return true;
}
/**
* 出力側のドロップ完了処理。
* actionがMOVEの場合、ツリーを削除します。
* ※importDataがfalseを返した場合、actionはNONEになります。
*/
@Override
protected void exportDone(JComponent source, Transferable data,
int action) {
// 7.ドロップ完了後の処理をします。
if (!(source instanceof JTree)) {
return;
}
JTree tree = (JTree)source;
if (action == MOVE) {
for (DataFlavor df : data.getTransferDataFlavors()) {
try {
TreePath[] patha = (TreePath[]) data.getTransferData(df);
TreePath path = patha[0];
Object oo = path.getLastPathComponent();
DefaultMutableTreeNode node = (DefaultMutableTreeNode)oo;
node.removeFromParent();
((DefaultTreeModel)tree.getModel()).reload();
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
} else {
super.exportDone(source, data, action);
}
}
/**
* 入力側のドロップ処理。
* ドロップされたノードに、ドラッグされたノードを追加します。
*/
@Override
public boolean importData(JComponent comp, Transferable t) {
// 6.ドロップされたデータを受け取ります。
if (!(comp instanceof JTree)) {
return false;
}
JTree tree = (JTree)comp;
javax.swing.JTree.DropLocation loc = tree.getDropLocation();
TreePath path = loc.getPath();
DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
DataFlavor[] dfa = t.getTransferDataFlavors();
for (DataFlavor df : dfa) {
try {
TreePath[] orgPathA = (TreePath[])t.getTransferData(df);
for (TreePath orgPath : orgPathA) {
DefaultMutableTreeNode oNode = (DefaultMutableTreeNode)orgPath.getLastPathComponent();
node.add(oNode);
}
((DefaultTreeModel)tree.getModel()).reload();
return true;
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
return true;
}
}
/**
* ツリーパス用トランスファエイブル
* ツリーパスの配列と、データフレーバーの配列を持つ。
* http://ugnag.lar.jp/docs/java/dd/index.html
* ※ugnagさんのコードをほぼそのまま利用しています。
*/
class TreePathTransferable implements Transferable
{
TreePath[] paths;
// データフレーバ(フレーバ=食品への風味付け)
DataFlavor[] dflv;
public TreePathTransferable(TreePath[] paths){
this.paths = paths;
dflv = new DataFlavor[]{new DataFlavor(TreePath[].class, "array of TreePath")};
}
@Override
public Object getTransferData(DataFlavor flavor){
for (DataFlavor df : dflv) {
if (df.getMimeType().equals(flavor.getMimeType())){
if (df.getClass().equals(flavor.getClass())){
return paths;
}
}
}
return null;
}
@Override
public DataFlavor[] getTransferDataFlavors(){
return dflv;
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor){
DataFlavor[] flv = getTransferDataFlavors();
for(int i = 0 ; i < flv.length ; i++){
if(flv[i].equals(flavor)){
return true;
}
}
return false;
}
}
1.ドラッグを許可します。
2.トランスファハンドラを設定します。
3.転送データを作成します。
ドラッグ操作を契機に呼び出されます。
4.アクションを返します。
NONE,COPY,MOVE,COPY_OR_MOVE,LINKの5種類があります。
NONE,COPY,MOVEまではいいとして、COPY_OR_MOVE,LINKが謎です。
5.ドロップ可能かどうかを返します。
ドロップ可能な場合TRUE。ドロップ不可の場合FALSEを返します。
FALSEを返すと、マウスカーソルが車両通行止めになります。
6.ドロップされたデータを受け取ります。
3.で作成したデータを受け取ります。
JTree.getDropLocation().getPath()で、どのツリーパスにドロップされたかが分ります。
今回はドラッグしたツリーを、ドロップされたツリーに追加しています。
7.ドロップ完了後の処理をします。
6.でFALSEを返すと、パラメータのアクションがNONEになります。
今回は、MOVEの場合だけ、ドラッグしたツリーを削除しています。
2008年1月1日火曜日
JAVA6 Swing JTreeでヒントの表示 ヒントの表示位置を、ツリーアイテムに被せる(winのエクスプローラ風)
1.JTreeをツールチップマネージャーに登録します。
2.セルレンダラを設定します。
3.セルレンダラのgetToolTipText(MouseEvent event)を実装(オーバーライド)します。
4.JTreeのgetToolTipLocation(MouseEvent event)を実装(オーバーライド)します。(new!!)
import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTree;
import javax.swing.ToolTipManager;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
public class JTreeHintTest2 {
/**
* @param args
*/
public static void main(String[] args) {
JFrame f = new JFrame();
f.setSize(200, 200);
JTree t = new MyTree2();
ToolTipManager.sharedInstance().registerComponent(t); // 1.JTreeをツールチップマネージャーに登録します。
t.setCellRenderer(new MyRendrer2()); // 2.セルレンダラを設定します。
f.add(t);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class MyRendrer2 extends DefaultTreeCellRenderer {
// 3.セルレンダラのgetToolTipText(MouseEvent event)を実装します。
@Override
public String getToolTipText(MouseEvent event) {
return getText();
}
}
class MyTree2 extends JTree {
// 4.JTreeのgetToolTipLocation(MouseEvent event)を実装(オーバーライド)します。
@Override
public Point getToolTipLocation(MouseEvent event) {
Point p = null;
if(event != null) {
p = event.getPoint();
int selRow = getRowForLocation(p.x, p.y);
TreeCellRenderer r = getCellRenderer();
if(selRow != -1 && r != null) {
TreePath path = getPathForRow(selRow);
Object lastPath = path.getLastPathComponent();
Component rComponent = r.getTreeCellRendererComponent
(this, lastPath, isRowSelected(selRow),
isExpanded(selRow), getModel().isLeaf(lastPath), selRow,
true);
if(rComponent instanceof TreeCellRenderer) {
JLabel r2 = (JLabel)rComponent;
Rectangle pathBounds = getPathBounds(path);
int iconWidth = r2.getIcon().getIconWidth();
p = new Point(pathBounds.x + iconWidth, pathBounds.y);
}
}
}
return p;
}
}
■ 解説
1.JTreeをツールチップマネージャーに登録します。
ヒントを表示するには、まずツールチップマネージャーにコンポーネントを登録する必要があります。
2.セルレンダラを設定します。
ヒントに表示する文字列は、セルレンダラのgetToolTipText(MouseEvent event)から取得されます。
よって、getToolTipText(MouseEvent event)を実装したセルレンダラをJTreeに設定する必要があります。
3.セルレンダラのgetToolTipText(MouseEvent event)を実装します。
2.と同じなので割愛。
4.JTreeのgetToolTipLocation(MouseEvent event)を実装(オーバーライド)します。
ヒントの表示位置は、JTreeのgetToolTipLocation(MouseEvent event)で設定します。
JTreeにはデフォルトの実装がありますが、これをオーバーライドして自分好みの座標に変換します。
今回のコードは、デフォルトの実装をコピペして改造した物です。
Rectangle pathBounds = getPathBounds(path);
int iconWidth = r2.getIcon().getIconWidth();
p = new Point(pathBounds.x + iconWidth, pathBounds.y);
アイテムの表示位置の端っこに、アイコンの幅だけ横にずらした座標を設定しています。
JAVA6 Swing JTreeでヒントの表示
1.JTreeをツールチップマネージャーに登録します。
2.セルレンダラを設定します。
3.セルレンダラのgetToolTipText(MouseEvent event)を実装します。
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.ToolTipManager;
import javax.swing.tree.DefaultTreeCellRenderer;
public class JTreeHintTest {
/**
* @param args
*/
public static void main(String[] args) {
JFrame f = new JFrame();
f.setSize(200, 200);
JTree t = new MyTree();
ToolTipManager.sharedInstance().registerComponent(t); // 1.JTreeをツールチップマネージャーに登録します。
t.setCellRenderer(new MyRendrer()); // 2.セルレンダラを設定します。
f.add(t);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class MyRendrer extends DefaultTreeCellRenderer {
// 3.セルレンダラを設定します。
@Override
public String getToolTipText(MouseEvent event) {
return getText();
}
}
class MyTree extends JTree {
@Override
public String getToolTipText(MouseEvent event) {
return super.getToolTipText(event);
}
}
■ 解説
1.JTreeをツールチップマネージャーに登録します。
ヒントを表示するには、まずツールチップマネージャーにコンポーネントを登録する必要があります。
2.セルレンダラを設定します。
ヒントに表示する文字列は、セルレンダラのgetToolTipText(MouseEvent event)から取得されます。
よって、getToolTipText(MouseEvent event)を実装したセルレンダラをJTreeに設定する必要があります。
3.セルレンダラのgetToolTipText(MouseEvent event)を実装します。
2.と同じなので割愛。
登録:
投稿 (Atom)