/*
* FindBugs - Find bugs in Java programs
* Copyright (C) 2003,2004 University of Maryland
* Copyright (C) 2004 Dave Brosius <dbrosius@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* ConfigureDetectorsDialog.java
*
* Created on June 3, 2003, 3:52 PM
*/
package edu.umd.cs.findbugs.gui;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import edu.umd.cs.findbugs.BugPattern;
import edu.umd.cs.findbugs.DetectorFactory;
import edu.umd.cs.findbugs.DetectorFactoryCollection;
import edu.umd.cs.findbugs.L10N;
import edu.umd.cs.findbugs.config.UserPreferences;
/**
* Configure Detectors by enabling/disabling them.
*
* @author David Hovemeyer
*/
public class ConfigureDetectorsDialog extends javax.swing.JDialog {
private static final long serialVersionUID = 1L;
private static final int SPEED_COLUMN = 1;
private static final int ENABLED_COLUMN = 2;
/**
* Creates new form ConfigureDetectorsDialog
*/
public ConfigureDetectorsDialog(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();
postInitComponents();
}
/**
* 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.
*/
private void initComponents() {//GEN-BEGIN:initComponents
java.awt.GridBagConstraints gridBagConstraints;
detectorTableScrollPane = new javax.swing.JScrollPane();
detectorTable = new javax.swing.JTable();
detectorDescriptionScrollPane = new javax.swing.JScrollPane();
detectorDescription = new javax.swing.JEditorPane();
jSeparator1 = new javax.swing.JSeparator();
okButton = new javax.swing.JButton();
cancelButton = new javax.swing.JButton();
spacer = new javax.swing.JLabel();
restoreDefaultsButton = new javax.swing.JButton();
getContentPane().setLayout(new java.awt.GridBagLayout());
setTitle("Configure Detectors");
addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(java.awt.event.WindowEvent evt) {
closeDialog(evt);
}
@Override
public void windowOpened(java.awt.event.WindowEvent evt) {
formWindowOpened(evt);
}
});
detectorTableScrollPane.setBorder(new javax.swing.border.BevelBorder(javax.swing.border.BevelBorder.LOWERED));
detectorTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Bug Detector", "Speed", "Enabled"
}
) {
private static final long serialVersionUID = 1L;
Class[] types = new Class [] {
java.lang.String.class, java.lang.String.class, java.lang.Boolean.class
};
boolean[] canEdit = new boolean [] {
false, false, true
};
@Override
public Class<?> getColumnClass(int columnIndex) {
return types [columnIndex];
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
populateTable();
detectorTable.getColumnModel().getColumn(ENABLED_COLUMN).setMaxWidth(60);
detectorTable.getColumnModel().getColumn(SPEED_COLUMN).setMaxWidth(60);
detectorTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
{
DefaultTableModel m = (DefaultTableModel)detectorTable.getModel();
m.setColumnIdentifiers( new String[]
{
L10N.getLocalString("dlg.bugdetector_lbl", "Bug Detector"),
L10N.getLocalString("dlg.speed_lbl", "Speed"),
L10N.getLocalString("dlg.enabled_lbl", "Enabled"),
});
DefaultSortedTableModel sortedModel = new DefaultSortedTableModel(m, detectorTable.getTableHeader());
detectorTable.setModel(sortedModel);
}
detectorTableScrollPane.setViewportView(detectorTable);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridwidth = 4;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 0.8;
gridBagConstraints.insets = new java.awt.Insets(6, 6, 2, 6);
getContentPane().add(detectorTableScrollPane, gridBagConstraints);
detectorDescriptionScrollPane.setBorder(new javax.swing.border.BevelBorder(javax.swing.border.BevelBorder.LOWERED));
detectorDescriptionScrollPane.setPreferredSize(new java.awt.Dimension(110, 120));
detectorDescriptionScrollPane.setViewportView(detectorDescription);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridwidth = 4;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weighty = 0.3;
gridBagConstraints.insets = new java.awt.Insets(2, 6, 2, 6);
getContentPane().add(detectorDescriptionScrollPane, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 2;
gridBagConstraints.gridwidth = 4;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.insets = new java.awt.Insets(3, 0, 3, 0);
getContentPane().add(jSeparator1, gridBagConstraints);
okButton.setMnemonic('O');
okButton.setText("OK");
okButton.setText(L10N.getLocalString("dlg.ok_btn","OK"));
okButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
okButtonActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 2;
gridBagConstraints.gridy = 3;
gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 2);
getContentPane().add(okButton, gridBagConstraints);
cancelButton.setMnemonic('C');
cancelButton.setText("Cancel");
cancelButton.setText(L10N.getLocalString("dlg.cancel_btn", "Cancel"));
cancelButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelButtonActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 3;
gridBagConstraints.gridy = 3;
gridBagConstraints.insets = new java.awt.Insets(0, 2, 4, 6);
getContentPane().add(cancelButton, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 3;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.weightx = 1.0;
getContentPane().add(spacer, gridBagConstraints);
restoreDefaultsButton.setText("Restore Defaults");
restoreDefaultsButton.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
restoreDefaultsButton.setText(L10N.getLocalString("dlg.restoredefaults_btn", "Restore Defaults"));
restoreDefaultsButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
restoreDefaultsButtonActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 3;
gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 0);
getContentPane().add(restoreDefaultsButton, gridBagConstraints);
pack();
}//GEN-END:initComponents
private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened
setTitle(L10N.getLocalString("dlg.configuredetectors_ttl", "Configure Detectors"));
}//GEN-LAST:event_formWindowOpened
/**
* reverts the selected state of all the detectors to their defaults as specified in the findbugs.xml file
*
* @param evt the swing event corresponding to the mouse click of the Restore Defaults button
*/
private void restoreDefaultsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_restoreDefaultsButtonActionPerformed
Iterator<DetectorFactory> i = DetectorFactoryCollection.instance().factoryIterator();
DefaultSortedTableModel sorter = (DefaultSortedTableModel) detectorTable.getModel();
TableModel model = sorter.getBaseTableModel();
int row = 0;
while (i.hasNext()) {
DetectorFactory factory = i.next();
if (factory.isHidden())
continue;
model.setValueAt(factory.isDefaultEnabled() ? Boolean.TRUE : Boolean.FALSE, row++, ENABLED_COLUMN);
}
}//GEN-LAST:event_restoreDefaultsButtonActionPerformed
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
closeDialog();
}//GEN-LAST:event_cancelButtonActionPerformed
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
// Update new enabled/disabled status for the Detectors
int num = factoryList.size();
DefaultSortedTableModel sorter = (DefaultSortedTableModel) detectorTable.getModel();
TableModel model = sorter.getBaseTableModel();
for (int i = 0; i < num; ++i) {
DetectorFactory factory = factoryList.get(i);
Boolean enabled = (Boolean) model.getValueAt(i, ENABLED_COLUMN);
UserPreferences.getUserPreferences().enableDetector(
factory, enabled.booleanValue());
}
closeDialog();
}//GEN-LAST:event_okButtonActionPerformed
/**
* Closes the dialog
*/
private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
setVisible(false);
dispose();
}//GEN-LAST:event_closeDialog
/**
* installs a list selection listener to populate the bottom details page based on selection changes in top grid.
* A conversion from the table sorter index to the base model index is done to get the correct details
*/
private void postInitComponents() {
// Listen to detector table selections so we can (hopefully)
// display the description of the detector
ListSelectionModel rowSM = detectorTable.getSelectionModel();
rowSM.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) return;
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
if (!lsm.isSelectionEmpty()) {
int selectedRow = lsm.getMinSelectionIndex();
DefaultSortedTableModel sorter = (DefaultSortedTableModel) detectorTable.getModel();
viewDetectorDetails(factoryList.get(sorter.getBaseModelIndex(selectedRow)));
}
}
});
}
/**
* populates the bottom detector details pane based on the detector selected
*
* @param factory the detector that is currently selected
*/
private void viewDetectorDetails(DetectorFactory factory) {
String detailHTML = factory.getDetailHTML();
if (detailHTML == null) {
detectorDescription.setText("");
} else {
detectorDescription.setContentType("text/html");
detectorDescription.setText(detailHTML);
StringBuilder toolTip = new StringBuilder(100);
toolTip.append("<html><body><b>");
toolTip.append(factory.getFullName());
toolTip.append("</b><br><br><table border='1' width='100%'><tr><th>");
toolTip.append(L10N.getLocalString("msg.bugpatternsreported_txt", "Bug Patterns Reported"));
toolTip.append("</th></tr>");
Collection<BugPattern> patterns = factory.getReportedBugPatterns();
for (BugPattern pattern : patterns) {
toolTip.append("<tr><td align='center'>");
toolTip.append("[");
toolTip.append(pattern.getAbbrev());
toolTip.append("] ");
toolTip.append(pattern.getType());
toolTip.append("</td></tr>");
}
toolTip.append("</body></html>");
detectorDescription.setToolTipText(toolTip.toString());
}
}
/**
* populates the Detector JTable model with all available detectors
* Due to Netbeans form builder, populate table gets called before the tablesorter is installed,
* so it is correct for the model retrieved from the table to be assumed to be the base DefaultTableModel.
*/
private void populateTable() {
Iterator<DetectorFactory> i = DetectorFactoryCollection.instance().factoryIterator();
while (i.hasNext()) {
DetectorFactory factory = i.next();
if (factory.isHidden())
continue;
DefaultTableModel model = (DefaultTableModel) detectorTable.getModel();
model.addRow(new Object[]{
factory.getShortName(),
factory.getSpeed(),
UserPreferences.getUserPreferences().isDetectorEnabled(factory)
? Boolean.TRUE : Boolean.FALSE
});
factoryList.add(factory);
}
}
private void closeDialog() {
setVisible(false);
dispose();
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
new ConfigureDetectorsDialog(new javax.swing.JFrame(), true).setVisible(true);
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton cancelButton;
private javax.swing.JEditorPane detectorDescription;
private javax.swing.JScrollPane detectorDescriptionScrollPane;
private javax.swing.JTable detectorTable;
private javax.swing.JScrollPane detectorTableScrollPane;
private javax.swing.JSeparator jSeparator1;
private javax.swing.JButton okButton;
private javax.swing.JButton restoreDefaultsButton;
private javax.swing.JLabel spacer;
// End of variables declaration//GEN-END:variables
// My variables
private ArrayList<DetectorFactory> factoryList = new ArrayList<DetectorFactory>();
}