Java tutorial
/* Copyright (C) 2005-2015 JabRef contributors. Copyright (C) 2005 Andreas Rudert, based on ExportCustomizationDialog by ?? This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package net.sf.jabref.importer; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.zip.ZipFile; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.BorderFactory; import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableColumnModel; import net.sf.jabref.Globals; import net.sf.jabref.gui.FileDialogs; import net.sf.jabref.gui.JabRefFrame; import net.sf.jabref.gui.help.HelpAction; import net.sf.jabref.gui.help.HelpFile; import net.sf.jabref.gui.keyboard.KeyBinding; import net.sf.jabref.gui.util.FocusRequester; import net.sf.jabref.importer.fileformat.ImportFormat; import net.sf.jabref.logic.l10n.Localization; import net.sf.jabref.preferences.JabRefPreferences; import com.jgoodies.forms.builder.ButtonBarBuilder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Dialog to manage custom importers. */ public class ImportCustomizationDialog extends JDialog { // Column widths for import customization dialog table: private static final int COL_0_WIDTH = 200; private static final int COL_1_WIDTH = 80; private static final int COL_2_WIDTH = 200; private static final int COL_3_WIDTH = 200; private final JTable customImporterTable; private static final Log LOGGER = LogFactory.getLog(ImportCustomizationDialog.class); /** * * @param frame */ public ImportCustomizationDialog(final JabRefFrame frame) { super(frame, Localization.lang("Manage custom imports"), false); ImportTableModel tableModel = new ImportTableModel(); customImporterTable = new JTable(tableModel); TableColumnModel cm = customImporterTable.getColumnModel(); cm.getColumn(0).setPreferredWidth(COL_0_WIDTH); cm.getColumn(1).setPreferredWidth(COL_1_WIDTH); cm.getColumn(2).setPreferredWidth(COL_2_WIDTH); cm.getColumn(3).setPreferredWidth(COL_3_WIDTH); JScrollPane sp = new JScrollPane(customImporterTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); customImporterTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); customImporterTable.setPreferredScrollableViewportSize(getSize()); if (customImporterTable.getRowCount() > 0) { customImporterTable.setRowSelectionInterval(0, 0); } JButton addFromFolderButton = new JButton(Localization.lang("Add from folder")); addFromFolderButton.addActionListener(e -> { CustomImporter importer = new CustomImporter(); importer.setBasePath(FileDialogs.getNewDir(frame, new File(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)), Collections.emptyList(), Localization.lang("Select Classpath of New Importer"), JFileChooser.CUSTOM_DIALOG, false)); String chosenFileStr = null; if (importer.getBasePath() != null) { chosenFileStr = FileDialogs.getNewFile(frame, importer.getFileFromBasePath(), Collections.singletonList(".class"), Localization.lang("Select new ImportFormat subclass"), JFileChooser.CUSTOM_DIALOG, false); } if (chosenFileStr != null) { try { importer.setClassName(pathToClass(importer.getFileFromBasePath(), new File(chosenFileStr))); importer.setName(importer.getInstance().getFormatName()); importer.setCliId(importer.getInstance().getId()); addOrReplaceImporter(importer); customImporterTable.revalidate(); customImporterTable.repaint(); } catch (Exception exc) { JOptionPane.showMessageDialog(frame, Localization.lang("Could not instantiate %0", chosenFileStr)); } catch (NoClassDefFoundError exc) { JOptionPane.showMessageDialog(frame, Localization.lang( "Could not instantiate %0. Have you chosen the correct package path?", chosenFileStr)); } } }); addFromFolderButton .setToolTipText(Localization.lang("Add a (compiled) custom ImportFormat class from a class path.") + "\n" + Localization.lang("The path need not be on the classpath of JabRef.")); JButton addFromJarButton = new JButton(Localization.lang("Add from jar")); addFromJarButton.addActionListener(e -> { String basePath = FileDialogs.getNewFile(frame, new File(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)), Arrays.asList(".zip", ".jar"), Localization.lang("Select a Zip-archive"), JFileChooser.CUSTOM_DIALOG, false); if (basePath != null) { try (ZipFile zipFile = new ZipFile(new File(basePath), ZipFile.OPEN_READ)) { ZipFileChooser zipFileChooser = new ZipFileChooser(this, zipFile); zipFileChooser.setVisible(true); customImporterTable.revalidate(); customImporterTable.repaint(10); } catch (IOException exc) { LOGGER.info("Could not open Zip-archive.", exc); JOptionPane.showMessageDialog(frame, Localization.lang("Could not open %0", basePath) + "\n" + Localization.lang("Have you chosen the correct package path?")); } catch (NoClassDefFoundError exc) { LOGGER.info("Could not instantiate Zip-archive reader.", exc); JOptionPane.showMessageDialog(frame, Localization.lang("Could not instantiate %0", basePath) + "\n" + Localization.lang("Have you chosen the correct package path?")); } } }); addFromJarButton .setToolTipText(Localization.lang("Add a (compiled) custom ImportFormat class from a Zip-archive.") + "\n" + Localization.lang("The Zip-archive need not be on the classpath of JabRef.")); JButton showDescButton = new JButton(Localization.lang("Show description")); showDescButton.addActionListener(e -> { int row = customImporterTable.getSelectedRow(); if (row == -1) { JOptionPane.showMessageDialog(frame, Localization.lang("Please select an importer.")); } else { CustomImporter importer = ((ImportTableModel) customImporterTable.getModel()).getImporter(row); try { ImportFormat importFormat = importer.getInstance(); JOptionPane.showMessageDialog(frame, importFormat.getDescription()); } catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException exc) { LOGGER.warn("Could not instantiate importer " + importer.getName(), exc); JOptionPane.showMessageDialog(frame, Localization.lang("Could not instantiate %0 %1", importer.getName() + ":\n", exc.getMessage())); } } }); JButton removeButton = new JButton(Localization.lang("Remove")); removeButton.addActionListener(e -> { int row = customImporterTable.getSelectedRow(); if (row == -1) { JOptionPane.showMessageDialog(frame, Localization.lang("Please select an importer.")); } else { customImporterTable.removeRowSelectionInterval(row, row); Globals.prefs.customImports .remove(((ImportTableModel) customImporterTable.getModel()).getImporter(row)); Globals.IMPORT_FORMAT_READER.resetImportFormats(); customImporterTable.revalidate(); customImporterTable.repaint(); } }); Action closeAction = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { dispose(); } }; JButton closeButton = new JButton(Localization.lang("Close")); closeButton.addActionListener(closeAction); JButton helpButton = new HelpAction(HelpFile.CUSTOM_IMPORTS).getHelpButton(); // Key bindings: JPanel mainPanel = new JPanel(); ActionMap am = mainPanel.getActionMap(); InputMap im = mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); im.put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE_DIALOG), "close"); am.put("close", closeAction); mainPanel.setLayout(new BorderLayout()); mainPanel.add(sp, BorderLayout.CENTER); JPanel buttons = new JPanel(); ButtonBarBuilder bb = new ButtonBarBuilder(buttons); buttons.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); bb.addGlue(); bb.addButton(addFromFolderButton); bb.addButton(addFromJarButton); bb.addButton(showDescButton); bb.addButton(removeButton); bb.addButton(closeButton); bb.addUnrelatedGap(); bb.addButton(helpButton); bb.addGlue(); getContentPane().add(mainPanel, BorderLayout.CENTER); getContentPane().add(buttons, BorderLayout.SOUTH); this.setSize(getSize()); pack(); this.setLocationRelativeTo(frame); new FocusRequester(customImporterTable); } /* * (non-Javadoc) * @see java.awt.Component#getSize() */ @Override public Dimension getSize() { int width = COL_0_WIDTH + COL_1_WIDTH + COL_2_WIDTH + COL_3_WIDTH; return new Dimension(width, width / 2); } /** * Converts a path relative to a base-path into a class name. * * @param basePath base path * @param path path that includes base-path as a prefix * @return class name */ private static String pathToClass(File basePath, File path) { String className = null; File actualPath = path; // remove leading basepath from path while (!actualPath.equals(basePath)) { className = actualPath.getName() + (className == null ? "" : "." + className); actualPath = actualPath.getParentFile(); } if (className != null) { int lastDot = className.lastIndexOf('.'); if (lastDot < 0) { return className; } className = className.substring(0, lastDot); } return className; } /** * Adds an importer to the model that underlies the custom importers. * * @param importer importer */ public void addOrReplaceImporter(CustomImporter importer) { Globals.prefs.customImports.replaceImporter(importer); Globals.IMPORT_FORMAT_READER.resetImportFormats(); ((ImportTableModel) customImporterTable.getModel()).fireTableDataChanged(); } /** * Table model for the custom importer table. */ private class ImportTableModel extends AbstractTableModel { private final String[] columnNames = new String[] { Localization.lang("Import name"), Localization.lang("Command line id"), Localization.lang("ImportFormat class"), Localization.lang("Contained in") }; @Override public Object getValueAt(int rowIndex, int columnIndex) { Object value = null; CustomImporter importer = getImporter(rowIndex); if (columnIndex == 0) { value = importer.getName(); } else if (columnIndex == 1) { value = importer.getClidId(); } else if (columnIndex == 2) { value = importer.getClassName(); } else if (columnIndex == 3) { value = importer.getFileFromBasePath(); } return value; } @Override public int getColumnCount() { return columnNames.length; } @Override public int getRowCount() { return Globals.prefs.customImports.size(); } @Override public String getColumnName(int col) { return columnNames[col]; } public CustomImporter getImporter(int rowIndex) { CustomImporter[] importers = Globals.prefs.customImports .toArray(new CustomImporter[Globals.prefs.customImports.size()]); return importers[rowIndex]; } } }