I wrote a little project analyser, some time ago. It's not really an answer, but I wanted to share my solution. There is no main()
method yet. Just create one like this:
MainFrame mf = new MainFrame();
mf.setVisible(true);
It supports for filtering files on file extensions. So you can specify for example C++. This will accept all .h
and .cpp
files.
You have to specify a folder and it will recursively count files, lines and bytes.
import java.awt.event.ItemEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
/**
*
* @author martijncourteaux
*/
public class MainFrame extends javax.swing.JFrame
{
private File root;
private volatile int _files;
private volatile int _lines;
private volatile long _bytes;
/** Creates new form MainFrame */
public MainFrame()
{
initComponents();
}
/** 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() {
jLabel1 = new javax.swing.JLabel();
btnSelectRoot = new javax.swing.JButton();
lblRoot = new javax.swing.JLabel();
cmbExtensions = new javax.swing.JComboBox();
jLabel2 = new javax.swing.JLabel();
btnAnalyse = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Project Analyser");
setLocation(new java.awt.Point(40, 62));
jLabel1.setText("Project Root:");
btnSelectRoot.setText("Select");
btnSelectRoot.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnSelectRootActionPerformed(evt);
}
});
lblRoot.setText(" ");
cmbExtensions.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "[Any]", "h;cpp", "java", "xml", "Customize..." }));
cmbExtensions.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
cmbExtensionsItemStateChanged(evt);
}
});
jLabel2.setText("Extensions:");
btnAnalyse.setText("Analyse");
btnAnalyse.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnAnalyseActionPerformed(evt);
}
});
org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(cmbExtensions, 0, 352, Short.MAX_VALUE)
.add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
.add(jLabel1)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(lblRoot, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 174, Short.MAX_VALUE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(btnSelectRoot))
.add(jLabel2)
.add(btnAnalyse, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 352, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jLabel1)
.add(btnSelectRoot)
.add(lblRoot))
.add(18, 18, 18)
.add(jLabel2)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(cmbExtensions, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(btnAnalyse, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 90, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void btnSelectRootActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnSelectRootActionPerformed
{//GEN-HEADEREND:event_btnSelectRootActionPerformed
JFileChooser fc = new JFileChooser(root.getParentFile());
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int option = fc.showDialog(this, "Select");
if (option == JFileChooser.APPROVE_OPTION)
{
this.root = fc.getSelectedFile();
this.lblRoot.setText(root.getParentFile().getName() + "/" + root.getName());
}
}//GEN-LAST:event_btnSelectRootActionPerformed
private void cmbExtensionsItemStateChanged(java.awt.event.ItemEvent evt)//GEN-FIRST:event_cmbExtensionsItemStateChanged
{//GEN-HEADEREND:event_cmbExtensionsItemStateChanged
if (cmbExtensions.getSelectedIndex() == cmbExtensions.getItemCount() - 1 && evt.getStateChange() == ItemEvent.SELECTED)
{
evt.getStateChange();
String extensions = JOptionPane.showInputDialog(this, "Specify the extensions, seperated by semi-colon (;) and without dot.");
if (extensions == null)
{
cmbExtensions.setSelectedIndex(0);
return;
}
DefaultComboBoxModel model = (DefaultComboBoxModel) cmbExtensions.getModel();
model.insertElementAt(extensions, cmbExtensions.getSelectedIndex());
cmbExtensions.validate();
cmbExtensions.setSelectedIndex(cmbExtensions.getItemCount() - 2);
}
}//GEN-LAST:event_cmbExtensionsItemStateChanged
private void btnAnalyseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnAnalyseActionPerformed
{//GEN-HEADEREND:event_btnAnalyseActionPerformed
if (root == null)
{
JOptionPane.showMessageDialog(this, "Please select a root.");
return;
}
_files = 0;
_lines = 0;
_bytes = 0L;
btnAnalyse.setHorizontalAlignment(JButton.LEFT);
updateButtonText();
final int i = cmbExtensions.getSelectedIndex();
final String[] extensions = cmbExtensions.getSelectedItem().toString().toLowerCase().split(";");
final FileFilter ff = new FileFilter()
{
@Override
public boolean accept(File file)
{
if (i == 0) return true;
if (file.isDirectory())
{
return true;
}
String name = file.getName().toLowerCase();
for (String ext : extensions)
{
if (name.endsWith(ext))
{
return true;
}
}
return false;
}
};
final SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>()
{
@Override
protected Void doInBackground() throws Exception
{
scan(root, ff);
updateButtonText();
return null;
}
};
sw.execute();
final SwingWorker<Void, Void> sw2 = new SwingWorker<Void, Void>()
{
@Override
protected Void doInBackground() throws Exception
{
while (!sw.isDone())
{
updateButtonText();
}
return null;
}
};
sw2.execute();
}//GEN-LAST:event_btnAnalyseActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnAnalyse;
private javax.swing.JButton btnSelectRoot;
private javax.swing.JComboBox cmbExtensions;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel lblRoot;
// End of variables declaration//GEN-END:variables
private void updateButtonText()
{
String txt = "<html>";
txt += "Files: " + _files + "<br>\n";
txt += "Lines: " + _lines + "<br>\n";
txt += "Bytes: " + _bytes + "\n";
btnAnalyse.setText(txt);
}
private void scan(File folder, FileFilter ff)
{
File[] files = folder.listFiles(ff);
try
{
for (File f : files)
{
if (f == null)
{
continue;
}
if (f.isDirectory())
{
scan(f, ff);
} else
{
analyse(f);
}
}
} catch (Exception e)
{
}
}
private void analyse(File f)
{
if (f.exists())
{
_files++;
_bytes += f.length();
try
{
BufferedReader r = new BufferedReader(new FileReader(f));
while (r.readLine() != null)
{
_lines++;
}
r.close();
} catch (Exception e)
{
}
}
}
}