2

I created a JList that contains a list of files that are in a directory. Here is the JList.

JList MList;
String ListData[]
// Create a new listbox control
List = new JList(ListData);

I also created a method that reads a list of text files in a directory:

     public String ReadDirectory() {
        String path = "C://Documents and Settings/myfileTxt";

        String files = null;
        File folder = new File(path);
        File[] listOfFiles = folder.listFiles();

        for (int i = 0; i < listOfFiles.length; i++) {
            if (listOfFiles[i].isFile()) {
                files = listOfFiles[i].getName();
                if (files.endsWith(".txt") || files.endsWith(".TXT")) {
                    System.out.println(files);
                }
            }
        }
        return files;
    }

The problem is I want the result of this method (the list of text files) in a JList. How can I put the File objects in the JList?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Lou
  • 51
  • 1
  • 2
  • 3
  • what's `String path = "C://Documents and Settings/myfileTxt";`, that isn't `C:/Documents and Settings/myfileTxt`, `not too C:\\Documents and Settings\\myfileTxt` – mKorbel Aug 28 '11 at 21:40
  • please learn java naming conventions and stick to them – kleopatra Aug 29 '11 at 08:42
  • package your problem into small chunks and solve them one-after-the-other. Hint: the method _does not_ return a _list_ (neither of files nor of fileNames) – kleopatra Aug 29 '11 at 08:54

5 Answers5

9

Don't put strings into the JList, use File objects and set a renderer. Since the component returned by the default renderer is a JLabel, it is easy to set an icon.

File List

import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.Border;
import javax.swing.filechooser.FileSystemView;
import java.io.File;
import java.io.FileFilter;

/**
This code uses a JList in two forms (layout orientation vertical & horizontal wrap) to
display a File[].  The renderer displays the file icon obtained from FileSystemView.
*/
class FileList {

    public Component getGui(File[] all, boolean vertical) {
        // put File objects in the list..
        JList fileList = new JList(all);
        // ..then use a renderer
        fileList.setCellRenderer(new FileRenderer(!vertical));

        if (!vertical) {
            fileList.setLayoutOrientation(javax.swing.JList.HORIZONTAL_WRAP);
            fileList.setVisibleRowCount(-1);
        } else {
            fileList.setVisibleRowCount(9);
        }
        return new JScrollPane(fileList);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                File f = new File(System.getProperty("user.home"));
                FileList fl = new FileList();
                Component c1 = fl.getGui(f.listFiles(new TextFileFilter()),true);

                //f = new File(System.getProperty("user.home"));
                Component c2 = fl.getGui(f.listFiles(new TextFileFilter()),false);

                JFrame frame = new JFrame("File List");
                JPanel gui = new JPanel(new BorderLayout());
                gui.add(c1,BorderLayout.WEST);
                gui.add(c2,BorderLayout.CENTER);
                c2.setPreferredSize(new Dimension(375,100));
                gui.setBorder(new EmptyBorder(3,3,3,3));

                frame.setContentPane(gui);
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

class TextFileFilter implements FileFilter {

    public boolean accept(File file) {
        // implement the logic to select files here..
        String name = file.getName().toLowerCase();
        //return name.endsWith(".java") || name.endsWith(".class");
        return name.length()<20;
    }
}

class FileRenderer extends DefaultListCellRenderer {

    private boolean pad;
    private Border padBorder = new EmptyBorder(3,3,3,3);

    FileRenderer(boolean pad) {
        this.pad = pad;
    }

    @Override
    public Component getListCellRendererComponent(
        JList list,
        Object value,
        int index,
        boolean isSelected,
        boolean cellHasFocus) {

        Component c = super.getListCellRendererComponent(
            list,value,index,isSelected,cellHasFocus);
        JLabel l = (JLabel)c;
        File f = (File)value;
        l.setText(f.getName());
        l.setIcon(FileSystemView.getFileSystemView().getSystemIcon(f));
        if (pad) {
            l.setBorder(padBorder);
        }

        return l;
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • would be harder to re-create JLabel again ...., just `setText(f.getName());` thanks, JLabel returns Renderer by default +1 – mKorbel Aug 28 '11 at 21:37
  • hmm whatever without `l.` :-) – mKorbel Aug 28 '11 at 23:06
  • nitpicking: you wouldn't create the border on every call :-) – kleopatra Aug 29 '11 at 08:45
  • @Andrew Thompson psssst and now she's here, look like as without favorite coffee after this morning :-) – mKorbel Aug 29 '11 at 09:09
  • @Kleopatra I was wondering if anyone would pick that nit! source edited. – Andrew Thompson Aug 29 '11 at 09:17
  • @mKorbel You know the drill - "Duck & Cover". ;) – Andrew Thompson Aug 29 '11 at 09:17
  • can you add listener to items in side list and also remove and add item possibility, it will make your code perfect? – itro Mar 06 '12 at 08:07
  • Is there a tutorial on the internet for doing that? That could actually be what I'm looking for. I was originally going to use a JList but I like the style of this much better. – Vince Mar 02 '17 at 18:26
  • @Vince *"Is there a tutorial on the internet for doing that?"* Doing what, exactly? Now would be a good time for being more detailed, rather than less. – Andrew Thompson Mar 02 '17 at 18:40
  • @AndrewThompson Rendering the labels and icons into the list. I'm creating a search. where it takes inputted text and searches for folders and files that contain the text inputted. (similar to windows explorer search). – Vince Mar 02 '17 at 18:54
  • @Vince See the `FileRenderer` class, Note it takes less than 100 lines of code (in the complete example above) to achieve what is seen above! Copy the code into a new project, compile and run it to convince yourself it works as advertised. Then go through the code carefully and try to understand it, checking the Java Docs for any class, method or attribute you don't know about or understand. Then if you have any further questions, create an example specific to the question and ask it on a new question thread. – Andrew Thompson Mar 02 '17 at 19:15
  • @AndrewThompson I already checked your code. Haha. I was just wondering if anyone knew of a good tutorial online for it. I am slowly going through it though. :) Thanks for your quick replies! – Vince Mar 02 '17 at 19:19
  • @Vince Well there's always [How to Use Lists: Writing a Custom Cell Renderer](http://docs.oracle.com/javase/tutorial/uiswing/components/list.html#renderer).. – Andrew Thompson Mar 02 '17 at 19:27
3

@Andrew Thompson

eeeergght nothing good coming from this night 03:36AM in my TimeZone and at 06:00 I must wakeUp,

but somewhere I lost (not me) JLabel, heavens where it could be

import java.awt.*;
import java.io.File;
import javax.swing.*;
import javax.swing.filechooser.FileSystemView;

public class FilesInTheJList {

