package gui.dialog; import ctex.Main; import database.Db; import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import container.ContainerType; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Dimension; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.util.Vector; /** * JDialog that makes it possible to change entry types and add new ones. * * @author stefan */ public class CustomizeEntryDialog extends JDialog { boolean debug = false; private static final long serialVersionUID = 1L; // Entry types section private JLabel allTypesLabel = new JLabel(Main.myLang.getString("customizeentrydialog.alltypeslabel")); private JList allTypes = new JList(); private DefaultListModel allTypesModel = new DefaultListModel(); private JScrollPane allTypesScroller = new JScrollPane(allTypes); private JTextField addTypeField = new JTextField(); private JButton addTypeButton = new JButton(Main.myLang.getString("button.add")); private JButton removeTypeButton = new JButton(Main.myLang.getString("button.remove")); private JButton defaultTypeButton = new JButton(Main.myLang.getString("button.default")); // Required fields section private JLabel requiredLabel = new JLabel(Main.myLang.getString("customizeentrydialog.requiredlabel")); private JList requiredList = new JList(); private DefaultListModel requiredModel = new DefaultListModel(); private JScrollPane requiredScroller = new JScrollPane(requiredList); private JButton requiredUpButton = new JButton(new ImageIcon(getClass().getClassLoader().getResource("images/arrow_up.png"))); private JButton requiredDownButton = new JButton(new ImageIcon(getClass().getClassLoader().getResource("images/arrow_down.png"))); private JButton requiredRemoveButton = new JButton(Main.myLang.getString("button.remove")); private JComboBox requiredComboBox = new JComboBox(); private JButton requiredAddButton = new JButton(Main.myLang.getString("button.add")); // Optional fields section private JLabel optionalLabel = new JLabel(Main.myLang.getString("customizeentrydialog.optionallabel")); private JList optionalList = new JList(); private DefaultListModel optionalModel = new DefaultListModel(); private JScrollPane optionalScroller = new JScrollPane(optionalList); private JButton optionalUpButton = new JButton(new ImageIcon(getClass().getClassLoader().getResource("images/arrow_up.png"))); private JButton optionalDownButton = new JButton(new ImageIcon(getClass().getClassLoader().getResource("images/arrow_down.png"))); private JButton optionalRemoveButton = new JButton(Main.myLang.getString("button.remove")); private JComboBox optionalComboBox = new JComboBox(); private JButton optionalAddButton = new JButton(Main.myLang.getString("button.add")); // Bottom buttons private JButton okButton = new JButton(Main.myLang.getString("button.ok")); private JButton applyButton = new JButton(Main.myLang.getString("button.apply")); private JButton cancelButton = new JButton(Main.myLang.getString("button.cancel")); // Overall contentPane, extra contentPane for the buttom buttons and GridBagConstraints private JPanel contentPane = new JPanel(new GridBagLayout()); private JPanel contentPaneBottom = new JPanel(new GridBagLayout()); private GridBagConstraints constraints = new GridBagConstraints(); Insets insets = new Insets(0, 0, 0, 0); /* Values displayed on screen availableTypes is shown in the JLists * fieldTypes is shown in the ComboBoxes twice */ private Vector<ContainerType> availableTypes = new Vector<ContainerType>(); private Vector<ContainerType> entryTypes = new Vector<ContainerType>(); private Vector<String> fieldTypes = new Vector<String>(); private Db theDb = null; /** * Constructor for this class. Basically just initializes all the used swing * components, loads the available entry types and sets everything up * * @param theDb */ public CustomizeEntryDialog(final Db theDb){ // Settings of the JDialog this.theDb = theDb; setSize(new Dimension(750, 285)); setPreferredSize(new Dimension(750, 285)); setTitle(Main.myLang.getString("customizeentrydialog.title")); // Close dialog when pressing ESC getRootPane().registerKeyboardAction(new ActionListener() { public void actionPerformed(ActionEvent e) { dispose(); } }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); setContentPane(contentPane); setModal(true); availableTypes = theDb.getAllTypes(); // Loading types from files to display for (int i = 0; i < availableTypes.size(); i++) { if (availableTypes.get(i).isEntryType()) { entryTypes.add(availableTypes.get(i)); } } // Loading all combobox fields loadComboBoxFields(); /* * Entry types section */ allTypes.setModel(allTypesModel); for (int i = 0; i < entryTypes.size(); i++) { allTypesModel.addElement(entryTypes.get(i).getType()); } allTypes.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // Always displaying the needed fields on the two JLists requiredList and optionalList allTypes.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent lse) { requiredModel.clear(); optionalModel.clear(); if (!allTypes.isSelectionEmpty()) { for (int i = 0; i < entryTypes.get(allTypes.getSelectedIndex()).getRequiredFields().size(); i++) { requiredModel.add(i, entryTypes.get(allTypes.getSelectedIndex()) .getRequiredFields().get(i)); } for (int i = 0; i < entryTypes.get(allTypes.getSelectedIndex()) .getOptionalFields().size(); i++) { optionalModel.add(i, entryTypes.get(allTypes.getSelectedIndex()) .getOptionalFields().get(i)); } // Activates/disables the Remove-Button if (entryTypes.get(allTypes.getSelectedIndex()).isDeletable()) { removeTypeButton.setEnabled(true); } else { removeTypeButton.setEnabled(false); } } } }); allTypesScroller.setPreferredSize(new Dimension(220, 150)); constraints.gridx = 0; constraints.gridy = 0; constraints.insets = insets; constraints.gridwidth = 2; constraints.anchor = GridBagConstraints.LINE_START; contentPane.add(allTypesLabel, constraints); constraints.gridy = 1; constraints.fill = GridBagConstraints.BOTH; constraints.weightx = 1.0; constraints.weighty = 1.0; contentPane.add(allTypesScroller, constraints); constraints.fill = GridBagConstraints.NONE; constraints.weightx = 0.0; constraints.weighty = 0.0; // Input fields and buttons of the entry types section addTypeField.setPreferredSize(new Dimension(145, 24)); constraints.gridwidth = 1; constraints.gridy = 2; constraints.weightx = 1.0; constraints.fill = GridBagConstraints.HORIZONTAL; // Fill stays for Add-Button contentPane.add(addTypeField, constraints); constraints.weightx = 0.0; constraints.gridx = 1; constraints.gridy = 2; // Adds an empty type to the availableTypes vector and to the JList model addTypeButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if ((addTypeField.getText().compareTo("") != 0) && (!allTypesModel.contains(addTypeField.getText()))) { entryTypes.add(new ContainerType(addTypeField.getText(), true, true)); allTypesModel.addElement(addTypeField.getText()); allTypes.setSelectedValue(addTypeField.getText(), true); } } }); contentPane.add(addTypeButton, constraints); constraints.weightx = 0.0; constraints.fill = GridBagConstraints.NONE; // Fill ends here constraints.gridx = 0; constraints.gridy = 3; // Removes a type from the availableTypes vector and the JList model removeTypeButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (!allTypes.isSelectionEmpty()) { if (entryTypes.get(allTypes.getSelectedIndex()).isDeletable()) { entryTypes.removeElementAt(allTypes.getSelectedIndex()); allTypesModel.removeElementAt(allTypes.getSelectedIndex()); requiredModel.clear(); optionalModel.clear(); } } } }); contentPane.add(removeTypeButton, constraints); constraints.gridx = 1; // Messagebox to be sure the user wants to restore defaults defaultTypeButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { int returnValue = JOptionPane.showConfirmDialog(null, "Do you really want to restore the default values? This can not be undone.", "Restore default values?", JOptionPane.YES_NO_OPTION); /* The user pressed ok, so the default values get loaded after the * old values got cleared. */ if (returnValue == 0) { allTypesModel.clear(); requiredModel.clear(); optionalModel.clear(); entryTypes.clear(); // Reloading default types into database theDb.reloadDefaultTypes(); // Getting the default types from database availableTypes = theDb.getAllTypes(); // Loading types from files to display for (int i = 0; i < availableTypes.size(); i++) { if (availableTypes.get(i).isEntryType()) { entryTypes.add(availableTypes.get(i)); } } for (int i = 0; i < entryTypes.size(); i++) { allTypesModel.addElement(entryTypes.get(i).getType()); } } } }); contentPane.add(defaultTypeButton, constraints); /* * Required fields section */ requiredList.setModel(requiredModel); requiredList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); requiredScroller.setPreferredSize(new Dimension(220, 150)); constraints.gridwidth = 3; constraints.gridx = 2; constraints.gridy = 0; contentPane.add(requiredLabel, constraints); constraints.gridy = 1; constraints.fill = GridBagConstraints.BOTH; constraints.weightx = 1.0; constraints.weighty = 1.0; contentPane.add(requiredScroller, constraints); constraints.fill = GridBagConstraints.NONE; constraints.weightx = 0.0; constraints.weighty = 0.0; constraints.gridwidth = 1; // Input fields and buttons of the required fields section constraints.gridy = 2; // Moves a list item upward requiredUpButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { if (!requiredList.isSelectionEmpty()) { int position = requiredList.getSelectedIndex(); if (position != 0) { swapRequiredItems(position, position - 1); requiredList.setSelectedIndex(position - 1); requiredList.ensureIndexIsVisible(position - 1); } } } }); contentPane.add(requiredUpButton, constraints); constraints.gridx = 3; // Moves a list item downward requiredDownButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (!requiredList.isSelectionEmpty()) { int position = requiredList.getSelectedIndex(); if (position != (requiredModel.getSize() - 1)) { swapRequiredItems(position, position + 1); requiredList.setSelectedIndex(position + 1); requiredList.ensureIndexIsVisible(position + 1); } } } }); contentPane.add(requiredDownButton, constraints); constraints.gridx = 4; // Removes selected item from requiredModel and requiredList requiredRemoveButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (!requiredList.isSelectionEmpty()) { entryTypes.get(allTypes.getSelectedIndex()) .getRequiredFields().remove(requiredList.getSelectedIndex()); requiredModel.remove(requiredList.getSelectedIndex()); } } }); contentPane.add(requiredRemoveButton, constraints); requiredComboBox.setPreferredSize(new Dimension(145, 24)); constraints.gridwidth = 2; constraints.gridx = 2; constraints.gridy = 3; constraints.weightx = 1.0; constraints.fill = GridBagConstraints.HORIZONTAL; // Fill stays for Add-Button contentPane.add(requiredComboBox, constraints); constraints.weightx = 0.0; constraints.gridwidth = 1; constraints.gridx = 4; /* Adds the selected item from the ComboBox to the requiredList, if * the current type is not a default type */ requiredAddButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (!allTypes.isSelectionEmpty() && fieldNotUsed((String) requiredComboBox.getSelectedItem())) { requiredModel.addElement(requiredComboBox.getSelectedItem()); entryTypes.get(allTypes.getSelectedIndex()).getRequiredFields().add( (String) requiredComboBox.getSelectedItem()); } } }); contentPane.add(requiredAddButton, constraints); constraints.fill = GridBagConstraints.NONE; // Fill ends here /* * Optional fields section */ optionalList.setModel(optionalModel); optionalList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); optionalScroller.setPreferredSize(new Dimension(220, 150)); constraints.gridwidth = 3; constraints.gridx = 5; constraints.gridy = 0; contentPane.add(optionalLabel, constraints); constraints.gridy = 1; constraints.fill = GridBagConstraints.BOTH; constraints.weightx = 1.0; constraints.weighty = 1.0; contentPane.add(optionalScroller, constraints); constraints.fill = GridBagConstraints.NONE; constraints.weightx = 0.0; constraints.weighty = 0.0; constraints.gridwidth = 1; // Input fields and buttons of the optional fields section constraints.gridy = 2; // Moves a list item upward optionalUpButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (!optionalList.isSelectionEmpty()) { int position = optionalList.getSelectedIndex(); if (position != 0) { swapOptionalItems(position, position - 1); optionalList.setSelectedIndex(position - 1); optionalList.ensureIndexIsVisible(position - 1); } } } }); contentPane.add(optionalUpButton, constraints); constraints.gridx = 6; // Moves a list item downward optionalDownButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (!optionalList.isSelectionEmpty()) { int position = optionalList.getSelectedIndex(); if (position != (optionalModel.getSize() - 1)) { swapOptionalItems(position, position + 1); optionalList.setSelectedIndex(position + 1); optionalList.ensureIndexIsVisible(position + 1); } } } }); contentPane.add(optionalDownButton, constraints); constraints.gridx = 7; // Removes selected item from requiredModel and requiredList optionalRemoveButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (!optionalList.isSelectionEmpty()) { entryTypes.get(allTypes.getSelectedIndex()) .getOptionalFields().remove(optionalList.getSelectedIndex()); optionalModel.remove(optionalList.getSelectedIndex()); } } }); contentPane.add(optionalRemoveButton, constraints); optionalComboBox.setPreferredSize(new Dimension(145, 24)); constraints.gridwidth = 2; constraints.gridx = 5; constraints.gridy = 3; constraints.weightx = 1.0; constraints.fill = GridBagConstraints.HORIZONTAL; // Fill stays for Add-Button contentPane.add(optionalComboBox, constraints); constraints.weightx = 0.0; constraints.gridwidth = 1; constraints.gridx = 7; /* Adds the selected item from the ComboBox to the optionalList, if * the current type is not a default type */ optionalAddButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (!allTypes.isSelectionEmpty() && fieldNotUsed((String) optionalComboBox.getSelectedItem())) { optionalModel.addElement(optionalComboBox.getSelectedItem()); entryTypes.get(allTypes.getSelectedIndex()).getOptionalFields().add( (String) optionalComboBox.getSelectedItem()); } } }); contentPane.add(optionalAddButton, constraints); constraints.fill = GridBagConstraints.NONE; // Fill ends here /* * Bottom buttons section (on the extra pane contentPaneBottom) */ insets.set(3, 3, 3, 3); constraints.weightx = 0.0; constraints.gridx = 0; constraints.gridy = 0; // Saves the files and closes the JDialog okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { saveAvailableTypes(); dispose(); } }); contentPaneBottom.add(okButton, constraints); constraints.gridx = 1; // Saves the files applyButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { saveAvailableTypes(); availableTypes = theDb.getAllTypes(); // Loading types from files to display for (int i = 0; i < availableTypes.size(); i++) { if (availableTypes.get(i).isEntryType()) { entryTypes.add(availableTypes.get(i)); } } } }); contentPaneBottom.add(applyButton, constraints); constraints.gridx = 2; // Closes the JDialog cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { dispose(); } }); contentPaneBottom.add(cancelButton, constraints); // Adding contentPaneBottom to the other contentPane constraints.gridx = 0; constraints.gridy = 4; constraints.fill = GridBagConstraints.HORIZONTAL; constraints.gridwidth = GridBagConstraints.REMAINDER; contentPane.add(contentPaneBottom, constraints); // Displaying JContentPane and the JDialog getContentPane().setVisible(true); setVisible(true); } /** * After changes have been done in the "Customize entry type"-Dialog, * the changes are saved to the database. */ public void saveAvailableTypes(){ theDb.setAllTypes(entryTypes); } /** * Loads all possible fields that can be chosen to be * required or optional fields and saves them into the * vector fieldTypes */ public void loadComboBoxFields() { try { FileInputStream fileStream = new FileInputStream("types/fields.dat"); DataInputStream in = new DataInputStream(fileStream); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String field; while ((field = reader.readLine()) != null) { fieldTypes.add(field); requiredComboBox.addItem(field); optionalComboBox.addItem(field); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * Checks if a field can still be used, or if some other * part of the type already used it * * @param field Is the field that should be checked * @return boolean true if it's not used by any part of the type */ public boolean fieldNotUsed(String field) { return (!entryTypes.get(allTypes.getSelectedIndex()) .getRequiredFields().contains(field)) && (!entryTypes.get(allTypes.getSelectedIndex()) .getOptionalFields().contains(field)); } /** * Method that swaps two elements inside requiredList and * the requiredFields vector of the entry type * * @param a Index 1 * @param b Index 2 */ public void swapRequiredItems(int a, int b) { Object aObject = requiredModel.getElementAt(a); Object bObject = requiredModel.getElementAt(b); requiredModel.set(a, bObject); requiredModel.set(b, aObject); entryTypes.get(allTypes.getSelectedIndex()) .getRequiredFields().set(a, (String) bObject); entryTypes.get(allTypes.getSelectedIndex()) .getRequiredFields().set(b, (String) aObject); } /** * Method that swaps two elements inside optionalList and * the optionalFields vector of the entry type * * @param a Index 1 * @param b Index 2 */ public void swapOptionalItems(int a, int b) { Object aObject = optionalModel.getElementAt(a); Object bObject = optionalModel.getElementAt(b); optionalModel.set(a, bObject); optionalModel.set(b, aObject); entryTypes.get(allTypes.getSelectedIndex()) .getOptionalFields().set(a, (String) bObject); entryTypes.get(allTypes.getSelectedIndex()) .getOptionalFields().set(b, (String) aObject); } }