/* * Zettelkasten - nach Luhmann * Copyright (C) 2001-2015 by Daniel Lüdecke (http://www.danielluedecke.de) * * Homepage: http://zettelkasten.danielluedecke.de * * * 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 3 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, see <http://www.gnu.org/licenses/>. * * * Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU * General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben * und/oder modifizieren, entweder gemäß Version 3 der Lizenz oder (wenn Sie möchten) * jeder späteren Version. * * Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen von Nutzen sein * wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder * der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der * GNU General Public License. * * Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm * erhalten haben. Falls nicht, siehe <http://www.gnu.org/licenses/>. */ package de.danielluedecke.zettelkasten; import bibtex.dom.BibtexEntry; import de.danielluedecke.zettelkasten.util.classes.InitStatusbarForTasks; import de.danielluedecke.zettelkasten.database.Settings; import de.danielluedecke.zettelkasten.database.BibTex; import de.danielluedecke.zettelkasten.util.Tools; import de.danielluedecke.zettelkasten.util.Constants; import de.danielluedecke.zettelkasten.database.Daten; import com.explodingpixels.macwidgets.MacWidgetFactory; import com.explodingpixels.widgets.TableUtils; import de.danielluedecke.zettelkasten.util.ColorUtil; import de.danielluedecke.zettelkasten.util.FileOperationsUtil; import de.danielluedecke.zettelkasten.util.PlatformUtil; import de.danielluedecke.zettelkasten.util.classes.Comparer; import java.awt.FileDialog; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.ListIterator; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JTable; import javax.swing.KeyStroke; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableModel; import javax.swing.table.TableRowSorter; import org.jdesktop.application.Action; import org.jdesktop.application.Application; import org.jdesktop.application.ApplicationContext; import org.jdesktop.application.Task; import org.jdesktop.application.TaskMonitor; import org.jdesktop.application.TaskService; /** * * @author danielludecke */ public class CImportBibTex extends javax.swing.JDialog { /** * */ private Settings settingsObj; /** * */ private BibTex bibtexObj; /** * */ private Daten dataObj; /** * When the user wants to re-import bibtex-entries, abstracts/annotations of bibtex-entries that * create a new entry can be a) added as new entry, b) replace an existing entry that already * has been created from a bibtex-abstract or c) added to that existing entry. * <br><br> * The user's choice, made in {@link #addSelectedAuthors() addSelectedAuthors()}, is stored in * this variable */ private int updateOption = -1; /** * The constants for the options stored in {@link #updateOption updateOption}. */ private static final int UPDATE_OPTION_REPLACE = 0; private static final int UPDATE_OPTION_NEW = 1; private static final int UPDATE_OPTION_CONCAT = 2; private static final int UPDATE_OPTION_CANCEL = 3; public static final int BIBTEX_SOURCE_FILE = 1; public static final int BIBTEX_SOURCE_DB = 2; private ZettelkastenView mainframe; /** * This array-list contains all entry-numbers of those entries that have been modified during * the import-operation, e.g. if bibtex-entries contained abstracts and the user chose to modify * existing entries. */ private ArrayList<Integer> modifiedEntries; /** * This array-list contains all entry-numbers of those entries that have been modified during * the import-operation, e.g. if bibtex-entries contained abstracts and the user chose to modify * existing entries. * * @return all entry-numbers of those entries that have been modified during the * import-operation */ public ArrayList<Integer> getModifiedEntries() { return modifiedEntries; } /** * This variable stores the amount of entries that have been added during the import-operation * (i.e. which are new), e.g. if bibtex-entries contained abstacts and the user chose to create * new entries. */ private int newEntries = 0; /** * In case any bibtex-entries have been imported, this method returns the count of new added / * imported entries. * * @return The amount of imported entries. */ public int getNewEntriesCount() { return newEntries; } /** * */ private LinkedList<Object[]> linkedtablelist = null; /** * get the strings for file descriptions from the resource map */ private org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(de.danielluedecke.zettelkasten.ZettelkastenApp.class). getContext().getResourceMap(CImportBibTex.class); /** * * @param parent * @param mf * @param d * @param bt * @param s */ public CImportBibTex(java.awt.Frame parent, ZettelkastenView mf, Daten d, BibTex bt, Settings s) { super(parent); settingsObj = s; bibtexObj = bt; dataObj = d; mainframe = mf; initComponents(); initComboBox(); initBorders(settingsObj); // set combobox items jComboBoxShowBibTex.setModel(new javax.swing.DefaultComboBoxModel(new String[]{ resourceMap.getString("comboBoxItem1"), resourceMap.getString("comboBoxItem2"), resourceMap.getString("comboBoxItem3") })); // set application icon setIconImage(Constants.zknicon.getImage()); // set last settings switch (settingsObj.getLastUsedBibtexImportSource()) { case BIBTEX_SOURCE_DB: jRadioButtonSourceDB.setSelected(true); break; case BIBTEX_SOURCE_FILE: jRadioButtonSourceFile.setSelected(true); break; default: jRadioButtonSourceDB.setSelected(true); break; } initListeners(); initTable(); // init the progressbar and animated icon for background tasks InitStatusbarForTasks isb = new InitStatusbarForTasks(statusLabel, null, null); // initially, disable apply button jButtonApply.setEnabled(false); // if we have mac os x with aqua-look&feel, make certain components look like mac... if (settingsObj.isMacAqua() || settingsObj.isSeaGlass()) { // make button smaller... jButtonSelectAll.putClientProperty("JButton.buttonType", "roundRect"); // textfield should look like search-textfield... jTextFieldFilterTable.putClientProperty("JTextField.variant", "search"); if (settingsObj.isSeaGlass()) { jButtonApply.putClientProperty("JComponent.sizeVariant", "small"); jButtonBrowseBibtex.putClientProperty("JComponent.sizeVariant", "small"); jButtonCancel.putClientProperty("JComponent.sizeVariant", "small"); jButtonSelectAll.putClientProperty("JComponent.sizeVariant", "small"); } } if (jRadioButtonSourceFile.isSelected()) { // retrieve filepath of currently attached file, if any... File cuf = bibtexObj.getCurrentlyAttachedFile(); File luf = bibtexObj.getFilePath(); // and set it as initial value to the textfield if (cuf != null && cuf.exists()) { jTextFieldBibtexFilepath.setText(cuf.toString()); fillBibtexTable(); } else if (luf != null && luf.exists()) { jTextFieldBibtexFilepath.setText(luf.toString()); fillBibtexTable(); } } else { fillBibtexTable(); } jButtonRefresh.setEnabled(false); } private void initBorders(Settings settingsObj) { /* * Constructor for Matte Border * public MatteBorder(int top, int left, int bottom, int right, Color matteColor) */ jScrollPane1.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, ColorUtil.getBorderGray(settingsObj))); } private void initTable() { // create new table sorter TableRowSorter<TableModel> sorter = new TableRowSorter<>(); // tell tgis jtable that it has an own sorter jTableBibEntries.setRowSorter(sorter); // and tell the sorter, which table model to sort. sorter.setModel((DefaultTableModel) jTableBibEntries.getModel()); // in this table, the first column needs a custom comparator. try { sorter.setComparator(0, new Comparer()); sorter.setComparator(1, new Comparer()); } catch (IndexOutOfBoundsException e) { Constants.zknlogger.log(Level.WARNING, e.getLocalizedMessage()); } // noe header re-ordering jTableBibEntries.getTableHeader().setReorderingAllowed(false); // apply grid-settings and cellspacing jTableBibEntries.setGridColor(settingsObj.getTableGridColor()); jTableBibEntries.setShowHorizontalLines(settingsObj.getShowGridHorizontal()); jTableBibEntries.setShowVerticalLines(settingsObj.getShowGridVertical()); jTableBibEntries.setIntercellSpacing(settingsObj.getCellSpacing()); // get the default fontsize for tables and lists int defaultsize = settingsObj.getTableFontSize(); // only set new fonts, when fontsize differs from the initial value if (defaultsize > 0) { // get current font Font f = jTableBibEntries.getFont(); // create new font, add fontsize-value f = new Font(f.getName(), f.getStyle(), f.getSize() + defaultsize); // set new font jTableBibEntries.setFont(f); } // make extra table-sorter for itunes-tables if (settingsObj.isMacAqua()) { // make extra table-sorter for itunes-tables TableUtils.SortDelegate sortDelegate = new TableUtils.SortDelegate() { @Override public void sort(int columnModelIndex, TableUtils.SortDirection sortDirection) { } }; TableUtils.makeSortable(jTableBibEntries, sortDelegate); // set back default resize mode jTableBibEntries.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); } } /** * Here we set all available character-encodings for the bibtex-file. each reference-manager * (jabref, refworks, citavi) has its own character-encoding, so we have to take this into * account when importing bibtex-files. */ private void initComboBox() { // reset combobox jComboBoxEncoding.removeAllItems(); // add items that show the bibtex-encodings for (String s : Constants.BIBTEX_DESCRIPTIONS) { jComboBoxEncoding.addItem(s); } try { // auto-select last used format, when we auto-load the last used bibtex-file jComboBoxEncoding.setSelectedIndex(settingsObj.getLastUsedBibtexFormat()); } catch (IllegalArgumentException e) { Constants.zknlogger.log(Level.WARNING, e.getLocalizedMessage()); } // reset combobox that contains the citation styles jComboBoxCiteStyle.removeAllItems(); // add values for citation styles jComboBoxCiteStyle.addItem(resourceMap.getString("citeStyleGeneral")); jComboBoxCiteStyle.addItem(resourceMap.getString("citeStyleCBE")); jComboBoxCiteStyle.addItem(resourceMap.getString("citeStyleAPA")); try { // auto-select last used cite style, when we auto-load the last used bibtex-file jComboBoxCiteStyle.setSelectedIndex(bibtexObj.getCiteStyle()); } catch (IllegalArgumentException e) { Constants.zknlogger.log(Level.WARNING, e.getLocalizedMessage()); } } /** * Init several listeners for the components. */ private void initListeners() { // these codelines add an escape-listener to the dialog. so, when the user // presses the escape-key, the same action is performed as if the user // presses the cancel button... KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); ActionListener cancelAction = new java.awt.event.ActionListener() { @Override public void actionPerformed(ActionEvent evt) { cancel(); } }; getRootPane().registerKeyboardAction(cancelAction, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); // when the radio-button for file-input is selected, we want to enable its related // components and disable all the stuff for the manual-selection-radio-button jComboBoxEncoding.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionEvent evt) { if (jComboBoxEncoding.getSelectedIndex() != -1) { settingsObj.setLastUsedBibtexFormat(jComboBoxEncoding.getSelectedIndex()); } } }); jComboBoxCiteStyle.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionEvent evt) { if (jComboBoxCiteStyle.getSelectedIndex() != -1) { // change cite-style-setting bibtexObj.setCiteStyle(jComboBoxCiteStyle.getSelectedIndex()); // if we already have any attached bibtex-file, upate table fillBibtexTable(); } } }); jComboBoxShowBibTex.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionEvent evt) { fillBibtexTable(); } }); SelectionListener listener = new SelectionListener(); jTableBibEntries.getSelectionModel().addListSelectionListener(listener); jTableBibEntries.getColumnModel().getSelectionModel().addListSelectionListener(listener); jTextFieldFilterTable.addKeyListener(new java.awt.event.KeyAdapter() { @Override public void keyReleased(java.awt.event.KeyEvent evt) { if (Tools.isNavigationKey(evt.getKeyCode())) { // if user pressed navigation key, select next table entry de.danielluedecke.zettelkasten.util.TableUtils.navigateThroughList(jTableBibEntries, evt.getKeyCode()); } else { // select table-entry live, while the user is typing... de.danielluedecke.zettelkasten.util.TableUtils.selectByTyping(jTableBibEntries, jTextFieldFilterTable, 1); } } }); // when the radio.button for manual input is selected, we want to enable its related // components and disable all the stuff for the file-selection-radio-button jRadioButtonSourceDB.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionEvent evt) { fillBibtexTable(); settingsObj.setLastUsedBibtexImportSource(BIBTEX_SOURCE_DB); } }); // when the radio.button for manual input is selected, we want to enable its related // components and disable all the stuff for the file-selection-radio-button jRadioButtonSourceFile.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionEvent evt) { fillBibtexTable(); settingsObj.setLastUsedBibtexImportSource(BIBTEX_SOURCE_FILE); } }); // create action which should be executed when the user presses // the enter-key AbstractAction a_enter = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { if (jTextFieldFilterTable == e.getSource()) { filterList(false); } } }; // put action to the textfield's actionmaps jTextFieldFilterTable.getActionMap().put("EnterKeyPressed", a_enter); // associate enter-keystroke with that action KeyStroke ks = KeyStroke.getKeyStroke("ENTER"); jTextFieldFilterTable.getInputMap().put(ks, "EnterKeyPressed"); // create action which should be executed when the user presses // the alt + enter-key (reg ex search) AbstractAction a_regex_enter = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { if (jTextFieldFilterTable == e.getSource()) { filterList(true); } } }; // put action to the textfield's actionmaps jTextFieldFilterTable.getActionMap().put("RegExEnterKeyPressed", a_regex_enter); // associate enter-keystroke with that action ks = KeyStroke.getKeyStroke("alt ENTER"); jTextFieldFilterTable.getInputMap().put(ks, "RegExEnterKeyPressed"); // create action which should be executed when the user presses // the delete/backspace-key AbstractAction a_delete = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { if (jTableBibEntries == e.getSource()) { deleteBibtexEntry(); } } }; // put action to the tables' actionmaps jTableBibEntries.getActionMap().put("DeleteKeyPressed", a_delete); // check for os, and use appropriate controlKey ks = KeyStroke.getKeyStroke((PlatformUtil.isMacOS()) ? "BACK_SPACE" : "DELETE"); jTableBibEntries.getInputMap().put(ks, "DeleteKeyPressed"); } private void deleteBibtexEntry() { // get the selected rows int[] rows = jTableBibEntries.getSelectedRows(); // if we have no selected values, leave method if (rows.length < 1) { return; } // ask whether bibtex entries really should be removed int option = JOptionPane.showConfirmDialog(null, resourceMap.getString("removeBibtexEntryMsg"), resourceMap.getString("removeBibtexEntryTitle"), JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE); // the user chose to cancel the operation, so return "null" if (JOptionPane.YES_OPTION == option) { // iterate all selected values for (int cnt = 0; cnt < rows.length; cnt++) { // now to the bibey Object bibkey = jTableBibEntries.getValueAt(rows[cnt], 0); // if we have any author, go on... bibtexObj.removeEntry(bibkey.toString()); // check for filtered list if (linkedtablelist != null && linkedtablelist.size() > 0) { // init the object-variable Object[] o = new Object[2]; // fill object with values o[0] = jTableBibEntries.getValueAt(rows[cnt], 0); o[1] = jTableBibEntries.getValueAt(rows[cnt], 1); // add object to linked list linkedtablelist.remove(o); } } // check for filtered list if (linkedtablelist != null && linkedtablelist.size() > 0) { refreshList(); } else { fillBibtexTable(); } } } private void filterList(boolean regEx) { // when we filter the table and want to restore it, we don't need to run the // time-consuming task that creates the author-list and related author-frequencies. // instead, we simply copy the values from the linkedlist to the table-model, which is // much faster. but therefore we have to apply all changes to the filtered-table // (like adding/changing values in a filtered list) to the linked list as well. // get text from the textfield containing the filter string // convert to lowercase, we don't want case-sensitive search String text = jTextFieldFilterTable.getText().toLowerCase(); // when we have no text, do nothing if (text.isEmpty()) { return; } // get table model DefaultTableModel dtm = (DefaultTableModel) jTableBibEntries.getModel(); // if we haven't already stored the current complete table data, do this now if (null == linkedtablelist) { // create new instance of list linkedtablelist = new LinkedList<>(); // go through all table-data for (int cnt = 0; cnt < dtm.getRowCount(); cnt++) { // init the object-variable Object[] o = new Object[2]; // fill object with values o[0] = dtm.getValueAt(jTableBibEntries.convertRowIndexToModel(cnt), 0); o[1] = dtm.getValueAt(jTableBibEntries.convertRowIndexToModel(cnt), 1); // add object to linked list linkedtablelist.add(o); } } de.danielluedecke.zettelkasten.util.TableUtils.filterTable(jTableBibEntries, dtm, text, new int[]{1}, regEx); // reset textfield jTextFieldFilterTable.setText(""); jTextFieldFilterTable.requestFocusInWindow(); // enable textfield only if we have more than 1 element in the jtable jTextFieldFilterTable.setEnabled(jTableBibEntries.getRowCount() > 0); // enable refresh button jButtonRefresh.setEnabled(true); } private void fillBibtexTable() { if (jRadioButtonSourceFile.isSelected()) { // retrieve currently attached file File currentlyattachedfile = bibtexObj.getCurrentlyAttachedFile(); // if we have no currently attached bibtex-file, or the currently attached bibtex-file // differs from the new selected file of the user, open the bibtex-file now if ((null == currentlyattachedfile) || (!currentlyattachedfile.toString().equals(bibtexObj.getFilePath().toString()))) { // open selected file, using the character encoding of the related reference-manager (i.e. // the programme that has exported the bib-tex-file). bibtexObj.openAttachedFile(Constants.BIBTEX_ENCODINGS[jComboBoxEncoding.getSelectedIndex()], false); // retrieve currently attached bibtex-file currentlyattachedfile = bibtexObj.getCurrentlyAttachedFile(); } // set filepath to textfield jTextFieldBibtexFilepath.setText((currentlyattachedfile != null && currentlyattachedfile.exists()) ? currentlyattachedfile.toString() : ""); } // block all components setComponentsBlocked(true); // reset linked list linkedtablelist = null; // start the background task manually Task impBibT = startImport(); // get the application's context... ApplicationContext appC = Application.getInstance().getContext(); // ...to get the TaskMonitor and TaskService TaskMonitor tM = appC.getTaskMonitor(); TaskService tS = appC.getTaskService(); // with these we can execute the task and bring it to the foreground // i.e. making the animated progressbar and busy icon visible tS.execute(impBibT); tM.setForegroundTask(impBibT); } private void setComponentsBlocked(boolean block) { jButtonCancel.setEnabled(!block); jButtonApply.setEnabled(!block); jButtonSelectAll.setEnabled(!block); jButtonBrowseBibtex.setEnabled(!block); jCheckBoxAddAsEntry.setEnabled(!block); jCheckBoxImportKeywords.setEnabled(!block); jComboBoxEncoding.setEnabled(!block); jComboBoxShowBibTex.setEnabled(!block); jComboBoxCiteStyle.setEnabled(!block); jTableBibEntries.setEnabled(!block); jTextFieldFilterTable.setEnabled(!block); jRadioButtonSourceDB.setEnabled(!block); jRadioButtonSourceFile.setEnabled(!block); // refresh button is either blockes (disabled) or enabled whether // we have any content in linkedtablelist. jButtonRefresh.setEnabled((block) ? false : linkedtablelist != null); } @Action public Task addSelectedAuthors() { // check whether user wants to import existing entries as well, i.e. the user // wants to import bibtex-abstracts AND automatically create entries from those // abstracts, where existing entries will be replaced by new bibtex-updates. // in this case, the combo box's selected index must be greater than 0 if (jComboBoxShowBibTex.getSelectedIndex() > 0) { // create a JOptionPane with repalce/new/concat/cancel options updateOption = JOptionPane.showOptionDialog(this, resourceMap.getString("msgConfirmUpdateEntry"), resourceMap.getString("msgConfirmUpdateEntryTitle"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, new Object[]{ resourceMap.getString("optionReplace"), resourceMap.getString("optionNew"), resourceMap.getString("optionConcat"), resourceMap.getString("optionCancel"),}, resourceMap.getString("optioneReplace")); // if user closes or cancels the dialog, return... if (JOptionPane.CLOSED_OPTION == updateOption || updateOption == UPDATE_OPTION_CANCEL) { return null; } } // in this case, only new entries are imported, thus we can ignore the variable updateOption else { updateOption = -1; } // disable components setComponentsBlocked(true); // return task return new addSelectedAuthorsTask(org.jdesktop.application.Application.getInstance(de.danielluedecke.zettelkasten.ZettelkastenApp.class)); } private class addSelectedAuthorsTask extends org.jdesktop.application.Task<Object, Void> { addSelectedAuthorsTask(org.jdesktop.application.Application app) { // Runs on the EDT. Copy GUI state that // doInBackground() depends on from parameters // to createLinksTask fields, here. super(app); } @Override protected Object doInBackground() { // get the selected rows int[] rows = jTableBibEntries.getSelectedRows(); // create new list with possible modified entries. modifiedEntries = new ArrayList<>(); // if we have no selected values, leave method if (rows.length < 1) { return null; } // iterate all selected values for (int cnt = 0; cnt < rows.length; cnt++) { // retrieve author from table-selection Object au = jTableBibEntries.getValueAt(rows[cnt], 1); // now to the bibey Object bibkey = jTableBibEntries.getValueAt(rows[cnt], 0); // if we have any author, go on... if (au != null && !au.toString().isEmpty()) { // init bibkey-pos int bibkeypos = -1; // check if we have any bibkey value and retrieve bibkey-position in author-data // the variable "bibkeypos" stores the index-number of that author value that has // the bibkey "bibkey" associated. if (bibkey != null) { // retrieve bibkey position in author data base bibkeypos = dataObj.getBibkeyPosition(bibkey.toString()); // retrieve bibtex entry from attached file BibtexEntry be = (jRadioButtonSourceDB.isSelected()) ? bibtexObj.getEntry(bibkey.toString()) : bibtexObj.getEntryFromAttachedFile(bibkey.toString()); // add to data base bibtexObj.addEntry(be); } // check whether bibkey already exists... // if we have *not* found any bibkey, or if we have no bibkey (e.g. if bibkey // value was null), we can add the author value if (-1 == bibkeypos) { // ...add author to the data file int pos = dataObj.addAuthor(au.toString(), 0); // if author was successfully added... if (pos != -1) { // check for valid bibkey-value if (bibkey != null) { // and add it to the recently added author-value dataObj.setAuthorBibKey(pos, bibkey.toString()); // if the user also wants to add imported literatur as entries, do // this here. we then have to check whether the imported bibtex-entry // has an abstract or annotation, and if so, we use this as content for // the new entry if (jCheckBoxAddAsEntry.isSelected()) { // init variable String[] keywords = null; // if user also wants keywords, retrieve them now if (jCheckBoxImportKeywords.isSelected()) { keywords = (jRadioButtonSourceDB.isSelected()) ? bibtexObj.getKeywords(bibkey.toString()) : bibtexObj.getKeywordsFromAttachedFile(bibkey.toString()); } // retrieve abstract (i.e. content for entry) String content = (jRadioButtonSourceDB.isSelected()) ? bibtexObj.getAbstract(bibkey.toString()) : bibtexObj.getAbstractFromAttachedFile(bibkey.toString()); // only create content/new entry, if any abstract was found... if (content != null && !content.isEmpty()) { // finally, add entry to dataset dataObj.addEntryFromBibTex("", content, new String[]{au.toString()}, keywords, Tools.getTimeStamp()); // and increase entry counter newEntries++; } // if nothing found, add at least the keywords else if (keywords != null && keywords.length > 0) { // add keywords to database dataObj.addKeywordsToDatabase(keywords); } } else if (jCheckBoxImportKeywords.isSelected()) { String[] keywords = (jRadioButtonSourceDB.isSelected()) ? bibtexObj.getKeywords(bibkey.toString()) : bibtexObj.getKeywordsFromAttachedFile(bibkey.toString()); if (keywords != null && keywords.length > 0) { // add keywords to database dataObj.addKeywordsToDatabase(keywords); } } } } } // here we have an already existing bibkey and update the author-values... // so we have the index-number of that author-value with the bibkey "bibkey" // stored in the value "bibkeypos". else { // set new author value, i.e. overwrite existing author with new value dataObj.setAuthor(bibkeypos, au.toString()); // if the user also wants to *update* imported literatur as entries, we do // this here. we then have to check whether the imported bibtex-entry // has an abstract or annotation, and if so, we use this as content for // the new entry or update an existing entry with this content if (jCheckBoxAddAsEntry.isSelected() && bibkey != null) { // before we check whether // retrieve abstract (i.e. content for entry) String content = (jRadioButtonSourceDB.isSelected()) ? bibtexObj.getAbstract(bibkey.toString()) : bibtexObj.getAbstractFromAttachedFile(bibkey.toString()); // only create content/new entry, if any abstract was found... if (content != null && !content.isEmpty()) { // we need an indicator variable that tells as, whether any entry // was found at all. It can happen, that a user later adds an abstract // and wants to import it now... boolean anyAbstractEntyrFound = false; // we now have to go through all entries and check whether they have an // attribute "fromBibTex" (we do this by calling the method // "CDaten.isContentFromBibTex(int pos)"). If an entry has this // this attribute set to true, we then check whether the entry's // author-value equals the imported author-value (author-index-number // has to equal "bibkeypos"). if both isContentFromBibTex is true and // author-index-number equals bibkeypos, we know that we have to update // the entry's content. We do this according to the user's choice, which // is stored in "updateOption". for (int counter = 1; counter <= dataObj.getCount(Daten.ZKNCOUNT); counter++) { // retrieve entry's bibtex-attribute. here we check, whether // the entry with the index-number "counter" has content from // a bibtex file. only in this case we need to update the entry if (dataObj.isContentFromBibTex(counter)) { // now we have to check, whether any of the entry's author-values // has the same bibkey like the imported bibtex-entry... // only in this case we need to update the content if (dataObj.existsInAuthors(bibkeypos, counter)) { // now we know, that the entry with the index-number "counter" // - was created from a formerly bibtex-import // - has an author with the index-number "bibkeypos" // so it has to be updated or replaced, but only // if the content differs from the previous content // // replace UTF-chars with UBB-tags for creating/changing an entry content = Tools.replaceUnicodeToUbb(content); // now check what the user chose to do. switch (updateOption) { // the user wants to add a new entry from the abstract case UPDATE_OPTION_NEW: // we have to check whether the new imported content *differs* // from the existing zettel-content if (!content.equals(dataObj.getZettelContent(counter))) { // init variable String[] keywords = null; // if user also wants keywords, retrieve them now if (jCheckBoxImportKeywords.isSelected()) { keywords = (jRadioButtonSourceDB.isSelected()) ? bibtexObj.getKeywords(bibkey.toString()) : bibtexObj.getKeywordsFromAttachedFile(bibkey.toString()); } // finally, add entry to dataset dataObj.addEntryFromBibTex("", content, new String[]{au.toString()}, keywords, Tools.getTimeStamp()); // and delete bibtex-attribute from the *old* entry... dataObj.setContentFromBibTexRemark(counter, false); // update found-variable anyAbstractEntyrFound = true; // and increase entry counter newEntries++; } break; // the user wants to add a new entry from the abstract case UPDATE_OPTION_REPLACE: // init variable String[] keywords = null; // if user also wants keywords, retrieve them now if (jCheckBoxImportKeywords.isSelected()) { keywords = (jRadioButtonSourceDB.isSelected()) ? bibtexObj.getKeywords(bibkey.toString()) : bibtexObj.getKeywordsFromAttachedFile(bibkey.toString()); } // change entry's content dataObj.setZettelContent(counter, content, true); // and add new keywords dataObj.addKeywordsToEntry(keywords, counter, 1); // update found-variable anyAbstractEntyrFound = true; // store entry-number of modified entry modifiedEntries.add(counter); break; // the user wants to concatenate a the abstract to an existing entry case UPDATE_OPTION_CONCAT: // init variable keywords = null; // if user also wants keywords, retrieve them now if (jCheckBoxImportKeywords.isSelected()) { keywords = (jRadioButtonSourceDB.isSelected()) ? bibtexObj.getKeywords(bibkey.toString()) : bibtexObj.getKeywordsFromAttachedFile(bibkey.toString()); } // we have to check whether the new imported content *differs* // from the existing zettel-content if (!content.equals(dataObj.getZettelContent(counter))) { // change entry's content dataObj.setZettelContent(counter, dataObj.getZettelContent(counter) + "[br][br]" + content, true); } // and add new keywords dataObj.addKeywordsToEntry(keywords, counter, 1); // update found-variable anyAbstractEntyrFound = true; // store entry-number of modified entry modifiedEntries.add(counter); break; } } } } // check whether we have found any abstract at all... if not, // we create a new entry here if (!anyAbstractEntyrFound) { // init variable String[] keywords = null; // if user also wants keywords, retrieve them now if (jCheckBoxImportKeywords.isSelected()) { keywords = (jRadioButtonSourceDB.isSelected()) ? bibtexObj.getKeywords(bibkey.toString()) : bibtexObj.getKeywordsFromAttachedFile(bibkey.toString()); } // finally, add entry to dataset dataObj.addEntryFromBibTex("", content, new String[]{au.toString()}, keywords, Tools.getTimeStamp()); // and increase entry counter newEntries++; } } } } } // update progress bar setProgress(cnt, 0, rows.length); } return null; } @Override protected void succeeded(Object result) { // Runs on the EDT. Update the GUI based on // the result computed by doInBackground(). } @Override protected void finished() { // enable components setComponentsBlocked(false); // import was not cancelled. // if we have modified entries, add all modified entries to the history, // so the user can go through all modified entries, and auto-select last entry if (getModifiedEntries() != null && getModifiedEntries().size() > 0) { // iterate modified entries for (int cnt = 0; cnt < getModifiedEntries().size(); cnt++) { // add modified entry to history dataObj.addToHistory(getModifiedEntries().get(cnt)); } // set displayed zettel to last modified entry. mainframe.displayedZettel = getModifiedEntries().get(getModifiedEntries().size() - 1); } // update display, since we have new authors and possibly new entries as well mainframe.updateDisplay(); // tell user about success JOptionPane.showMessageDialog(null, resourceMap.getString("authorImportOkMsg", String.valueOf(getNewEntriesCount()), String.valueOf((getModifiedEntries() != null) ? getModifiedEntries().size() : 0)), resourceMap.getString("authorImportOkTitle"), JOptionPane.PLAIN_MESSAGE); // close window setVisible(false); dispose(); // call gc System.gc(); } } @Action public void refreshList() { // first check whether we have any saved values at all if (linkedtablelist != null) { // get table model DefaultTableModel dtm = (DefaultTableModel) jTableBibEntries.getModel(); // delete all data from the author-table dtm.setRowCount(0); // create an iterator for the linked list ListIterator<Object[]> iterator = linkedtablelist.listIterator(); // go through complete linked list and add each element to the table(model) while (iterator.hasNext()) { dtm.addRow(iterator.next()); } // enable filter field jTextFieldFilterTable.setEnabled(true); // disable refresh button jButtonRefresh.setEnabled(false); } linkedtablelist = null; } @Action public void selectAllTableContent() { jTableBibEntries.getSelectionModel().setSelectionInterval(0, jTableBibEntries.getRowCount() - 1); } @Action public Task startImport() { return new startImportTask(org.jdesktop.application.Application.getInstance(de.danielluedecke.zettelkasten.ZettelkastenApp.class)); } private class startImportTask extends org.jdesktop.application.Task<Object, Void> { ArrayList<String[]> rowdata = new ArrayList<>(); startImportTask(org.jdesktop.application.Application app) { // Runs on the EDT. Copy GUI state that // doInBackground() depends on from parameters // to createLinksTask fields, here. super(app); } @Override protected Object doInBackground() { // retrieve count of entries int count = (jRadioButtonSourceFile.isSelected()) ? bibtexObj.getAttachedFileCount() : bibtexObj.getCount(); // iterate all entries of the bibtex file for (int cnt = 0; cnt < count; cnt++) { String bibkey, au; // check which bibtex data source we need if (jRadioButtonSourceFile.isSelected()) { // ...retrieve bibkey bibkey = bibtexObj.getBibkeyFromAttachedFile(cnt); // retrieve each bibtex-author au = bibtexObj.getFormattedEntryFromAttachedFile(cnt); } else { // ...retrieve bibkey bibkey = bibtexObj.getBibkey(cnt); // retrieve each bibtex-author au = bibtexObj.getFormattedEntry(cnt); } // check whether *all* entries should be displayed or not switch (jComboBoxShowBibTex.getSelectedIndex()) { // here we want to display only *new* entries case 0: // if author does not exist AND the bibkey of the imported literature does not already exist... if (au != null && !au.isEmpty() && -1 == dataObj.getAuthorPosition(au) && -1 == dataObj.getAuthorBibKeyPosition(bibkey)) { // we have a new entry and add it to the table rowdata.add(new String[]{bibkey, au}); } break; // here we want to display only *existing* entries case 1: // if bibkey already exists... if (au != null && !au.isEmpty() && dataObj.getAuthorBibKeyPosition(bibkey) != -1) { // we have an existing entry and can add it to the table rowdata.add(new String[]{bibkey, au}); } break; // here we want to display only *all* entries case 2: // if author does not exist... if (au != null && !au.isEmpty()) { // we have any valid entry, whether new or existing, and can add it to the table rowdata.add(new String[]{bibkey, au}); } break; } setProgress(cnt, 0, count); } return null; } @Override protected void succeeded(Object result) { // Runs on the EDT. Update the GUI based on // the result computed by doInBackground(). } @Override protected void finished() { // get iterator for all rowdata Iterator<String[]> it = rowdata.iterator(); // create tablemodel for the table data, which is not editable DefaultTableModel tm = (DefaultTableModel) jTableBibEntries.getModel(); tm.setRowCount(0); // and iterate all loaded bibtex-entries while (it.hasNext()) { tm.addRow(it.next()); } setComponentsBlocked(false); // initially, disable apply button jButtonApply.setEnabled(false); // set status text, how many entries are selected. jLabel2.setText(resourceMap.getString("jLabel2num", String.valueOf(jTableBibEntries.getSelectedRowCount()), String.valueOf(jTableBibEntries.getRowCount()))); } } @Action public void browseFile() { // retrieve attached bibtex-file File selectedfile = bibtexObj.getCurrentlyAttachedFile(); // if we have no attached file, set last used file as filepath if (null == selectedfile || !selectedfile.exists()) { selectedfile = bibtexObj.getFilePath(); } selectedfile = FileOperationsUtil.chooseFile(this, (settingsObj.isMacAqua()) ? FileDialog.LOAD : JFileChooser.OPEN_DIALOG, JFileChooser.FILES_ONLY, (null == selectedfile) ? null : selectedfile.toString(), (null == selectedfile) ? null : selectedfile.getName(), resourceMap.getString("fileChooserTitle"), new String[]{".bib", ".txt"}, resourceMap.getString("bibTexDesc"), settingsObj); if (selectedfile != null) { // set new bibtex-filepath bibtexObj.setFilePath(selectedfile); bibtexObj.detachCurrentlyAttachedFile(); fillBibtexTable(); } } /** * Closes the window */ @Action public void cancel() { dispose(); setVisible(false); // call gc System.gc(); } /** * This class sets up a selection listener for the tables. each table which shall react on * selections, e.g. by showing an entry, gets this selectionlistener in the method * {@link #initSelectionListeners() initSelectionListeners()}. */ private class SelectionListener implements ListSelectionListener { SelectionListener() { } @Override public void valueChanged(ListSelectionEvent e) { // en- or disable apply button jButtonApply.setEnabled(jTableBibEntries.getSelectedRowCount() > 0); // set status text, how many entries are selected. jLabel2.setText(resourceMap.getString("jLabel2num", String.valueOf(jTableBibEntries.getSelectedRowCount()), String.valueOf(jTableBibEntries.getRowCount()))); } } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { buttonGroup1 = new javax.swing.ButtonGroup(); jComboBoxEncoding = new javax.swing.JComboBox(); jLabelEncoding = new javax.swing.JLabel(); jCheckBoxAddAsEntry = new javax.swing.JCheckBox(); jCheckBoxImportKeywords = new javax.swing.JCheckBox(); jButtonApply = new javax.swing.JButton(); jButtonCancel = new javax.swing.JButton(); jLabel1 = new javax.swing.JLabel(); jComboBoxCiteStyle = new javax.swing.JComboBox(); jScrollPane1 = new javax.swing.JScrollPane(); jTableBibEntries = (settingsObj.isMacStyle()) ? MacWidgetFactory.createITunesTable(null) : new javax.swing.JTable(); jLabel2 = new javax.swing.JLabel(); jButtonSelectAll = new javax.swing.JButton(); jButtonRefresh = new javax.swing.JButton(); jTextFieldFilterTable = new javax.swing.JTextField(); jComboBoxShowBibTex = new javax.swing.JComboBox(); statusLabel = new javax.swing.JLabel(); jPanel1 = new javax.swing.JPanel(); jButtonBrowseBibtex = new javax.swing.JButton(); jTextFieldBibtexFilepath = new javax.swing.JTextField(); jRadioButtonSourceFile = new javax.swing.JRadioButton(); jRadioButtonSourceDB = new javax.swing.JRadioButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(de.danielluedecke.zettelkasten.ZettelkastenApp.class).getContext().getResourceMap(CImportBibTex.class); setTitle(resourceMap.getString("FormCImportBibTex.title")); // NOI18N setMinimumSize(new java.awt.Dimension(100, 100)); setName("FormCImportBibTex"); // NOI18N jComboBoxEncoding.setName("jComboBoxEncoding"); // NOI18N jLabelEncoding.setText(resourceMap.getString("jLabelEncoding.text")); // NOI18N jLabelEncoding.setName("jLabelEncoding"); // NOI18N jCheckBoxAddAsEntry.setText(resourceMap.getString("jCheckBoxAddAsEntry.text")); // NOI18N jCheckBoxAddAsEntry.setToolTipText(resourceMap.getString("jCheckBoxAddAsEntry.toolTipText")); // NOI18N jCheckBoxAddAsEntry.setName("jCheckBoxAddAsEntry"); // NOI18N jCheckBoxImportKeywords.setText(resourceMap.getString("jCheckBoxImportKeywords.text")); // NOI18N jCheckBoxImportKeywords.setToolTipText(resourceMap.getString("jCheckBoxImportKeywords.toolTipText")); // NOI18N jCheckBoxImportKeywords.setName("jCheckBoxImportKeywords"); // NOI18N javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(de.danielluedecke.zettelkasten.ZettelkastenApp.class).getContext().getActionMap(CImportBibTex.class, this); jButtonApply.setAction(actionMap.get("addSelectedAuthors")); // NOI18N jButtonApply.setName("jButtonApply"); // NOI18N jButtonCancel.setAction(actionMap.get("cancel")); // NOI18N jButtonCancel.setName("jButtonCancel"); // NOI18N jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N jLabel1.setName("jLabel1"); // NOI18N jComboBoxCiteStyle.setName("jComboBoxCiteStyle"); // NOI18N jScrollPane1.setBorder(null); jScrollPane1.setMinimumSize(new java.awt.Dimension(25, 25)); jScrollPane1.setName("jScrollPane1"); // NOI18N jTableBibEntries.setModel(new javax.swing.table.DefaultTableModel( new Object [][] { }, new String [] { "BibKey", "Literaturangabe" } ) { Class[] types = new Class [] { java.lang.String.class, java.lang.String.class }; boolean[] canEdit = new boolean [] { false, false }; public Class getColumnClass(int columnIndex) { return types [columnIndex]; } public boolean isCellEditable(int rowIndex, int columnIndex) { return canEdit [columnIndex]; } }); jTableBibEntries.setName("jTableBibEntries"); // NOI18N jTableBibEntries.getTableHeader().setReorderingAllowed(false); jScrollPane1.setViewportView(jTableBibEntries); if (jTableBibEntries.getColumnModel().getColumnCount() > 0) { jTableBibEntries.getColumnModel().getColumn(0).setHeaderValue(resourceMap.getString("jTableBibEntries.columnModel.title0")); // NOI18N jTableBibEntries.getColumnModel().getColumn(1).setHeaderValue(resourceMap.getString("jTableBibEntries.columnModel.title1")); // NOI18N } jLabel2.setText(resourceMap.getString("jLabel2.text")); // NOI18N jLabel2.setName("jLabel2"); // NOI18N jButtonSelectAll.setAction(actionMap.get("selectAllTableContent")); // NOI18N jButtonSelectAll.setName("jButtonSelectAll"); // NOI18N jButtonRefresh.setAction(actionMap.get("refreshList")); // NOI18N jButtonRefresh.setIcon(resourceMap.getIcon("jButtonRefresh.icon")); // NOI18N jButtonRefresh.setBorderPainted(false); jButtonRefresh.setContentAreaFilled(false); jButtonRefresh.setFocusPainted(false); jButtonRefresh.setName("jButtonRefresh"); // NOI18N jButtonRefresh.setPreferredSize(new java.awt.Dimension(22, 22)); jTextFieldFilterTable.setToolTipText(resourceMap.getString("jTextFieldFilterTable.toolTipText")); // NOI18N jTextFieldFilterTable.setName("jTextFieldFilterTable"); // NOI18N jComboBoxShowBibTex.setName("jComboBoxShowBibTex"); // NOI18N statusLabel.setIcon(resourceMap.getIcon("statusLabel.icon")); // NOI18N statusLabel.setText(resourceMap.getString("statusLabel.text")); // NOI18N statusLabel.setName("statusLabel"); // NOI18N jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(resourceMap.getString("jPanel1.border.title"))); // NOI18N jPanel1.setName("jPanel1"); // NOI18N jButtonBrowseBibtex.setAction(actionMap.get("browseFile")); // NOI18N jButtonBrowseBibtex.setName("jButtonBrowseBibtex"); // NOI18N jTextFieldBibtexFilepath.setEditable(false); jTextFieldBibtexFilepath.setName("jTextFieldBibtexFilepath"); // NOI18N buttonGroup1.add(jRadioButtonSourceFile); jRadioButtonSourceFile.setText(resourceMap.getString("jRadioButtonSourceFile.text")); // NOI18N jRadioButtonSourceFile.setName("jRadioButtonSourceFile"); // NOI18N buttonGroup1.add(jRadioButtonSourceDB); jRadioButtonSourceDB.setText(resourceMap.getString("jRadioButtonSourceDB.text")); // NOI18N jRadioButtonSourceDB.setName("jRadioButtonSourceDB"); // NOI18N javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(jRadioButtonSourceFile) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jTextFieldBibtexFilepath) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButtonBrowseBibtex)) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(jRadioButtonSourceDB) .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jTextFieldBibtexFilepath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jButtonBrowseBibtex) .addComponent(jRadioButtonSourceFile)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jRadioButtonSourceDB) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jCheckBoxAddAsEntry, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addComponent(jTextFieldFilterTable) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButtonRefresh, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButtonCancel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButtonApply) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(statusLabel)) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabelEncoding) .addComponent(jLabel1)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jComboBoxCiteStyle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jComboBoxEncoding, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addComponent(jCheckBoxImportKeywords)) .addGap(0, 0, Short.MAX_VALUE)) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addComponent(jComboBoxShowBibTex, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButtonSelectAll))) .addContainerGap()) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabelEncoding) .addComponent(jComboBoxEncoding, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(jComboBoxCiteStyle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jCheckBoxAddAsEntry) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jCheckBoxImportKeywords) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButtonSelectAll) .addComponent(jComboBoxShowBibTex, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel2)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 193, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jButtonRefresh, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jTextFieldFilterTable, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jButtonCancel) .addComponent(jButtonApply)) .addComponent(statusLabel)) .addGap(3, 3, 3)) ); pack(); }// </editor-fold>//GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.ButtonGroup buttonGroup1; private javax.swing.JButton jButtonApply; private javax.swing.JButton jButtonBrowseBibtex; private javax.swing.JButton jButtonCancel; private javax.swing.JButton jButtonRefresh; private javax.swing.JButton jButtonSelectAll; private javax.swing.JCheckBox jCheckBoxAddAsEntry; private javax.swing.JCheckBox jCheckBoxImportKeywords; private javax.swing.JComboBox jComboBoxCiteStyle; private javax.swing.JComboBox jComboBoxEncoding; private javax.swing.JComboBox jComboBoxShowBibTex; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabelEncoding; private javax.swing.JPanel jPanel1; private javax.swing.JRadioButton jRadioButtonSourceDB; private javax.swing.JRadioButton jRadioButtonSourceFile; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTable jTableBibEntries; private javax.swing.JTextField jTextFieldBibtexFilepath; private javax.swing.JTextField jTextFieldFilterTable; private javax.swing.JLabel statusLabel; // End of variables declaration//GEN-END:variables }