views:

22

answers:

1

I want to make it like when I click a button, it will create a new file. Then the jTree will highlight the new file. Below are my code. Currently I create new file, i will show the new file but no highlight the file.

class FileTreeModel implements TreeModel {
private FileNode root;

public FileTreeModel(String directory) {
    root = new FileNode(directory);
}

public Object getRoot() {
    return root;
}

public Object getChild(Object parent, int index) {
    FileNode parentNode = (FileNode) parent;
    return new FileNode(parentNode, parentNode.listFiles()[index].getName());
}

public int getChildCount(Object parent) {
    FileNode parentNode = (FileNode) parent;
    if (parent == null || !parentNode.isDirectory()
            || parentNode.listFiles() == null) {
        return 0;
    }

    return parentNode.listFiles().length;
}

public boolean isLeaf(Object node) {
    return (getChildCount(node) == 0);
}

public int getIndexOfChild(Object parent, Object child) {
    FileNode parentNode = (FileNode) parent;
    FileNode childNode = (FileNode) child;

    return Arrays.asList(parentNode.list()).indexOf(childNode.getName());
}

public void valueForPathChanged(TreePath path, Object newValue) {

}

public void addTreeModelListener(TreeModelListener l) {
}

public void removeTreeModelListener(TreeModelListener l) {
}
}

class FileNode extends java.io.File {

public FileNode(String directory) {
    super(directory);
}

public FileNode(FileNode parent, String child) {
    super(parent, child);
}

@Override
public String toString() {
    return getName();

}
}

jTree = new JTree();
jTree.setBounds(new Rectangle(164, 66, 180, 421));
jTree.setBackground(SystemColor.inactiveCaptionBorder);
jTree.setBorder(BorderFactory.createTitledBorder(null, "",
TitledBorder.LEADING, TitledBorder.TOP, new Font("Arial",
                        Font.BOLD, 12), new Color(0, 0, 0)));
FileTreeModel model = new FileTreeModel(root);
jTree.setRootVisible(false);
jTree.setModel(model);
expandAll(jTree);

public void expandAll(JTree tree) {

    int row = 0;
    while (row < tree.getRowCount()) {
        tree.expandRow(row);
        row++;
    }
}
+1  A: 

I think you could use the setSelectedRow [1] function.

EDIT: Added a sketch for the solution

You need to have a tree model that will read the files from the file system (original source):

import java.io.File;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

class FileSystemModel implements TreeModel {
  private File root;

  private Vector listeners = new Vector();

  public FileSystemModel(File rootDirectory) {
    root = rootDirectory;
  }

  public Object getRoot() {
    return root;
  }

  public Object getChild(Object parent, int index) {
    File directory = (File) parent;
    String[] children = directory.list();
    return new File(directory, children[index]);
  }

  public int getChildCount(Object parent) {
    File file = (File) parent;
    if (file.isDirectory()) {
      String[] fileList = file.list();
      if (fileList != null)
    return file.list().length;
    }
    return 0;
  }

  public boolean isLeaf(Object node) {
    File file = (File) node;
    return file.isFile();
  }

  public int getIndexOfChild(Object parent, Object child) {
    File directory = (File) parent;
    File file = (File) child;
    String[] children = directory.list();
    for (int i = 0; i < children.length; i++) {
      if (file.getName().equals(children[i])) {
    return i;
      }
    }
    return -1;

  }

  public void valueForPathChanged(TreePath path, Object value) {
    File oldFile = (File) path.getLastPathComponent();
    String fileParentPath = oldFile.getParent();
    String newFileName = (String) value;
    File targetFile = new File(fileParentPath, newFileName);
    oldFile.renameTo(targetFile);
    File parent = new File(fileParentPath);
    int[] changedChildrenIndices = { getIndexOfChild(parent, targetFile) };
    Object[] changedChildren = { targetFile };
    fireTreeNodesChanged(path.getParentPath(), changedChildrenIndices, changedChildren);

  }

  private void fireTreeNodesChanged(TreePath parentPath, int[] indices, Object[] children) {
    TreeModelEvent event = new TreeModelEvent(this, parentPath, indices, children);
    Iterator iterator = listeners.iterator();
    TreeModelListener listener = null;
    while (iterator.hasNext()) {
      listener = (TreeModelListener) iterator.next();
      listener.treeNodesChanged(event);
    }
  }

  public void addTreeModelListener(TreeModelListener listener) {
    listeners.add(listener);
  }

  public void removeTreeModelListener(TreeModelListener listener) {
    listeners.remove(listener);
  }
}

Then you would create a button listener to create the new file:

private void myButtonActionPerformed(java.awt.event.ActionEvent evt) {
    File f = new File(MY_DIR + "/file" + new Random().nextInt());
    try {
        f.createNewFile();

        FileSystemModel model = new FileSystemModel(new File(MY_DIR));
        tree.setModel(model);

        File root = (File) tree.getModel().getRoot();
        TreePath path = getPathFor(model, root, f);

        tree.expandPath(path);
        tree.setSelectionPath(path);
    }
    catch (IOException e)
    {

    }
}

Finally you would return the TreePath for the newly created file:

private TreePath getPathFor(FileSystemModel model, File root, File searched)
{
    TreePath path = getPath(model, null, root, searched);

    return path;
}

private TreePath getPath(FileSystemModel model, TreePath path, File parent, File searched)
{
    if (path == null)
    {
        path = new TreePath(parent);
    }
    else if (parent.isDirectory())
    {

        path = path.pathByAddingChild(parent);
    }

    if (parent.getAbsolutePath().equals(searched.getAbsolutePath()))
    {
        return path.pathByAddingChild(parent);
    }

    for (int i = 0; i < model.getChildCount(parent); i++)
    {
        File child = ((File)model.getChild(parent, i)).getAbsoluteFile();
        TreePath found = getPath(model, path, child, searched);

        if (found != null)
        {
            return found;
        }
    }

    return null;
}

This is just a demo on how you could do it, though its highly inneficient, because it recreates the model every time. I'm sure you can come up with a better solution.

the_void
Can you elaborate more?
How to set the new file to first row, the file are sorted by alphabert
I will sketch a sample shortly
the_void
Hi it works thanks alot can i just display the folder instead of whole path for example my root is "src/file" then my file = "src/file/My Note/New File" can i just show My Note/file instead or whole path
Yes, you can. Just make a subclass of `File` and overwrite the `toString()` method to return only the file name, not the full path to the file.
the_void
Hi i created a class FileNode extends java.io.File { public FileNode(String directory) { super(directory); } public FileNode(FileNode parent, String child) { super(parent, child); } @Override public String toString() { return ]getName(); }}this code i get from a website. but it still shwoing full path
See the `TreeFile` class declaration.
the_void
Hi Thank You very much it solved me a big problem thank you.:)
You're welcome :)
the_void