    public FilesInTheJList() {
        JList displayList = new JList(new File("C:\\").listFiles());
        displayList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        displayList.setCellRenderer(new MyCellRenderer());
        displayList.setLayoutOrientation(javax.swing.JList.HORIZONTAL_WRAP);
        displayList.setName("displayList");
        JFrame f = new JFrame("Files In the JList");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setPreferredSize(new Dimension(500, 300));
        displayList.setVisibleRowCount(-1);
        f.add(new JScrollPane(displayList));
        f.pack();
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                FilesInTheJList fITJL = new FilesInTheJList();
            }
        });
    }

    private static class MyCellRenderer extends DefaultListCellRenderer  {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getListCellRendererComponent(JList list, Object value,
                int index, boolean isSelected, boolean cellHasFocus) {
            if (value instanceof File) {
                File file = (File) value;
                setText(file.getName());
                setIcon(FileSystemView.getFileSystemView().getSystemIcon(file));
                if (isSelected) {
                    setBackground(list.getSelectionBackground());
                    setForeground(list.getSelectionForeground());
                } else {
                    setBackground(list.getBackground());
                    setForeground(list.getForeground());
                }
                setEnabled(list.isEnabled());
                setFont(list.getFont());
                setOpaque(true);
            }
            return this;
        }
    }
}

enter image description here

import java.awt.*;
import java.io.File;
import javax.swing.*;
import javax.swing.filechooser.FileSystemView;

public class FilesInTheJList {

    private static final int COLUMNS = 4;
    private Dimension size;

