package de.uni_passau.fim.infosun.prophet.util.settings.components; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTextField; import javax.swing.SwingUtilities; import de.uni_passau.fim.infosun.prophet.util.qTree.Attribute; import de.uni_passau.fim.infosun.prophet.util.settings.Setting; import static de.uni_passau.fim.infosun.prophet.util.language.UIElementNames.getLocalized; /** * A <code>Setting</code> that uses a <code>JFileChooser</code> enable choosing a path. The chosen path will be * displayed in a <code>JTextField</code>. */ public class PathChooserSetting extends Setting { /** * The type of path to enable choosing. */ public enum Type { /** * Enable choosing file paths only. */ FILES(JFileChooser.FILES_ONLY), /** * Enable choosing directory paths only. */ DIRECTORIES(JFileChooser.DIRECTORIES_ONLY), /** * Enable choosing directory or file paths. */ BOTH(JFileChooser.FILES_AND_DIRECTORIES); private int mode; /** * Constructs a new <code>PathChooserSetting.Type</code> containing the given constant. * * @param mode * should be one of {@link javax.swing.JFileChooser#FILES_ONLY}, * {@link javax.swing.JFileChooser#DIRECTORIES_ONLY}, * {@link javax.swing.JFileChooser#FILES_AND_DIRECTORIES} */ Type(int mode) { this.mode = mode; } /** * Returns the <code>JFileChooser</code> magic int constant appropriate for the type. * * @return the appropriate constant */ public int getMode() { return mode; } } private Type type; private JLabel caption; private JTextField textField; /** * Constructs a new <code>PathChooserSetting</code> for the given <code>Attribute</code>. * If <code>borderDesc</code> is not <code>null</code> this <code>JPanel</code> will be surrounded by a titled * border with the given title. This <code>PathChooserSetting</code> will only allow choosing files. * * @param attribute * the <code>Attribute</code> for this <code>Setting</code> * @param borderDesc * the title for the border or <code>null</code> for no border */ public PathChooserSetting(Attribute attribute, String borderDesc) { this(attribute, borderDesc, Type.FILES); } /** * Constructs a new <code>PathChooserSetting</code> for the given <code>Attribute</code>. * If <code>borderDesc</code> is not <code>null</code> this <code>JPanel</code> will be surrounded by a titled * border with the given title. Using the <code>type</code> argument the <code>JFileChooser</code> can * be configured to allow choosing files, directories or both. * * @param attribute * the <code>Attribute</code> for this <code>Setting</code> * @param borderDesc * the title for the border or <code>null</code> for no border * @param type * the type of path that can be chosen */ public PathChooserSetting(Attribute attribute, String borderDesc, Type type) { super(attribute, borderDesc); JButton pathButton; this.type = type; caption = new JLabel(); add(caption, BorderLayout.NORTH); textField = new JTextField(); textField.setColumns(20); add(textField, BorderLayout.CENTER); pathButton = new JButton(getLocalized("BUTTON_LABEL_FIND")); pathButton.addActionListener(this::choose); add(pathButton, BorderLayout.EAST); } /** * Used as an <code>ActionListener</code> for the button that displays the path chooser. * * @param event * the <code>ActionEvent</code> produced by the button, ignored by this method */ private void choose(ActionEvent event) { File workingDir = new File("."); JFileChooser fc = new JFileChooser(workingDir); fc.setFileSelectionMode(type.getMode()); if (fc.showSaveDialog(SwingUtilities.getRoot(this)) == JFileChooser.APPROVE_OPTION) { String selectedPath; try { selectedPath = fc.getSelectedFile().getCanonicalPath(); } catch (IOException e) { e.printStackTrace(); return; } String currentPath; try { currentPath = workingDir.getCanonicalPath(); } catch (IOException e) { e.printStackTrace(); return; } if (selectedPath.startsWith(currentPath)) { selectedPath = selectedPath.substring(currentPath.length() + 1); JOptionPane.showMessageDialog(null, getLocalized("MESSAGE_RELATIVE_PATH_NOTIFICATION")); } textField.setText(selectedPath); } } @Override public void setCaption(String cap) { caption.setText(cap); } @Override public void loadValue() { textField.setText(attribute.getValue()); } @Override public void saveValue() { attribute.setValue(textField.getText()); } }