package jmathlib.ui.swing; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.GridBagConstraints; import java.awt.Insets; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.filechooser.FileSystemView; import javax.swing.plaf.metal.MetalIconFactory; import jmathlib.core.functions.*; /** Panel that allows the user to change the application properties * TODO: Make this look nicer. Internationalise the strings. */ public class SearchPathSelection extends JPanel { public static final int OK_BUTTON = JOptionPane.OK_OPTION; public static final int CANCEL_BUTTON = JOptionPane.CANCEL_OPTION; private DefaultListModel model = new DefaultListModel(); private JList list = new JList(model); private JButton addButton = new JButton("Add"); private JButton removeButton = new JButton("Remove"); //TODO: Some nice graphics here. private JButton upButton = new JButton("^"); private JButton downButton = new JButton("v"); public SearchPathSelection() { init(); } //adds function loaders that are not already in the model public void addFunctionLoader(FileFunctionLoader fl) { if (!model.contains(fl)) { this.model.addElement(fl); } } public int getFunctionLoaderCount() { return model.getSize(); } public FileFunctionLoader getFunctionLoader(int index) { return (FileFunctionLoader) model.elementAt(index); } /* * blocks till dialog closed */ public static void showPathSelectionDialog(Component container) { SearchPathSelection p = new SearchPathSelection(); FunctionManager fm = KeyHandler.runningReference.interpreter.globals.getFunctionManager(); for (int i = 0; i < fm.getFunctionLoaderCount(); i++) { FunctionLoader fl = fm.getFunctionLoader(i); if (fl instanceof FileFunctionLoader) { p.addFunctionLoader((FileFunctionLoader) fl); } } if (JOptionPane.showConfirmDialog(container, p, "Select Search Paths", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE) == JOptionPane.OK_OPTION) { //Pass 1: Remove functionloaders that are not in the new set for (int i = 0; i < fm.getFunctionLoaderCount(); i++) { FunctionLoader fl = fm.getFunctionLoader(i); if (fl instanceof FileFunctionLoader) { boolean found = false; for (int j = 0; j < p.getFunctionLoaderCount(); j++) { if (p.getFunctionLoader(j).equals(fl)) { found = true; break; } } if (!found) { fm.removeFunctionLoader(fl); //Adjust loop (this is bad i know!) Better to use an Iterator. i--; } } } //Pass 2: Add new functionloaders in the new set for (int j = 0; j < p.getFunctionLoaderCount(); j++) { FileFunctionLoader fl = p.getFunctionLoader(j); if (j >= fm.getFunctionLoaderCount()) { fm.addFunctionLoader(fl); } else if (!fl.equals(fm.getFunctionLoader(j))) { fm.addFunctionLoaderAt(j, fl); } } } } private void init() { setPreferredSize(new Dimension(500, 250)); this.setLayout(new BorderLayout()); DefaultListCellRenderer render = 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); FileFunctionLoader f = (FileFunctionLoader) value; File basePath = f.getBaseDirectory(); if (FileSystemView.getFileSystemView().isFileSystem(basePath)) { c.setText(basePath.toString()); } else { c.setText(FileSystemView.getFileSystemView().getSystemDisplayName(basePath)); } c.setToolTipText(basePath.getPath()); if (f.isSystemLoader()) { c.setEnabled(false); } else { c.setEnabled(true); } return c; } }; this.list.setCellRenderer(render); this.add(new JScrollPane(list), BorderLayout.CENTER); JPanel buttonContainer = new JPanel(); this.add(buttonContainer, BorderLayout.EAST); GridBagLayout glayout = new GridBagLayout(); buttonContainer.setLayout(glayout); addButton.setIcon(new MetalIconFactory.FolderIcon16()); removeButton.setIcon(new MetalIconFactory.PaletteCloseIcon()); GridBagConstraints cons = new GridBagConstraints(); cons.gridx = 0; cons.gridy = 0; cons.insets = new Insets(5, 5, 5, 5); cons.fill = GridBagConstraints.HORIZONTAL; cons.anchor = GridBagConstraints.CENTER; buttonContainer.add(upButton, cons); cons.gridy = 1; buttonContainer.add(downButton, cons); cons.gridx = 1; cons.gridy = 0; buttonContainer.add(addButton, cons); cons.gridy = 1; buttonContainer.add(removeButton, cons); final Component container = this; MouseAdapter mouseListener = new MouseAdapter() { @Override public void mouseReleased(MouseEvent event) { super.mouseReleased(event); if (event.getSource() == addButton) { JFileChooser jfc = new JFileChooser(); jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); jfc.setMultiSelectionEnabled(true); int result = jfc.showOpenDialog(SwingGUI.runningReference); if (result == JFileChooser.APPROVE_OPTION) { File[] dirs = jfc.getSelectedFiles(); if (dirs != null) { for (int i = 0; i < dirs.length; i++) { addFunctionLoader(new FileFunctionLoader(dirs[i], false)); } } } } else if (event.getSource() == removeButton) { if (list.getSelectedIndex() != -1) { FileFunctionLoader fl = (FileFunctionLoader) model.elementAt(list.getSelectedIndex()); if (fl.isSystemLoader()) { JOptionPane.showMessageDialog(container, "Cannot remove a System Function Loader"); } else { model.remove(list.getSelectedIndex()); } } } else if (event.getSource() == upButton) { int selIndex = list.getSelectedIndex(); if (selIndex != -1 && selIndex > 0) { int newIndex = selIndex - 1; Object src = model.elementAt(selIndex); Object dst = model.elementAt(newIndex); model.setElementAt(dst, selIndex); model.setElementAt(src, newIndex); list.setSelectedIndex(newIndex); } } else if (event.getSource() == downButton) { int selIndex = list.getSelectedIndex(); if ((selIndex != -1) && selIndex < (model.getSize() - 1)) { int newIndex = selIndex + 1; Object src = model.elementAt(selIndex); Object dst = model.elementAt(newIndex); model.setElementAt(dst, selIndex); model.setElementAt(src, newIndex); list.setSelectedIndex(newIndex); } } } }; addButton.addMouseListener(mouseListener); removeButton.addMouseListener(mouseListener); upButton.addMouseListener(mouseListener); downButton.addMouseListener(mouseListener); } }