package bluej.utility;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.plaf.FileChooserUI;
import javax.swing.plaf.basic.BasicFileChooserUI;

import threadchecker.OnThread;
import threadchecker.Tag;
import bluej.Config;
import bluej.extensions.SourceType;
import bluej.pkgmgr.Package;
import bluej.utility.filefilter.DirectoryFilter;
import bluej.utility.filefilter.JavaSourceFilter;


| A file chooser for opening packages. | | Extends the behaviour of JFileChooser in the following ways: | | <ul> | <li>Only directories (either BlueJ packages or plain ones) are displayed. | <li>BlueJ packages are displayed with a different icon. | </ul> | | @author Michael Kolling | @author Axel Schmolitzky | @author Markus Ostman | @OnThread(Tag.Swing) class PackageChooser extends JFileChooser{ static private final Icon classIcon = Config.getFixedImageAsIcon("class-icon.png"); static private final Icon packageIcon = Config.getFixedImageAsIcon("package-icon.png"); static private final String previewLine1 = Config.getString("utility.packageChooser.previewPane1"); static private final String previewLine2 = Config.getString("utility.packageChooser.previewPane2"); private PackageDisplay displayPanel; private boolean allowNewFiles = true;
| Create a new PackageChooser. | | @param startDirectory the directory to start the package selection in. | @param preview whether to show the package structure preview pane | @param showArchives whether to allow choosing jar and zip files | public PackageChooser(File startDirectory, boolean preview, boolean showArchives) { super(startDirectory); if (showArchives) { setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); } else { setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); } setFileView(new PackageFileView()); if (preview) { displayPanel = new PackageDisplay(startDirectory); setAccessory(displayPanel); addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent e) { if (!(e.getNewValue() instanceof File)) { return; } File dir = (File)e.getNewValue(); if (dir == null) { return; } if (dir.getName().equals("")) { return; } displayPanel.setDisplayDirectory(dir.getAbsoluteFile()); } }); } }
| Set whether this chooser should allow new (non-existing) files to | be selected. This does not actually prevent the user from specifying | a non-existing file, it just tweaks UI behaviour a bit. | public void setAllowNewFiles(boolean allowNewFiles) { this.allowNewFiles = allowNewFiles; }
| (non-Javadoc) | @see javax.swing.JFileChooser#accept(java.io.File) | @Override public boolean accept(File f) { if (f.isDirectory()) return true; String fname = f.getName(); return fname.endsWith(".jar") || fname.endsWith(".JAR") || fname.endsWith(".zip") || fname.endsWith(".ZIP") || (Config.isGreenfoot() && (fname.endsWith(".gfar") || fname.endsWith(".GFAR") || fname.endsWith(".sb"))); }
| A directory was double-clicked. If this is a BlueJ package, consider | this a package selection and accept it as the "Open" action, otherwise | * just traverse into the directory. */ @Override public void setCurrentDirectory(File dir) // redefined{ if (Package.isPackage(dir)) { setSelectedFile(dir); super.approveSelection(); | |
} | |
else{ | | super.setCurrentDirectory(dir); | | if (allowNewFiles) { | | // Hack to make file chooser behave slightly nicer. The default behaviour is to put | | // the directory name, without a trailing slash, in the filename field. | | // See ticket #127 | | FileChooserUI ui = getUI(); | | if (ui instanceof BasicFileChooserUI) { | | BasicFileChooserUI mui = (BasicFileChooserUI) ui; | | mui.setFileName(""); } } } } /** * Approve the selection. We have this mainly so that derived classes * can call it... */ protected void approved() | | { | | super.approveSelection(); | | } | | class PackageDisplay extends JList | | { | | // number of lines at the top to display a header | | // explaining what the PackageDisplay is | | final int headerLines = 3; | | // index of the last class displayed (after this all list items are packages | | // and hence will have a different icon) | | int lastClass = 0; | | PackageDisplay(File displayDir) | | { | | this.setPreferredSize(new Dimension(150,200)); | | this.setCellRenderer(new MyListRenderer()); | | setDisplayDirectory(displayDir); | | } | | @Override | | protected void processMouseEvent(MouseEvent e) { | | } | | @Override | | protected void processMouseMotionEvent(MouseEvent e) { | | } | | public defVis void setDisplayDirectory(File displayDir) | | { | | if (displayDir == null) | | return; | | int maxDisplay = 3; | | File subDirs[] = displayDir.listFiles(new DirectoryFilter()); | | File srcFiles[] = displayDir.listFiles(new JavaSourceFilter()); | | List<String> listVec = new ArrayList<String>(); | | // headerLines is 3 | | listVec.add(previewLine1); | | listVec.add(previewLine2); | | listVec.add(" "); if (subDirs != null) { for (lastClass=0; lastClass<srcFiles.length && lastClass<maxDisplay; lastClass++) { String javaFileName = JavaNames.stripSuffix(srcFiles[lastClass].getName(), "." + SourceType.Java.toString().toLowerCase()); // check if the name would be a valid java name if (!JavaNames.isIdentifier(javaFileName)) | | continue; | | // files with a $ in them signify inner classes (which we want to ignore) | | if (javaFileName.indexOf('$') == -1) | | listVec.add(javaFileName); | | } | | } | | if (srcFiles != null) { | | for (int i=0; i<subDirs.length && i<maxDisplay; i++) { | | // first check if the directory name would be a valid package name | | if (!JavaNames.isIdentifier(subDirs[i].getName())) | | continue; | | listVec.add(subDirs[i].getName()); | | // now display sub sub dirs | | File subSubDirs[] = subDirs[i].listFiles(new DirectoryFilter()); | | if (subSubDirs != null) { | | for (int j=0; j<subSubDirs.length; j++) { | | // first check if the directory name would be a valid package name | | if (!JavaNames.isIdentifier(subSubDirs[j].getName())) | | continue; | | listVec.add(subDirs[i].getName() + "." + subSubDirs[j].getName()); } } } } setListData(listVec.toArray()); | | } | | class MyListRenderer extends DefaultListCellRenderer | | { | | @Override | | public Component getListCellRendererComponent(JList list, Object value, int index, | | boolean isSelected, boolean cellHasFocus) | | { | | Component s = super.getListCellRendererComponent(list, value, index, | | isSelected, cellHasFocus); | | if (index >= headerLines) { | | if ((index-headerLines) < lastClass) { | | ((JLabel)s).setIcon(classIcon); | | } | | else { | | ((JLabel)s).setIcon(packageIcon); | | } | | } | | return s; | | } | | } | | } | | }

.   - PackageChooser
.   PackageChooser
.   propertyChange
.   setAllowNewFiles
.   accept




117 neLoCode + 108 LoComm