/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.modules.filetypeid;
import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
import org.sleuthkit.autopsy.modules.filetypeid.CustomFileTypesManager.CustomFileTypesException;
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
/**
* A panel to allow a user to make custom file type definitions. In addition to
* being an ingest module global settings panel, an instance of this class also
* appears in the NetBeans options dialog as an options panel.
*/
final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPanel implements OptionsPanel {
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(FileTypeIdGlobalSettingsPanel.class.getName());
private static final String RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem");
private static final String ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem");
private static final String START_OFFSET_RELATIVE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetComboBox.startItem");
private static final String END_OFFSET_RELATIVE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetComboBox.endItem");
/**
* The list model for the file types list component of this panel is the set
* of MIME types associated with the user-defined file types. A mapping of
* the MIME types to file type objects lies behind the list model. This map
* is obtained from the user-defined types manager.
*/
private DefaultListModel<FileType> typesListModel;
private java.util.List<FileType> fileTypes;
private DefaultListModel<Signature> signaturesListModel;
/**
* This panel implements a property change listener that listens to ingest
* job events so it can disable the buttons on the panel if ingest is
* running. This is done to prevent changes to user-defined types while the
* type definitions are in use.
*/
// TODO: Disabling during ingest would not be necessary if the file ingest
// modules obtained and shared a per data source ingest job snapshot of the
// file type definitions.
IngestJobEventPropertyChangeListener ingestJobEventsListener;
/**
* Creates a panel to allow a user to make custom file type definitions.
*/
FileTypeIdGlobalSettingsPanel() {
initComponents();
customizeComponents();
addIngestJobEventsListener();
}
/**
* Does child component initialization in addition to that done by the
* Matisse generated code.
*/
@NbBundle.Messages({"FileTypeIdGlobalSettingsPanel.Title=Global File Type Identification Settings"})
private void customizeComponents() {
setName(Bundle.FileTypeIdGlobalSettingsPanel_Title());
setFileTypesListModel();
setSignaturesListModel();
setSignatureTypeComboBoxModel();
setOffsetRealtiveToComboBoxModel();
addTypeListSelectionListener();
populateTypeDetailsComponents();
}
/**
* Sets the list model for the list of file types.
*/
private void setFileTypesListModel() {
typesListModel = new DefaultListModel<>();
typesList.setModel(typesListModel);
}
private void setSignaturesListModel() {
this.signaturesListModel = new DefaultListModel<>();
signatureList.setModel(signaturesListModel);
}
/**
* Sets the model for the signature type combo box.
*/
private void setSignatureTypeComboBoxModel() {
DefaultComboBoxModel<String> sigTypeComboBoxModel = new DefaultComboBoxModel<>();
sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM);
sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM);
}
/**
* Sets the model for the signature type combo box.
*/
private void setOffsetRealtiveToComboBoxModel() {
DefaultComboBoxModel<String> offsetRelComboBoxModel = new DefaultComboBoxModel<>();
offsetRelComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM);
offsetRelComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.END_OFFSET_RELATIVE_COMBO_BOX_ITEM);
}
/**
* Adds a listener to the types list component so that the components in the
* file type details section of the panel can be populated and cleared based
* on the selection in the list.
*/
private void addTypeListSelectionListener() {
typesList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
if (typesList.getSelectedIndex() == -1) {
clearTypeDetailsComponents();
} else {
populateTypeDetailsComponents();
}
}
}
});
}
/**
* Add a property change listener that listens to ingest job events to
* disable the buttons on the panel if ingest is running. This is done to
* prevent changes to user-defined types while the type definitions are in
* use.
*/
// TODO: Disabling during ingest would not be necessary if the file ingest
// modules obtained and shared a per data source ingest job snapshot of the
// file type definitions.
private void addIngestJobEventsListener() {
ingestJobEventsListener = new IngestJobEventPropertyChangeListener();
IngestManager.getInstance().addIngestJobEventListener(ingestJobEventsListener);
}
/**
* A property change listener that listens to ingest job events.
*/
private class IngestJobEventPropertyChangeListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
enableButtons();
}
});
}
}
/**
* Enables or disables the panel buttons based on the state of the panel and
* the application.
*/
private void enableButtons() {
boolean ingestIsRunning = IngestManager.getInstance().isIngestRunning();
newTypeButton.setEnabled(!ingestIsRunning);
boolean fileTypeIsSelected = typesList.getSelectedIndex() != -1;
deleteTypeButton.setEnabled(!ingestIsRunning && fileTypeIsSelected);
editTypeButton.setEnabled(!ingestIsRunning && fileTypeIsSelected);
ingestRunningWarningLabel.setVisible(ingestIsRunning);
}
/**
* @inheritDoc
*/
@Override
public void load() {
try {
fileTypes = CustomFileTypesManager.getInstance().getUserDefinedFileTypes();
updateFileTypesListModel();
if (!typesListModel.isEmpty()) {
typesList.setSelectedIndex(0);
}
} catch (CustomFileTypesException ex) {
logger.log(Level.SEVERE, "Failed to get custom file types", ex);
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.loadFileTypes.errorMessage"),
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.loadFailed.title"),
JOptionPane.ERROR_MESSAGE);
fileTypes = Collections.emptyList();
}
enableButtons();
}
/**
* Sets the list model for the file types list component.
*/
private void updateFileTypesListModel() {
typesListModel.clear();
for (FileType fileType : fileTypes) {
typesListModel.addElement(fileType);
}
}
/**
* Populates all of the components in the file type details portion of the
* panel based on the current selection in the file types list.
*/
private void populateTypeDetailsComponents() {
FileType fileType = typesList.getSelectedValue();
this.signatureList.setEnabled(false);
if (null != fileType) {
List<Signature> signatures = fileType.getSignatures();
this.signaturesListModel.clear();
for (Signature sig : signatures) {
signaturesListModel.addElement(sig);
}
}
enableButtons();
}
/**
* Clears all of the components in the individual type details portion of
* the panel.
*/
private void clearTypeDetailsComponents() {
typesList.clearSelection();
this.signaturesListModel.clear();
enableButtons();
}
/**
* @inheritDoc
*/
@Override
public void store() {
try {
CustomFileTypesManager.getInstance().setUserDefinedFileTypes(fileTypes);
} catch (CustomFileTypesManager.CustomFileTypesException ex) {
logger.log(Level.SEVERE, "Failed to set custom file types", ex);
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.saveFileTypes.errorMessage"),
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.storeFailed.title"),
JOptionPane.ERROR_MESSAGE);
}
}
/**
* @inheritDoc
*/
@Override
public void saveSettings() {
store();
}
/**
* @inheritDoc
*/
@Override
@SuppressWarnings("FinalizeDeclaration")
protected void finalize() throws Throwable {
IngestManager.getInstance().removeIngestJobEventListener(ingestJobEventsListener);
super.finalize();
}
/**
* 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() {
jPanel3 = new javax.swing.JPanel();
ingestRunningWarningLabel = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jScrollPane2 = new javax.swing.JScrollPane();
jSplitPane1 = new javax.swing.JSplitPane();
jPanel1 = new javax.swing.JPanel();
jLabel2 = new javax.swing.JLabel();
typesScrollPane = new javax.swing.JScrollPane();
typesList = new javax.swing.JList<>();
deleteTypeButton = new javax.swing.JButton();
newTypeButton = new javax.swing.JButton();
editTypeButton = new javax.swing.JButton();
jPanel2 = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
jScrollPane1 = new javax.swing.JScrollPane();
signatureList = new javax.swing.JList<>();
setMaximumSize(null);
setPreferredSize(new java.awt.Dimension(752, 507));
jPanel3.setPreferredSize(new java.awt.Dimension(781, 339));
ingestRunningWarningLabel.setFont(ingestRunningWarningLabel.getFont().deriveFont(ingestRunningWarningLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
ingestRunningWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/modules/filetypeid/warning16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(ingestRunningWarningLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.ingestRunningWarningLabel.text")); // NOI18N
jLabel3.setFont(jLabel3.getFont().deriveFont(jLabel3.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel3.text")); // NOI18N
jScrollPane2.setMinimumSize(new java.awt.Dimension(300, 0));
jScrollPane2.setPreferredSize(new java.awt.Dimension(550, 275));
jSplitPane1.setDividerSize(1);
jSplitPane1.setMinimumSize(new java.awt.Dimension(0, 0));
jPanel1.setMinimumSize(new java.awt.Dimension(362, 0));
jPanel1.setPreferredSize(new java.awt.Dimension(362, 0));
jLabel2.setFont(jLabel2.getFont().deriveFont(jLabel2.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel2.text")); // NOI18N
typesList.setFont(typesList.getFont().deriveFont(typesList.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
typesList.setMaximumSize(new java.awt.Dimension(150, 0));
typesList.setMinimumSize(new java.awt.Dimension(150, 0));
typesScrollPane.setViewportView(typesList);
deleteTypeButton.setFont(deleteTypeButton.getFont().deriveFont(deleteTypeButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
deleteTypeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(deleteTypeButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.deleteTypeButton.text")); // NOI18N
deleteTypeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
deleteTypeButtonActionPerformed(evt);
}
});
newTypeButton.setFont(newTypeButton.getFont().deriveFont(newTypeButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
newTypeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(newTypeButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.newTypeButton.text")); // NOI18N
newTypeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
newTypeButtonActionPerformed(evt);
}
});
editTypeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/edit16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(editTypeButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.editTypeButton.text")); // NOI18N
editTypeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
editTypeButtonActionPerformed(evt);
}
});
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(newTypeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(editTypeButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(deleteTypeButton))
.addComponent(jLabel2)
.addComponent(typesScrollPane))
.addGap(31, 31, 31))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(12, 12, 12)
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(typesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 203, Short.MAX_VALUE)
.addGap(10, 10, 10)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(newTypeButton)
.addComponent(editTypeButton)
.addComponent(deleteTypeButton))
.addGap(7, 7, 7))
);
jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {deleteTypeButton, newTypeButton});
jSplitPane1.setLeftComponent(jPanel1);
jPanel2.setMinimumSize(new java.awt.Dimension(79, 0));
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel1.text")); // NOI18N
signatureList.setModel(new javax.swing.AbstractListModel<Signature>() {
Signature[] signatures = {};
public int getSize() { return signatures.length; }
public Signature getElementAt(int i) { return signatures[i]; }
});
signatureList.setEnabled(false);
signatureList.setMaximumSize(new java.awt.Dimension(32767, 32767));
signatureList.setPreferredSize(null);
jScrollPane1.setViewportView(signatureList);
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
.addGap(18, 18, 18)
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addComponent(jLabel1)
.addGap(100, 100, 100))
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
.addContainerGap())
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)
.addContainerGap())
);
jSplitPane1.setRightComponent(jPanel2);
jScrollPane2.setViewportView(jSplitPane1);
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(ingestRunningWarningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 761, Short.MAX_VALUE))
.addContainerGap())
);
jPanel3Layout.setVerticalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel3)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 281, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(ingestRunningWarningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 752, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 507, Short.MAX_VALUE)
);
}// </editor-fold>//GEN-END:initComponents
private void newTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newTypeButtonActionPerformed
AddFileTypeDialog dialog = new AddFileTypeDialog();
AddFileTypeDialog.BUTTON_PRESSED result = dialog.getResult();
if (result == AddFileTypeDialog.BUTTON_PRESSED.OK) {
fileTypes.add(dialog.getFileType());
updateFileTypesListModel();
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}
}//GEN-LAST:event_newTypeButtonActionPerformed
private void deleteTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTypeButtonActionPerformed
FileType fileType = typesList.getSelectedValue();
fileTypes.remove(fileType);
updateFileTypesListModel();
if (!typesListModel.isEmpty()) {
typesList.setSelectedIndex(0);
}
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_deleteTypeButtonActionPerformed
private void editTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editTypeButtonActionPerformed
int selected = this.typesList.getSelectedIndex();
AddFileTypeDialog dialog = new AddFileTypeDialog(this.typesListModel.get(this.typesList.getSelectedIndex()));
AddFileTypeDialog.BUTTON_PRESSED result = dialog.getResult();
if (result == AddFileTypeDialog.BUTTON_PRESSED.OK) {
this.fileTypes.remove(selected);
this.fileTypes.add(selected, dialog.getFileType());
updateFileTypesListModel();
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}
}//GEN-LAST:event_editTypeButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton deleteTypeButton;
private javax.swing.JButton editTypeButton;
private javax.swing.JLabel ingestRunningWarningLabel;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JSplitPane jSplitPane1;
private javax.swing.JButton newTypeButton;
private javax.swing.JList<Signature> signatureList;
private javax.swing.JList<FileType> typesList;
private javax.swing.JScrollPane typesScrollPane;
// End of variables declaration//GEN-END:variables
}