package jmathlib.ui.swing; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.ListSelectionListener; import javax.swing.filechooser.FileSystemView; import javax.swing.plaf.metal.MetalIconFactory; import java.io.*; import java.util.*; public class WorkingDirectoryPanel extends JPanel { private JComboBox workingDirectory = new JComboBox(); private DefaultComboBoxModel workingDirectoryModel = new DefaultComboBoxModel(); private JButton setWorkingDirectory = new JButton(); private DefaultListModel listModel = new DefaultListModel(); private JList fileView = new JList(listModel); private ListSelectionListener fileViewSelectionListener; File filesDirectory; public WorkingDirectoryPanel() { initialiseGUI(); registerListeners(); File cwd = KeyHandler.runningReference.interpreter.globals.getFunctionManager().getWorkingDirectory(); if (cwd != null) { setWorkingDirectory(cwd, false); } } private void initialiseGUI() { setLayout(new GridBagLayout()); JLabel label = new JLabel("Working Directory:"); GridBagConstraints cons = new GridBagConstraints(); cons.gridx = 0; cons.gridy = 0; cons.gridwidth = 2; cons.weighty = 0.1; add(label, cons); workingDirectory.setModel(workingDirectoryModel); workingDirectory.setEditable(true); workingDirectory.setRenderer(createRender2()); workingDirectory.getMinimumSize().width = 2; workingDirectory.getMaximumSize().width = 40; cons.gridx = 0; cons.gridy = 1; cons.gridwidth = 1; cons.weightx = 1; cons.weighty = 0.1; cons.fill = GridBagConstraints.HORIZONTAL; cons.insets = new Insets(5, 5, 0, 0); add(workingDirectory, cons); setWorkingDirectory.setIcon(new MetalIconFactory.FolderIcon16()); cons.gridx = 1; cons.gridy = 1; cons.gridwidth = 2; cons.weightx = 0.1; cons.weighty = 0.1; cons.insets = new Insets(5, 5, 0, 0); add(setWorkingDirectory, cons); cons.gridx = 0; cons.gridy = 2; cons.gridwidth = 2; cons.weighty = 0.1; add(new JLabel("Files:"), cons); cons.gridx = 0; cons.gridy = 3; cons.gridwidth = 2; cons.insets = new Insets(5, 5, 0, 0); cons.fill = GridBagConstraints.BOTH; cons.weighty = 1; cons.gridheight = GridBagConstraints.REMAINDER; cons.gridwidth = GridBagConstraints.REMAINDER; add(new JScrollPane(this.fileView), cons); fileView.setCellRenderer(createRender()); } private void registerListeners() { KeyListener keyListener = new KeyAdapter() { @Override public void keyPressed(KeyEvent event) { if (event.getSource() == fileView) { if (event.getKeyCode() == KeyEvent.VK_ENTER) { if (fileView.getSelectedIndex() != -1) { Object sel = fileView.getSelectedValue(); if (sel instanceof UpDirectory) { UpDirectory up = (UpDirectory) sel; setWorkingDirectory(up.getDirectory(), false); } else if (sel instanceof File) { File file = (File) sel; if (file.isDirectory()) { setWorkingDirectory(file, false); return; } SwingGUI.runningReference.openFileInEditor(file); } } } } else if (event.getSource() == workingDirectory.getEditor().getEditorComponent()) { if (event.getKeyCode() == KeyEvent.VK_ENTER) { JTextField field = (JTextField) workingDirectory.getEditor().getEditorComponent(); String text = field.getText(); setWorkingDirectory(new File(text), true); } } } }; this.fileView.addKeyListener(keyListener); this.workingDirectory.getEditor().getEditorComponent().addKeyListener(keyListener); MouseAdapter selectionListener = new MouseAdapter() { @Override public void mouseClicked(MouseEvent event) { super.mouseClicked(event); if (event.getSource() == fileView) { if (event.getClickCount() >= 2) { Object c = fileView.getSelectedValue(); if (c instanceof UpDirectory) { UpDirectory up = (UpDirectory) c; setWorkingDirectory(up.getDirectory(), false); } else if (c instanceof File) { File file = (File) fileView.getSelectedValue(); if (file.isDirectory()) { setWorkingDirectory(file, false); } else SwingGUI.runningReference.openFileInEditor(file); } } } else if (event.getSource() == setWorkingDirectory) { JFileChooser jfc = new JFileChooser(); jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); int result = jfc.showOpenDialog(SwingGUI.runningReference); if (result == JFileChooser.APPROVE_OPTION && jfc.getSelectedFile() != null) { setWorkingDirectory(jfc.getSelectedFile(), true); } } } }; this.fileView.addMouseListener(selectionListener); this.setWorkingDirectory.addMouseListener(selectionListener); } private DefaultListCellRenderer createRender() { return new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel c = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value instanceof File) { c.setText(FileSystemView.getFileSystemView().getSystemDisplayName((File) value)); c.setToolTipText(((File) value).getPath()); c.setIcon(FileSystemView.getFileSystemView().getSystemIcon((File) value)); } else if (value instanceof UpDirectory) { UpDirectory ud = (UpDirectory) value; c.setText("../ (" + FileSystemView.getFileSystemView().getSystemDisplayName(ud.getDirectory()) + ")"); c.setToolTipText(ud.getDirectory().getAbsolutePath()); c.setIcon(FileSystemView.getFileSystemView().getSystemIcon(ud.getDirectory())); } return c; } }; } private DefaultListCellRenderer createRender2() { return new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel c = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value instanceof File) { c.setText(((File) value).getAbsolutePath()); c.setToolTipText(((File) value).getPath()); c.setIcon(FileSystemView.getFileSystemView().getSystemIcon((File) value)); } return c; } }; } public void setWorkingDirectory(File dir, boolean remember) { if (!dir.exists()) { JOptionPane.showMessageDialog(this, "Folder Does not Exist", "Error", JOptionPane.ERROR_MESSAGE); return; } if (!dir.isDirectory()) { JOptionPane.showMessageDialog(this, "Is not a Directory", "Error", JOptionPane.ERROR_MESSAGE); return; } //Set the working directory in Mathlib (to find function files) KeyHandler.runningReference.interpreter.globals.getFunctionManager().setWorkingDirectory(dir); //Update the list view (ie files in the current working directory) updateFileList(dir); //updating JComboBox working directory stuff if (remember) { File currentValue = (File)workingDirectory.getSelectedItem(); if (currentValue != null) updateDirectoryHistory(currentValue); } this.workingDirectory.setSelectedItem(dir.getAbsoluteFile()); } private void updateFileList(File currentWorkingDir) { listModel.removeAllElements(); if (!FileSystemView.getFileSystemView().isRoot(currentWorkingDir) && !FileSystemView.getFileSystemView().isFileSystemRoot(currentWorkingDir)) { UpDirectory up = new UpDirectory(FileSystemView.getFileSystemView().getParentDirectory(currentWorkingDir)); listModel.addElement(up); } File[] children = order(currentWorkingDir.listFiles(new EasyFileFilter(new String[]{".m"}, "MATHLAB Scripts (.m)", true))); for (int i = 0; i < children.length; i++) { listModel.addElement(children[i]); } } private void updateDirectoryHistory(File dir) { int index = workingDirectoryModel.getIndexOf(dir); if (index != -1) { //Bring the previous entry to the head of the history Object obj = workingDirectoryModel.getElementAt(index); workingDirectoryModel.removeElementAt(index); workingDirectory.insertItemAt(obj, 0); } else { if (workingDirectoryModel.getSize() > 10) { workingDirectoryModel.removeElementAt(workingDirectoryModel.getSize() - 1); } this.workingDirectory.insertItemAt(dir, 0); } } private File[] getFiles(File[] files) { int counter = 0; for (int i = 0; i < files.length; i++) { if (files[i].isFile()) { counter++; } } File[] only = new File[counter]; counter = 0; for (int i = 0; i < files.length; i++) { if (files[i].isFile()) { only[counter] = files[i]; counter++; } } return only; } private File[] getDirectorys(File[] files) { int counter = 0; for (int i = 0; i < files.length; i++) { if (files[i].isDirectory()) { counter++; } } File[] only = new File[counter]; counter = 0; for (int i = 0; i < files.length; i++) { if (files[i].isDirectory()) { only[counter] = files[i]; counter++; } } return only; } public File[] getOrderedCombined(File[] directorys, File[] files) { File[] ordered = new File[directorys.length + files.length]; //Arrays.copyOf(directorys, directorys.length + files.length); for (int i = 0; i < directorys.length; i++) { ordered[i] = directorys[i]; } int insertPoint = directorys.length; for (int i = 0; i < files.length; i++) { ordered[insertPoint] = files[i]; } return ordered; } public File[] order(File[] unordered) { return getOrderedCombined(getDirectorys(unordered), getFiles(unordered)); } public static class UpDirectory { private File directoryAbove; public UpDirectory(File directoryAbove) { if (directoryAbove == null) throw new IllegalArgumentException("Unexpected non-null directory"); this.directoryAbove = directoryAbove; } public File getDirectory() { return this.directoryAbove; } } }