1

Trying to Add a list of files to a Jlist, then filter the files in the JList to only return .txt files and fixed char length. Also trying remove the file path that gets returned, and only show the filename+extension in the JList of files.

So far, accomplished all except removing the file path. For example, it still returns "C:\java_help.txt" instead of just "java_help.txt" in the JList.

    import javax.swing.*;
    import java.io.*;

    public class FileName extends JFrame{
        JPanel pnl=new JPanel();
        public static void main (String[]args) {
            FileName print=new FileName();
            }
        JList list;

        @SuppressWarnings("unchecked")
        public FileName() {
            super("Swing Window");
            setSize(250,300);
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setVisible(true);
            add(pnl);

            String path="C:/";
            File folder=new File(path);
            File[]listOfFiles=folder.listFiles(new TextFileFilter());

            list=new JList(listOfFiles);
            list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            list.setLayoutOrientation(JList.VERTICAL);
            pnl.add(list);
            pnl.revalidate();
            }
    }

    class TextFileFilter implements FileFilter {
        public boolean accept(File file) {
            String name=file.getName();
            return name.length()<28&&name.endsWith(".txt");
            }
        }

I thought getName() was supposed to accomplish this, but it doesn't seem to be the case. How can I remove the path from the filename, and be left with just filename+extension in the JList? Applicable examples to the code above would be appreciated.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
user3155369
  • 15
  • 2
  • 4
  • you can try using `Paths` instead of `File`, I believe it has a `.getName()` method. – SnakeDoc Jan 03 '14 at 19:32
  • 1
    The API makes it sound like getName() should return the last part of the path, but if it's not, can't you just parse the String yourself? – Kevin Workman Jan 03 '14 at 19:32
  • just a pet peeve of mine... don't use `@SuppressWarnings("Unchecked")`, your compiler is complaining for a reason, listen to it in order to build robust applications. – SnakeDoc Jan 03 '14 at 19:35
  • What java are you using? Because, not only does the API state it returns the file name (without the path), but in practice using OpenJDK and Oracle's java on my test systems, it works as expected and only returns the file name, no path. – SnakeDoc Jan 03 '14 at 19:44
  • Unrelated to your problem, but you have some general Swing problems here: You should wrap the `new FileName` line in `EventQueue.invokeLater`. Also put the `JList` inside a `JScrollPane`, and add the panel to the `JFrame` after it is all built: then you don't need to call revalidate. – wolfcastle Jan 03 '14 at 23:32

6 Answers6

1

I think the problem here isn't the code you have: the file filter looks okay. I think your complaint is how the text is displayed in the JList.

You need to implement a ListCellRender to change the display text.

See the JList tutorial for how to do this.

wolfcastle
  • 5,850
  • 3
  • 33
  • 46
  • Wow, I can't believe that so many people missed this. +1. Just other people recognise this. It's the responsibility of the ListCellRenderer to determine how the information in the model is displayed. Woot further context, suggesting that the OP modify there model data is erroneous, as they might want the full file reference for further processing – MadProgrammer Jan 03 '14 at 20:34
  • Gave up after a few hours, and implemented a ListCellRenderer instead. Should have done that before :P. Thanks! – user3155369 Jan 03 '14 at 23:49
0

take the returned value and do

