Clojure dialog box for file selection with filter for files' extensions
Asked Answered
H

2

7

This is a continuous crawling for a lipster beginner on Clojure and Java. I have this code to select a file, but I would like to filter the files' extensions that I am looking for.

(import javax.swing.JFileChooser)
(defn tlt-get-file [ ]
       (let [ filechooser (JFileChooser. "C:/") 
              retval (.showOpenDialog filechooser nil) ]
          (if (= retval JFileChooser/APPROVE_OPTION)
             (do 
                (println (.getSelectedFile filechooser))
                (.getSelectedFile filechooser))
              "")))

Your help always much appreciated.

Humus answered 17/11, 2011 at 19:13 Comment(1)
If you're planning on spending much time doing UIs in Clojure, you'll want to take a look at a lib like Seesaw (github.com/daveray/seesaw). There, this is just (choose-file :dir "C:/" :filters [["Images" ["png" "jpeg"]]]). Welcome to Clojure :)Neolamarckism
S
7
(import '(javax.swing JFileChooser)
        '(javax.swing.filechooser FileNameExtensionFilter))
(defn tlt-get-file [ ]
       (let [ extFilter (FileNameExtensionFilter. "Text File" (into-array  ["txt"]))
              filechooser (JFileChooser. "C:/")
              dummy (.setFileFilter filechooser extFilter)
              retval (.showOpenDialog filechooser nil) ]
          (if (= retval JFileChooser/APPROVE_OPTION)
             (do 
                (println (.getSelectedFile filechooser))
                (.getSelectedFile filechooser))
              "")))
Sunbow answered 17/11, 2011 at 22:6 Comment(0)
O
3

You need to set the file filter, which you can do either by extending the FileFilter class, or using a built-in implementation like FileNameExtensionFilter. Note that the FNEF takes variable arguments in Java, which means that it takes an array in actual JVM bytecode. So something like

(FileNameExtensionFilter. 
 "Text files only"
 (into-array ["txt"]))

would be a simple, reasonable filter.

Or if you would rather do something more specialized, like only accept extensions which have a J in them, you can implement the filtering yourself. Sadly, Java chose to make this a 100% abstract class instead of an interface, so you can't use reify. In an ideal world you could write

(reify java.io.FileFilter
  (getDescription [this] "Java loves Js!")
  (accept [this f]
    (boolean (re-find #"\..*j[^.]*$" (.getName f)))))

but Java loves classes, so instead you need

(proxy [java.io.FileFilter] []
  (getDescription [] "Java loves Js!")
  (accept [f]
    (boolean (re-find #"\..*j[^.]*$" (.getName f)))))
Ottinger answered 17/11, 2011 at 19:54 Comment(2)
Thanks for your very fast answer amalloy!! As I said, excuse my ignorance, but I am 'crawling' on Clojure and have zip Java experience. My question is how do I implement your solutions into my code?Humus
(.setFileFilter filechooser (some-file-filter-thingy)) before you open the dialog. That should be all it takes.Ottinger

© 2022 - 2024 — McMap. All rights reserved.