    public FilesInTheJList() {
        final JList list = new JList(new File("C:\\").listFiles()) {

            private static final long serialVersionUID = 1L;

            @Override
            public Dimension getPreferredScrollableViewportSize() {
                if (size != null) {
                    return new Dimension(size);
                }
                return super.getPreferredScrollableViewportSize();
            }
        };
        list.setFixedCellHeight(50);
        list.setFixedCellWidth(150);
        size = list.getPreferredScrollableViewportSize();
        size.width *= COLUMNS;
        list.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        list.setCellRenderer(new MyCellRenderer());
        list.setVisibleRowCount(0);
        list.setLayoutOrientation(JList.HORIZONTAL_WRAP);

        JFrame f = new JFrame("Files In the JList");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new JScrollPane(list));
        f.pack();
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                FilesInTheJList fITJL = new FilesInTheJList();
            }
        });
    }

    private static class MyCellRenderer extends JLabel implements ListCellRenderer {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getListCellRendererComponent(JList list, Object value,
                int index, boolean isSelected, boolean cellHasFocus) {
            if (value instanceof File) {
                File file = (File) value;
                setText(file.getName());
                setIcon(FileSystemView.getFileSystemView().getSystemIcon(file));
                if (isSelected) {
                    setBackground(list.getSelectionBackground());
                    setForeground(list.getSelectionForeground());
                } else {
                    setBackground(list.getBackground());
                    setForeground(list.getForeground());
                }
                setPreferredSize(new Dimension(250, 25));
                setEnabled(list.isEnabled());
                setFont(list.getFont());
                setOpaque(true);
            }
            return this;
        }
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Nice! I'll have to adapt that into FileBro as an alternative to the table view. But I don't understand the comment about the lost label. Both those codes worked fine for me here. – Andrew Thompson Aug 29 '11 at 02:24
  • BTW - The 1st code was more 'compact' on-screen. (a moment later) I understand why, now. Instead of `setPreferredSize(new Dimension(250, 25));` in the second code, how about `setBorder(new EmptyBorder(2,2,2,2));`? (adjust number for preference) – Andrew Thompson Aug 29 '11 at 02:30
  • @kleopatra that really imposible (then I accepted your down-voting) if a want to hold view for JList with horizontal orientations, for another (as I know) definitions for JList, this *** always swithing to the vertical ****, no idea how to solve, without dirty hack – mKorbel Aug 29 '11 at 09:02
  • @kleopatra please see my update, but still I can't override PreferredScrollableViewportSize correctly(only if I set there setFixedCellXxx), because is not implemeted for JList, also I tried setPrototypeCellValue for JList, but doesn't returns correct Dimnesion too – mKorbel Sep 28 '11 at 09:07
  • @mKorbel you have added a very nice code..will you please tell me how i will open file in a directory with default program...thanks in advance.. :) – Muhammad Saqlain Arif Jan 09 '14 at 11:32
  • @mKorbel in your given example where i will do that..i am new in java. – Muhammad Saqlain Arif Jan 09 '14 at 11:53
2

I don't quite understand what you're doing - it looks like you want to filter the content of the JList to be only files with the .txt extension. In that case, you're probably looking to implement a FilenameFilter that will cause list() to return a list of file names in a String[] that only matches what you specified.

For example,

public String[] ReadDirectory() {
    String path = "C://Documents and Settings/myfileTxt";

    String files = null;
    File folder = new File(path);
    FilenameFilter txtFilter = new TextFileFilter();
    String[] listOfFiles = folder.listFiles(txtFilter);

    return listOfFiles;
}



public class TextFileFilter extends FilenameFilter
{
    public boolean accept(File dir, String name)
    {
        if(name != null && name.endsWith(".txt"))
        {
            return true;
        }

        return false;
    }
}
no.good.at.coding
  • 20,221
  • 2
  • 60
  • 51
  • Given that a tree can hold `File` objects, I would suggest using a `FileFilter` instead of a `FilenameFilter`. See my answer for an example. Otherwise, +1 for not trying to get a list of all files, then filtering it into an expandable list ( like the question & 1st 2 replies ;). – Andrew Thompson Aug 28 '11 at 18:41
  • Ah, I see; I wasn't aware of that, thanks! And a +1 to you, for the SSCCE :) – no.good.at.coding Aug 28 '11 at 23:29
  • Actually you need to use `public class TextFileFilter implements FilenameFilter` instead of `public class TextFileFilter extends FilenameFilter` – zygimantus Jul 28 '15 at 08:12
1

Create list of strings List<String> fnames = new ArrayList<String>();, fill it with file names (fnames.add(files);), then set it to JList using list.setListData(fnames.toArray());. I guess that should work.

nidu
  • 549
  • 2
  • 18
1

Just edit your code like this,

public ArrayList<String> ReadDirectory() {
        String path = "C://Documents and Settings/myfileTxt";

        ArrayList<String> files = new ArrayList<String>();
        File folder = new File(path);
        File[] listOfFiles = folder.listFiles();

        for (int i = 0; i < listOfFiles.length; i++) {
            if (listOfFiles[i].isFile()) {
                files.add(listOfFiles[i].getName());
                if (files.endsWith(".txt") || files.endsWith(".TXT")) {
                    System.out.println(files);
                }
            }
        }
        return files;
    }

Which will return ArrayList object and then you can convert that ArrayList object to a normal array.

Something like this, Lets say your variable name is,

ArrayList<String> listData = new ArrayList<String>();

Just do this to convert it into normal array,

listData.toArray();
TeaCupApp
  • 11,316
  • 18
  • 70
  • 150