String[] PartsOfPath = ReturnedPath.split("\");

String JustFileName = PartsOfPath[(PartsOfPath.length - 1)];

I haven't tested that, but I would think that should work. Obviously swap with the variables names you need.

Spencer D
  • 3,376
  • 2
  • 27
  • 43
  • the OP has something wrong. file.getname() does indeed return only the file name + extension, no path is returned. I've tested on OpenJDK and Oracle's java, both Java 7 – SnakeDoc Jan 03 '14 at 19:45
0

Since you used 'C:` in your path, I assume you're on Windows and want something that will work on Windows.

Just trim the path:

String name=file.getName();
name = name.substring(name.lastIndexOf('\\'));
// ...

This will delete the path, leaving you with only the filename.

Obviously, it won't work on Linux. If you need it to, you can switch the character you're looking for. On Windows, this works.

ashes999
  • 9,925
  • 16
  • 73
  • 124
  • the OP has something wrong. `file.getname()` does indeed return only the file name + extension, no path is returned. I've tested on OpenJDK and Oracle's java, both Java 7. – SnakeDoc Jan 03 '14 at 19:45
  • @SnakeDoc you could be right. I usually use `someFile.getAbsolutePath()`, which may be what I'm thinking of here. – ashes999 Jan 03 '14 at 19:47
  • no you are right, the OP is trying to get the file name + extension, without the path. But, instead of creating some "hack" to do it, the OP needs to identify why the standard java method that works for everyone else, is not working for him. – SnakeDoc Jan 03 '14 at 19:49
  • 1
    also, just for a more robust program, don't hard code \\ , instead use `System.getProperty("file.separator")` which will return the system-specific directory separator... \ on windows (well actually \\ because it's java), and `/` on Unix/Linux. – SnakeDoc Jan 03 '14 at 19:53
  • 1
    Thanks, I was looking for something like `System.getProperty("file.separator")`. – ashes999 Jan 03 '14 at 20:21
0

The problem is your method accept() in TextFileFilter class.

Something is wrong with your return line, and I'm not entirely sure what you were trying to do there. It appears you are trying to return the name.

for me, this works as expected:

import java.io.File;

public class Test {
    public static void main(String[] args) {
        File f = new File("C:\\bell.wav");
        System.out.println(f.getName());
    }
}

Prints: bell.wav

If File is not working for you, try using Paths instead.

import java.nio.file.Path;
import java.nio.file.Paths;

public class Test {
    public static void main(String[] args) {
        Path p = Paths.get("C:\\bell.wav");
        System.out.println(p.getFileName());
    }
}

Prints: bell.wav

SnakeDoc
  • 13,611
  • 17
  • 65
  • 97
0

This works, but you only get the String and not the File object. Note if you replace the "C:\", the File path will no longer be valid if you need to retrieve the File object. So instead you just have a list of file names instead of File objects. That may be a reason the "C:\" stays in there originally.

String path = "C:/";
File folder = new File(path);
File[] listOfFiles = folder.listFiles(new TextFileFilter());

List<String> fileNames = new ArrayList<String>();
for (File f: listOfFiles) {
fileNames.add(f.getName().replace(path, ""));
}

list = new JList(fileNames.toArray());
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • why create a hack for something that should just work from the standard java library? – SnakeDoc Jan 03 '14 at 19:54
  • SnakeDoc 1. this isn't hack, Swing is based on premature arrays (otherwise you have to suggest to create AbstractListModel to OP), 2. this code is from this forum and based on one of posts by @Andrew Thompson (FileFilter must returns filtered Files only, based on filter as paramater) – mKorbel Jan 03 '14 at 20:05
  • @peeskillet search for his post, is not neccesary – mKorbel Jan 03 '14 at 20:06
  • 1
    hehehe I'm remember that and correctly [hint_hint_hint usage of renderer is the answer](http://stackoverflow.com/a/7222943/714968) – mKorbel Jan 03 '14 at 20:15
  • @mKorbel I think you may have missed my point. `file.getName()`, according to the standard java library, returns only the filename + extension, no path is returned. That is the "hack" I was referring to. The OP has something wrong someplace. – SnakeDoc Jan 03 '14 at 20:31
  • @SnakeDoc yes or not too, please to check linked code example im my post, and then to re_read OPs question, Renderer is designated to painting expected value with, btw this is in the answer by wolfcastle too – mKorbel Jan 03 '14 at 20:33
0

Here's a simple implementation of the ListCellRenderer wolfcastle suggests that will do what you want:

class SimpleFileCellRenderer extends DefaultListCellRenderer implements ListCellRenderer<Object>
{
    // Use this to show relative paths instead of absolute.  
    @Override
    public Component getListCellRendererComponent(
            JList<? extends Object> list, Object value, int index,
            boolean isSelected, boolean cellHasFocus) {

        Path relative = ((File) value).toPath().getFileName();

        return super.getListCellRendererComponent(list, relative, index, isSelected, cellHasFocus);
    }
}

Just call JList.setCellRenderer(new SimpleFileCellRenderer()); and you should be set.

kHAN
  • 1
  • 1