0001: package tide.sources;
0002:
0003: import tide.stats.CodeStats;
0004: import java.awt.Color;
0005: import java.awt.datatransfer.*;
0006: import java.awt.dnd.*;
0007: import java.awt.EventQueue;
0008: import tide.staticanalysis.StaticAnalysis;
0009: import tide.exttools.AStyle.AStyleLauncher;
0010: import tide.exttools.AStyle.AStyleSettingsDialog;
0011: import tide.execute.ExecuteActions;
0012: import java.awt.Component;
0013: import tide.exttools.SVN.SVNOps;
0014: import tide.project.*;
0015: import snow.utils.storage.*;
0016: import tide.editor.*;
0017: import tide.editor.bookmarks.SourceBookmark;
0018: import tide.exttools.findbugs.*;
0019: import tide.exttools.JLint.*;
0020: import tide.exttools.lint4j.*;
0021: import tide.exttools.PMD.*;
0022: import tide.exttools.checkstyle.*;
0023: import tide.syntaxtree.TreeFunctions;
0024: import snow.utils.gui.*;
0025: import snow.utils.SysUtils;
0026: import tide.utils.*;
0027: import javax.swing.*;
0028: import java.awt.BorderLayout;
0029: import java.awt.event.*;
0030: import javax.swing.border.*;
0031: import javax.swing.event.*;
0032: import javax.swing.tree.*;
0033: import java.util.*;
0034: import java.io.*;
0035:
0036: /** Contains mouse user actions controller of the sources tree.
0037: Selection of source nodes sets the actual edited source.
0038: */
0039: public class SourcesTreePanel extends JPanel {
0040: final private JTree tree = new JTree(new SourcesTreeModel());
0041: private SourcesTreeRenderer cellRenderer = new SourcesTreeRenderer();
0042:
0043: public SourcesTreePanel() {
0044: super (new BorderLayout(0, 0));
0045: setBorder(null);
0046:
0047: // useful at startup when the tree is not yet visible
0048:
0049: JScrollPane sp = new JScrollPane(tree);
0050: sp.getViewport().setBackground(
0051: UIManager.getColor("Tree.background"));
0052:
0053: sp.setBorder(null);
0054: sp.getViewport().setBorder(null);
0055: add(sp, BorderLayout.CENTER);
0056: tree.setVisible(false);
0057:
0058: tree.setCellRenderer(cellRenderer);
0059:
0060: // Selection
0061: // TODO: look with click listener because this listener
0062: // does not handle reselection ! this is a small problem
0063: // when the lib tree selected some source,
0064: tree.getSelectionModel().addTreeSelectionListener(
0065: new TreeSelectionListener() {
0066: public void valueChanged(TreeSelectionEvent tse) {
0067: TreePath tp = tse.getNewLeadSelectionPath();
0068: if (tp != null) {
0069: SourceFile src = (SourceFile) tp
0070: .getLastPathComponent();
0071: if (src.javaFile != null) {
0072: MainEditorFrame.instance
0073: .setSourceOrItemToEditOrView(
0074: src, false);
0075: // this should be the only called.
0076: // the other callers must call the tree selection functions, they
0077: // will bring the control here and select the wanted source !
0078: }
0079: }
0080: }
0081: });
0082:
0083: tree.addMouseListener(new MouseAdapter() {
0084: @Override
0085: public void mousePressed(MouseEvent me) {
0086: if (me.isPopupTrigger()) {
0087: showPopup(me);
0088: }
0089: }
0090:
0091: @Override
0092: public void mouseReleased(MouseEvent me) {
0093: if (me.isPopupTrigger()) {
0094: showPopup(me);
0095: }
0096: }
0097: });
0098:
0099: this .registerKeyboardAction(new ActionListener() {
0100: public void actionPerformed(ActionEvent ae) {
0101: java.util.List<SourceFile> files = getTreeModel()
0102: .getAllSourceFiles(false);
0103: new SearchTool(files, true,
0104: "Search in all sources names (" + files.size()
0105: + " sources)");
0106: }
0107: }, "SearchFileNames", Accelerators.search,
0108: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
0109:
0110: allowDropFilesFromOS();
0111:
0112: } // Constructor
0113:
0114: /** Notify the renderer (necessary, because he's not in the UI tree, as shared ref for the tree, just his paint is call )
0115: */
0116: @Override
0117: public void updateUI() {
0118: super .updateUI();
0119: if (cellRenderer != null) {
0120:
0121: cellRenderer = new SourcesTreeRenderer();
0122: //this.cellRenderer.updateUI(); // not working well, special renderer case.
0123: tree.setCellRenderer(this .cellRenderer);
0124: /*if(tree!=null)
0125: {
0126: tree.invalidate();
0127: tree.updateUI();
0128: }*/
0129: }
0130: }
0131:
0132: public void clearSelection() {
0133: tree.getSelectionModel().clearSelection();
0134: }
0135:
0136: /** @return an empty string if none. The java name otherwise
0137: */
0138: public String getActualSelectedClassName() {
0139: TreePath tp = tree.getSelectionPath();
0140: if (tp == null)
0141: return "";
0142: SourceFile src = (SourceFile) tp.getLastPathComponent();
0143: if (!src.isJavaFile())
0144: return "";
0145: return src.getJavaName();
0146: }
0147:
0148: /** @param javaName is a class or package name
0149: * if a source is found, select it in the editor.
0150:
0151: */
0152: public void setSelectedJavaName(String javaName,
0153: boolean enforceReselect) {
0154: //new Throwable().printStackTrace();
0155: SourceFile sf = getTreeModel().getSourceFile(javaName, "");
0156: setSelectedSource(sf, enforceReselect);
0157: }
0158:
0159: /** if not null, makes the path visible and select in the editor.
0160: @param enforceReselect if true, really perform a select, even if the selection is already made.
0161: */
0162: public void setSelectedSource(SourceFile sf, boolean enforceReselect) {
0163: //System.out.println("Set selected source: "+sf.getJavaName());
0164: if (enforceReselect) {
0165: tree.setSelectionPath(null);
0166: }
0167:
0168: if (sf != null) {
0169: TreePath tp = new TreePath(sf.getPath());
0170: tree.setSelectionPath(tp); // cause an editor update if changed! because we have a selection listener, not a mouse listener !
0171: tree.makeVisible(tp);
0172: tree.scrollPathToVisible(tp);
0173: //System.out.println("");
0174: }
0175: }
0176:
0177: /** must be called when loading a new project
0178: */
0179: public void setModel(SourcesTreeModel m) {
0180: tree.setModel(m);
0181: tree.setVisible(true);
0182: }
0183:
0184: public SourcesTreeModel getTreeModel() {
0185: return (SourcesTreeModel) tree.getModel();
0186: }
0187:
0188: /** Compile, execute actions are presented to the user.
0189: */
0190: private final void showPopup(MouseEvent me) {
0191: int selRow = tree.getRowForLocation(me.getX(), me.getY());
0192: if (selRow == -1) {
0193: return;
0194: }
0195:
0196: TreePath selPath = tree
0197: .getPathForLocation(me.getX(), me.getY());
0198: final SourceFile sf = (SourceFile) selPath
0199: .getLastPathComponent();
0200: if (sf == null)
0201: return;
0202:
0203: JPopupMenu popup = new JPopupMenu("Source files context menu");
0204:
0205: // special case ! When Ctrl is pressed, shows only the SVN menu
0206: // MainEditorFrame.enableExperimental
0207: if (me.isControlDown()) // BUGGY, Also jumps if alt+gr is down !! ?? even Java1.6
0208: {
0209: JMenu menuSVN = SVNOps.create_SourcesTreePopupMenu(sf);
0210: Component[] comps = menuSVN.getMenuComponents();
0211: menuSVN.removeAll();
0212: popup.add("Subversion SVN operations:");
0213: for (Component ci : comps) {
0214: popup.add(ci);
0215: }
0216: popup.show(tree, me.getX(), me.getY());
0217:
0218: return;
0219: }
0220:
0221: final List<SourceFile> allSubFiles = new ArrayList<SourceFile>();
0222: getTreeModel().getAllSourceFilesRecurse(sf, allSubFiles, false,
0223: false); // don't include folders nor ignored
0224:
0225: if (sf.isJavaFile()) {
0226: StringBuilder mainName = new StringBuilder(sf.getJavaName());
0227: if (sf.isProjectMainClass)
0228: mainName.append(" (Main project source)");
0229: popup.add(mainName.toString());
0230:
0231: boolean hasStaticMain = ExecuteActions.isExecutable(sf);
0232: if (hasStaticMain) {
0233: JMenuItem execute = new JMenuItem("Execute",
0234: Icons.sharedStart);
0235: execute.setAccelerator(Accelerators.runSelected); // just display, mapping occurs in the MainEditorFrame
0236: popup.addSeparator();
0237: popup.add(execute);
0238: execute.addActionListener(new ActionListener() {
0239: public void actionPerformed(ActionEvent ae) {
0240: MainEditorFrame.instance.execute(sf, false,
0241: null, null);
0242: }
0243: });
0244:
0245: JMenu menuProfile = new JMenu("Profile & Debug");
0246: menuProfile.setIcon(Icons.sharedDebugStart);
0247: popup.add(menuProfile);
0248:
0249: List<JMenuItem> dacts = ExecuteActions
0250: .createDebugRunActions(sf);
0251: for (JMenuItem it : dacts) {
0252: if (it == null) {
0253: menuProfile.addSeparator();
0254: } else {
0255: menuProfile.add(it);
0256: }
0257: }
0258:
0259: if (!sf.isProjectMainClass) {
0260: JMenuItem defMain = new JMenuItem(
0261: "Define as project main class",
0262: new Icons.StartIcon(10, 10, true, false,
0263: Color.blue.brighter()));
0264: popup.add(defMain);
0265: defMain.addActionListener(new ActionListener() {
0266: public void actionPerformed(ActionEvent ae) {
0267: MainEditorFrame.instance.getActualProject()
0268: .setMainSourceFile(sf.javaFile);
0269: getTreeModel().markMainProjectSource();
0270: }
0271: });
0272: }
0273: }
0274: } else if (allSubFiles.size() > 0) {
0275: String name = "";
0276: if (sf.isRoot()) {
0277: name = "Root package";
0278: } else {
0279: name = "Package " + sf.getJavaName();
0280: }
0281: popup.add(name + " (" + allSubFiles.size()
0282: + " java source file"
0283: + (allSubFiles.size() != 1 ? "s" : "") + ") ");
0284: popup.addSeparator();
0285: }
0286:
0287: if (allSubFiles.size() > 0) {
0288: JMenuItem compileBranch = new JMenuItem("Compile"
0289: + (allSubFiles.size() > 1 ? " branch" : ""),
0290: new Icons.LetterIcon("C", true, 17, 17, true));
0291: if (sf.isJavaFile()) {
0292: //not really precise...
0293: compileBranch
0294: .setAccelerator(Accelerators.compileChangedFiles); // just display, mapping occurs in the MainEditorFrame
0295: }
0296: popup.addSeparator();
0297: popup.add(compileBranch);
0298: compileBranch.addActionListener(new ActionListener() {
0299: public void actionPerformed(ActionEvent ae) {
0300: MainEditorFrame.instance.editorPanel
0301: .saveChangedFiles();
0302: MainEditorFrame.instance.compile_queued(
0303: allSubFiles, sf, false); // with dependencies
0304: }
0305: });
0306: }
0307:
0308: // Add file/package
0309: //
0310: if (sf.isDirectory) {
0311: SourcesTreeIcon nfi = new SourcesTreeIcon(false,
0312: SourcesTreeIcon.IconColor.Green, 17);
0313: nfi.doNotDrawCompiledBar = true;
0314: JMenuItem addSrc = new JMenuItem(
0315: "Create a new java source file", nfi);
0316: popup.addSeparator();
0317: popup.add(addSrc);
0318: addSrc.addActionListener(new ActionListener() {
0319: public void actionPerformed(ActionEvent ae) {
0320: addNewSourceDialog(sf.getJavaName(), null);
0321: }
0322: });
0323:
0324: SourcesTreeIcon npi = new SourcesTreeIcon(true,
0325: SourcesTreeIcon.IconColor.Green, 17);
0326: npi.doNotDrawCompiledBar = true;
0327: JMenuItem addPack = new JMenuItem("Create a new package",
0328: npi);
0329: popup.add(addPack);
0330: addPack.addActionListener(new ActionListener() {
0331: public void actionPerformed(ActionEvent ae) {
0332: String cn = JOptionPane
0333: .showInputDialog(
0334: SourcesTreePanel.this ,
0335: "Enter the new package name to create "
0336: + (sf.isRoot() ? "in the root"
0337: : ("in the package\n " + sf
0338: .getJavaName())));
0339: if (cn == null || cn.trim().length() == 0)
0340: return;
0341: String packageName = cn.trim();
0342: try {
0343: if (packageName.indexOf(' ') >= 0)
0344: throw new RuntimeException(
0345: "package names cannot contain spaces !");
0346: //if(packageName.indexOf('.')>=0) throw new RuntimeException("package names cannot contain dots !");
0347:
0348: SourceFile act = sf;
0349: for (String pi : packageName.split("\\.")) {
0350:
0351: act = getTreeModel().createNewJavaPackage(
0352: act, pi.trim());
0353: }
0354:
0355: updateTree();
0356: } catch (Exception e) {
0357: JOptionPane.showMessageDialog(
0358: SourcesTreePanel.this , ""
0359: + e.getMessage(),
0360: "Cannot create package",
0361: JOptionPane.ERROR_MESSAGE);
0362: }
0363: // don't select it, no sense !
0364: //TreePath tp = new TreePath(addedFile.getPath());
0365: //tree.setSelectionPath(tp);
0366:
0367: }
0368: });
0369:
0370: // TODO: allow only deleting empty folders...
0371: JMenuItem delete = new JMenuItem("Delete folder "
0372: + sf.getNodeNameToDisplayInTree(),
0373: Icons.sharedCross);
0374: if (!sf.getPackageName().equals("")) {
0375: popup.addSeparator();
0376: popup.add(delete);
0377:
0378: delete.addActionListener(new ActionListener() {
0379: public void actionPerformed(ActionEvent ae) {
0380: int rep = JOptionPane.showConfirmDialog(
0381: SourcesTreePanel.this ,
0382: "Are you sure you want to delete the folder\n "
0383: + sf.getJavaName() + " ?",
0384: "Deletion Confirmation",
0385: JOptionPane.YES_NO_CANCEL_OPTION);
0386: if (rep != JOptionPane.YES_OPTION)
0387: return;
0388:
0389: try {
0390: getTreeModel().delete(sf);
0391: updateTree();
0392: } catch (Exception e) {
0393: JOptionPane.showMessageDialog(
0394: SourcesTreePanel.this , ""
0395: + e.getMessage(), "Error",
0396: JOptionPane.ERROR_MESSAGE);
0397: }
0398: }
0399: });
0400: }
0401:
0402: } else {
0403: // single file
0404: if (sf.isEditable()) {
0405: JMenuItem ren = new JMenuItem("Rename file "
0406: + sf.getNodeNameToDisplayInTree(),
0407: Icons.sharedWiz);
0408: popup.addSeparator();
0409: popup.add(ren);
0410: ren.addActionListener(new ActionListener() {
0411: public void actionPerformed(ActionEvent ae) {
0412: // important.
0413: MainEditorFrame.instance.editorPanel
0414: .saveChangedFiles();
0415:
0416: final String oldJavaName = sf.getJavaName();
0417:
0418: RenameDialog rd = new RenameDialog(
0419: MainEditorFrame.instance, sf);
0420: if (!rd.wasAccepted())
0421: return;
0422: if (!rd.checkNameValidity()) {
0423: // NO definitively not try !
0424: return;
0425: }
0426:
0427: if (rd.getHasDependenciesErrors()) {
0428: if (JOptionPane
0429: .showConfirmDialog(
0430: MainEditorFrame.instance,
0431: "Are you sure you want to rename this source ?"
0432: + "\nThe renaming operation will not be perfect and your project may by injuried !"
0433: + "\n\ncontinue renaming ?",
0434: "Dangerous Renaming Operation Warning",
0435: JOptionPane.YES_NO_CANCEL_OPTION,
0436: JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION) {
0437: return;
0438: }
0439: }
0440:
0441: String newName = rd.getNewJavaSimpleName();
0442:
0443: System.out.println("renaming "
0444: + sf.getJavaName() + " in " + newName);
0445:
0446: try {
0447: MainEditorFrame.instance.editorPanel
0448: .removeTab(sf);
0449: sf.rename(newName, rd.renameInsourceCB
0450: .isSelected(), rd.renameInProjectCB
0451: .isSelected());
0452: getTreeModel().renameInCache(sf,
0453: oldJavaName);
0454: } catch (Exception e) {
0455: JOptionPane.showMessageDialog(
0456: SourcesTreePanel.this , ""
0457: + e.getMessage(), "Error",
0458: JOptionPane.ERROR_MESSAGE);
0459: e.printStackTrace();
0460: }
0461:
0462: updateTree();
0463: updateUI();
0464: setSelectedSource(sf, true); // re-add the tab
0465: }
0466: });
0467:
0468: JMenuItem delete = new JMenuItem("Delete file "
0469: + sf.getNodeNameToDisplayInTree(),
0470: Icons.sharedCross);
0471: //popup.addSeparator();
0472: popup.add(delete);
0473: delete.addActionListener(new ActionListener() {
0474: public void actionPerformed(ActionEvent ae) {
0475: int rep = JOptionPane.showConfirmDialog(
0476: SourcesTreePanel.this ,
0477: "Are you sure you want to delete the file\n "
0478: + sf.getJavaName() + " ?",
0479: "Deletion Confirmation",
0480: JOptionPane.YES_NO_CANCEL_OPTION);
0481: if (rep != JOptionPane.YES_OPTION)
0482: return;
0483:
0484: MainEditorFrame.instance.editorPanel
0485: .saveChangedFiles();
0486:
0487: try {
0488: MainEditorFrame.instance.editorPanel
0489: .removeTab(sf);
0490: getTreeModel().delete(sf);
0491: sf.deleteAssociatedClassFiles();
0492: updateTree();
0493: } catch (Exception e) {
0494: JOptionPane.showMessageDialog(
0495: SourcesTreePanel.this , ""
0496: + e.getMessage(), "Error",
0497: JOptionPane.ERROR_MESSAGE);
0498: e.printStackTrace();
0499: }
0500: }
0501: });
0502: }
0503: }
0504:
0505: if (allSubFiles.size() > 0) {
0506: JMenuItem ts = new JMenuItem("Analyse with TLint",
0507: new Icons.LetterIcon("T", false, 14, 14, true,
0508: Color.green.darker()));
0509: ts
0510: .setToolTipText("<html><body>Detects some issues that other tools don't, using reflection, ASM and source parsing:"
0511: + "<ul><li> missing @Override are detected (currently not in the anonymous classes, be aware of adapters)."
0512: + "<li> - @OverrideMustInvoke(When.LAST |FIRST|ANYTIME) are considered, ensuring that overriders calls super, and at the right place."
0513: + "<li> - @SubclassMustInvoke() are considered, ensuring that subclasses calls somewhere the marked method."
0514: + "<li> - @Recurse and @NonRecurse annotations are checked, missing @Recurse are detected."
0515: + "<p><br>NOTE: @SubclassMustInvoke() and @Recurse are custom creations, contained in the tIDE sourcecode."
0516: + "<br>To use them in your projects, just copy theese classes or their sources or create empty annotations with the same name."
0517: + "</ul></body></html>");
0518: popup.addSeparator();
0519: popup.add(ts);
0520: ts.addActionListener(new ActionListener() {
0521: public void actionPerformed(ActionEvent ae) {
0522: MainEditorFrame.instance.editorPanel
0523: .saveChangedFiles();
0524: StaticAnalysis.analyse(allSubFiles);
0525: }
0526: });
0527:
0528: JMenu extToolsMenu = new JMenu("Ext tools");
0529: popup.add(extToolsMenu);
0530:
0531: // nice help, telling us how much src files will be analysed (don't apply for tools analysing classes...)
0532: String nSubFilesTxt = "";
0533: if (allSubFiles.size() > 1) {
0534: nSubFilesTxt = allSubFiles.size() + " source"
0535: + (allSubFiles.size() == 1 ? "" : "s");
0536: }
0537:
0538: JMenuItem pmd = new JMenuItem("Analyse " + nSubFilesTxt
0539: + " with PMD");
0540: extToolsMenu.add(pmd);
0541: pmd.addActionListener(new ActionListener() {
0542: public void actionPerformed(ActionEvent ae) {
0543: MainEditorFrame.instance.editorPanel
0544: .saveChangedFiles();
0545: if (!PMDSettingsDialog.isConfigured()) {
0546: PMDSettingsDialog fbst = new PMDSettingsDialog(
0547: MainEditorFrame.instance,
0548: MainEditorFrame.instance
0549: .getActualProject());
0550: if (!fbst.dialogWasAccepted
0551: || !PMDSettingsDialog.isConfigured()) {
0552: return;
0553: }
0554: }
0555:
0556: final ProgressModalDialog progress = new ProgressModalDialog(
0557: MainEditorFrame.instance, "PMD analysis",
0558: false);
0559: Thread t = new Thread(new Runnable() {
0560: public void run() {
0561: try {
0562: PMDLauncher._analyse(false, progress,
0563: sf);
0564: } catch (Exception e) {
0565: JOptionPane.showMessageDialog(
0566: SourcesTreePanel.this , ""
0567: + e.getMessage(),
0568: "Error",
0569: JOptionPane.ERROR_MESSAGE);
0570: e.printStackTrace();
0571: } finally {
0572: progress.closeDialog();
0573: }
0574: }
0575: });
0576: t.setName("PMD analysis");
0577: t.setPriority(Thread.NORM_PRIORITY - 1);
0578: t.start();
0579:
0580: }
0581: });
0582:
0583: JMenuItem fb = new JMenuItem(
0584: "Analyse classes with FindBugs");
0585: extToolsMenu.add(fb);
0586: fb.addActionListener(new ActionListener() {
0587: public void actionPerformed(ActionEvent ae) {
0588: MainEditorFrame.instance.editorPanel
0589: .saveChangedFiles();
0590:
0591: // show settings dialog if not configured
0592: if (!FindBugsSettingsDialog.isConfigured()) {
0593: FindBugsSettingsDialog fbst = new FindBugsSettingsDialog(
0594: MainEditorFrame.instance,
0595: MainEditorFrame.instance
0596: .getActualProject());
0597: if (!fbst.dialogWasAccepted
0598: || !FindBugsSettingsDialog
0599: .isConfigured()) {
0600: return;
0601: }
0602: }
0603:
0604: final EstimatedProgressDialog progressDialog = new EstimatedProgressDialog(
0605: MainEditorFrame.instance,
0606: "FindBugs analysis", false);
0607: Thread t = new Thread() {
0608: public void run() {
0609: progressDialog.start();
0610:
0611: try {
0612: File bf = File.createTempFile(
0613: "findbugs_tmp_", ".xml");
0614: bf.deleteOnExit();
0615:
0616: String onlyAnalyse = sf.getJavaName();
0617: if (sf.isDirectory) {
0618: if (onlyAnalyse.length() == 0) {
0619: // analyse all !
0620: onlyAnalyse = null;
0621: } else {
0622: onlyAnalyse += ".-";
0623: }
0624: }
0625:
0626: new FindBugsLauncher(
0627: sf.isRoot() ? null : sf,
0628: onlyAnalyse,
0629: allSubFiles.size(),
0630: bf,
0631: MainEditorFrame.instance,
0632: MainEditorFrame.instance.globalProperties,
0633: progressDialog);
0634: } catch (final Exception e) {
0635: EventQueue.invokeLater(new Runnable() {
0636: public void run() {
0637: JOptionPane
0638: .showMessageDialog(
0639: SourcesTreePanel.this ,
0640: ""
0641: + e
0642: .getMessage(),
0643: "Error",
0644: JOptionPane.ERROR_MESSAGE);
0645: }
0646: });
0647:
0648: e.printStackTrace();
0649: } finally {
0650: progressDialog.closeDialog();
0651: }
0652: }
0653: };
0654: t.setName("Findbugs analysis");
0655: t.start();
0656: }
0657: });
0658:
0659: JMenuItem l4 = new JMenuItem("Analyse " + nSubFilesTxt
0660: + " with Lint4J"); // src and classes
0661: extToolsMenu.add(l4);
0662: l4.addActionListener(new ActionListener() {
0663: public void actionPerformed(ActionEvent ae) {
0664: if (!Lint4JSettingsDialog.isConfigured()) {
0665: Lint4JSettingsDialog fbst = new Lint4JSettingsDialog(
0666: MainEditorFrame.instance,
0667: MainEditorFrame.instance
0668: .getActualProject());
0669: if (!fbst.dialogWasAccepted
0670: || !Lint4JSettingsDialog.isConfigured()) {
0671: return;
0672: }
0673: }
0674:
0675: final List<File> sourceFiles = new ArrayList<File>();
0676: for (SourceFile sfi : allSubFiles) {
0677: if (!sfi.isIgnored()) {
0678: if (!sfi.javaPartName
0679: .equals("package-info")) {
0680: sourceFiles.add(sfi.javaFile);
0681: }
0682: }
0683: }
0684: MainEditorFrame.instance.editorPanel
0685: .saveChangedFiles();
0686:
0687: Thread t = new Thread() {
0688: public void run() {
0689: MainEditorFrame.instance.editorPanel
0690: .saveChangedFiles();
0691:
0692: try {
0693: Lint4JLauncher.analyse(sourceFiles);
0694: } catch (Exception e) {
0695: JOptionPane.showMessageDialog(
0696: SourcesTreePanel.this , ""
0697: + e.getMessage(),
0698: "Error",
0699: JOptionPane.ERROR_MESSAGE);
0700: e.printStackTrace();
0701: }
0702: }
0703: };
0704: t.setName("Lint4j analysis");
0705: t.start();
0706: }
0707: });
0708:
0709: JMenuItem jlint = new JMenuItem(
0710: "Analyse classes with JLint");
0711: extToolsMenu.add(jlint);
0712: jlint.addActionListener(new ActionListener() {
0713: public void actionPerformed(ActionEvent ae) {
0714: MainEditorFrame.instance.editorPanel
0715: .saveChangedFiles();
0716:
0717: if (!JLintSettingsDialog.isConfigured()) {
0718: JLintSettingsDialog fbst = new JLintSettingsDialog(
0719: MainEditorFrame.instance,
0720: MainEditorFrame.instance
0721: .getActualProject());
0722: if (!fbst.dialogWasAccepted
0723: || !JLintSettingsDialog.isConfigured()) {
0724: return;
0725: }
0726: }
0727:
0728: JLintChecker.analyse(allSubFiles);
0729: }
0730: });
0731:
0732: JMenuItem csd = new JMenuItem("Analyse " + nSubFilesTxt
0733: + " with CheckStyle");
0734: extToolsMenu.addSeparator();
0735: extToolsMenu.add(csd);
0736: csd.addActionListener(new ActionListener() {
0737: public void actionPerformed(ActionEvent ae) {
0738: MainEditorFrame.instance.editorPanel
0739: .saveChangedFiles();
0740: if (!CheckStyleSettingsDialog.isConfigured()) {
0741: CheckStyleSettingsDialog fbst = new CheckStyleSettingsDialog(
0742: MainEditorFrame.instance,
0743: MainEditorFrame.instance
0744: .getActualProject());
0745: if (!fbst.dialogWasAccepted
0746: || !CheckStyleSettingsDialog
0747: .isConfigured()) {
0748: return;
0749: }
0750: }
0751:
0752: MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc
0753: .clearDocument();
0754:
0755: final ProgressModalDialog progress = new ProgressModalDialog(
0756: MainEditorFrame.instance,
0757: "CheckStyle analysis", false);
0758: Thread t = new Thread(new Runnable() {
0759: public void run() {
0760: try {
0761: CheckStyleLauncher._analyse(false,
0762: progress, sf);
0763: } catch (Exception e) {
0764: JOptionPane.showMessageDialog(
0765: SourcesTreePanel.this , ""
0766: + e.getMessage(),
0767: "Error",
0768: JOptionPane.ERROR_MESSAGE);
0769: e.printStackTrace();
0770: }
0771: }
0772: });
0773: t.setName("CheckStyle analysis");
0774: t.setPriority(Thread.NORM_PRIORITY - 1);
0775: t.start();
0776: }
0777: });
0778:
0779: // Code provided by Mike K.
0780: JMenuItem astyle = new JMenuItem("Format " + nSubFilesTxt
0781: + " with AStyle", Icons.sharedWiz);
0782: extToolsMenu.add(astyle);
0783: astyle.addActionListener(new ActionListener() {
0784: public void actionPerformed(ActionEvent ae) {
0785: // important, since the files are being "rewritten"
0786: MainEditorFrame.instance.editorPanel
0787: .saveChangedFiles();
0788:
0789: if (!AStyleSettingsDialog.isConfigured()) {
0790: AStyleSettingsDialog fbst = new AStyleSettingsDialog(
0791: MainEditorFrame.instance,
0792: MainEditorFrame.instance
0793: .getActualProject());
0794: if (!fbst.dialogWasAccepted
0795: || !AStyleSettingsDialog.isConfigured()) {
0796: return;
0797: }
0798: }
0799:
0800: final ProgressModalDialog progress = new ProgressModalDialog(
0801: MainEditorFrame.instance,
0802: "AStyle formatting", false);
0803: Thread t = new Thread(new Runnable() {
0804: public void run() {
0805: try {
0806: AStyleLauncher._formatx(allSubFiles,
0807: progress);
0808: refreshTreeBranchFromFileSystem(sf);
0809: } catch (Exception e) {
0810: JOptionPane.showMessageDialog(
0811: SourcesTreePanel.this , ""
0812: + e.getMessage(),
0813: "Error",
0814: JOptionPane.ERROR_MESSAGE);
0815: e.printStackTrace();
0816: } finally {
0817: progress.closeDialog();
0818: }
0819: }
0820: });
0821: t.setName("AStyle format");
0822: t.setPriority(Thread.NORM_PRIORITY - 1);
0823: t.start();
0824:
0825: }
0826: });
0827:
0828: JMenuItem search = new JMenuItem("Search text in sources",
0829: Icons.sharedSearch);
0830: search.setAccelerator(Accelerators.globalSearch); // fake, calls another action, but nice to mention to the user now.
0831: popup.addSeparator();
0832: popup.add(search);
0833: search.addActionListener(new ActionListener() {
0834: public void actionPerformed(ActionEvent ae) {
0835: // only not ignored files
0836: List<SourceFile> files = new ArrayList<SourceFile>();
0837: for (SourceFile sf : allSubFiles) {
0838: if (!sf.isIgnored())
0839: files.add(sf);
0840: }
0841: MainEditorFrame.instance.editorPanel
0842: .saveChangedFiles();
0843: new SearchTool(files, false, "Search in "
0844: + files.size() + " source"
0845: + (files.size() == 0 ? "" : "s"));
0846: }
0847: });
0848:
0849: JMenuItem searchD = new JMenuItem("Search filenames",
0850: Icons.sharedSearch);
0851: searchD
0852: .setAccelerator(Accelerators.globalProjectFilenameSearch); // CTRL+F also mapped...
0853: popup.add(searchD);
0854: searchD.addActionListener(new ActionListener() {
0855: public void actionPerformed(ActionEvent ae) {
0856: // only not ignored files
0857: List<SourceFile> files = new ArrayList<SourceFile>();
0858: for (SourceFile sf : allSubFiles) {
0859: if (!sf.isIgnored())
0860: files.add(sf);
0861: }
0862:
0863: new SearchTool(files, true, "Search in "
0864: + files.size() + " filenames"
0865: + (files.size() == 0 ? "" : "s"));
0866: }
0867: });
0868: }
0869:
0870: // ignore /restore
0871: popup.addSeparator();
0872:
0873: boolean ignoreignore = sf.isSourceFile() && sf.isIgnored();
0874: if (!ignoreignore) {
0875: JMenuItem ignore = new JMenuItem("Ignore in this project",
0876: Icons.sharedCross);
0877: popup.add(ignore);
0878: ignore.addActionListener(new ActionListener() {
0879: public void actionPerformed(ActionEvent ae) {
0880: setIgnoredFlagRecurse(sf, true);
0881: }
0882: });
0883: }
0884:
0885: boolean ignorerestore = sf.isSourceFile() && !sf.isIgnored();
0886: if (!ignorerestore) {
0887: JMenuItem restore = new JMenuItem("Restore in this project");
0888: popup.add(restore);
0889: restore.addActionListener(new ActionListener() {
0890: public void actionPerformed(ActionEvent ae) {
0891: setIgnoredFlagRecurse(sf, false);
0892: }
0893: });
0894: }
0895:
0896: // Bookmarks
0897: //
0898: popup.addSeparator();
0899: SharedUtils.addBookmarksPopup(popup, sf.getJavaName());
0900:
0901: if (sf.isJavaFile()) {
0902: // add bookmark
0903: JMenuItem addBookmark = new JMenuItem(
0904: "Add a bookmark here", Icons.sharedPlus);
0905: popup.add(addBookmark);
0906: addBookmark.addActionListener(new ActionListener() {
0907: public void actionPerformed(ActionEvent ae) {
0908: String tt = JOptionPane
0909: .showInputDialog(
0910: SourcesTreePanel.this ,
0911: "Adding a bookmark for the sourcefile\n\n "
0912: + sf.getJavaName()
0913: + "\n\nBookmark description (optional)",
0914: "Add a bookmark",
0915: JOptionPane.QUESTION_MESSAGE);
0916: if (tt == null)
0917: return;
0918: MainEditorFrame.instance
0919: .getActualProject()
0920: .addBookmark(
0921: new SourceBookmark(
0922: sf.getJavaName(), 0, 0, tt)); // position 0
0923: }
0924: });
0925: }
0926:
0927: JMenu utilsMenu = new JMenu("Utilities");
0928: popup.addSeparator();
0929: popup.add(utilsMenu);
0930:
0931: JMenuItem parseDebug = new JMenuItem(
0932: "Parse and show warnings and errors");
0933: utilsMenu.add(parseDebug);
0934: parseDebug.addActionListener(new ActionListener() {
0935: public void actionPerformed(ActionEvent ae) {
0936: MainEditorFrame.instance.editorPanel.saveChangedFiles();
0937: TreeFunctions.parseAllToSearchForProblems(allSubFiles,
0938: false);
0939: }
0940: });
0941:
0942: //if(MainEditorFrame.enableExperimental)
0943: {
0944: JMenuItem parseDebug2 = new JMenuItem(
0945: "Parse with the new CC parser");
0946: utilsMenu.add(parseDebug2);
0947: parseDebug2.addActionListener(new ActionListener() {
0948: public void actionPerformed(ActionEvent ae) {
0949: MainEditorFrame.instance.editorPanel
0950: .saveChangedFiles();
0951: TreeFunctions.parseAllToSearchForProblems2(
0952: allSubFiles, false);
0953: }
0954: });
0955: }
0956:
0957: /* automatically performed when editing source => not really necessary anymore */
0958: if (MainEditorFrame.debug) {
0959: JMenuItem removeTailSpaces = new JMenuItem(
0960: "Remove spaces at end of lines", Icons.sharedWiz);
0961: utilsMenu.addSeparator();
0962: utilsMenu.add(removeTailSpaces);
0963: removeTailSpaces.addActionListener(new ActionListener() {
0964: public void actionPerformed(ActionEvent ae) {
0965: MainEditorFrame.instance.editorPanel
0966: .saveChangedFiles();
0967: TreeFunctions.removeTailingSpaces(allSubFiles);
0968: }
0969: });
0970: }
0971:
0972: JMenuItem stats = new JMenuItem("Statistics", Icons.sharedStat);
0973: utilsMenu.addSeparator();
0974: utilsMenu.add(stats);
0975: stats.addActionListener(new ActionListener() {
0976: public void actionPerformed(ActionEvent ae) {
0977: MainEditorFrame.instance.editorPanel.saveChangedFiles();
0978: CodeStats.analyse(allSubFiles, allSubFiles.size() == 1);
0979: }
0980: });
0981:
0982: if (allSubFiles.size() > 1) {
0983: JMenuItem stats2 = new JMenuItem("Detailled statistics",
0984: Icons.sharedStat);
0985: //utilsMenu.addSeparator();
0986: utilsMenu.add(stats2);
0987: stats2.addActionListener(new ActionListener() {
0988: public void actionPerformed(ActionEvent ae) {
0989: MainEditorFrame.instance.editorPanel
0990: .saveChangedFiles();
0991: CodeStats.analyse(allSubFiles, true);
0992: }
0993: });
0994: }
0995:
0996: JMenuItem analysePackageDepends = new JMenuItem(
0997: "View package dependencies", new Icons.TableIcon(18,
0998: 18, 4, 4, false));
0999: utilsMenu.addSeparator();
1000: utilsMenu.add(analysePackageDepends);
1001: analysePackageDepends.addActionListener(new ActionListener() {
1002: public void actionPerformed(ActionEvent ae) {
1003: MainEditorFrame.instance.editorPanel.saveChangedFiles();
1004: PackagesDependenciesAnalysis pdep = new PackagesDependenciesAnalysis(
1005: allSubFiles);
1006: new PackagesDependenciesViewer(pdep,
1007: "Packages dependencies of node "
1008: + sf.getJavaName()
1009: + " of project "
1010: + MainEditorFrame.instance
1011: .getActualProject()
1012: .getProjectName());
1013: }
1014: });
1015: JMenuItem viewSFDeps = new JMenuItem(
1016: "View source dependencies", new Icons.HArrow(14, 14,
1017: true, true, false));
1018: utilsMenu.add(viewSFDeps);
1019: viewSFDeps.addActionListener(new ActionListener() {
1020: public void actionPerformed(ActionEvent ae) {
1021: MainEditorFrame.instance.editorPanel.saveChangedFiles();
1022:
1023: SourceFileUtils.writeDependencies(sf,
1024: MainEditorFrame.instance.outputPanels
1025: .select_tIDE_Tab(true).doc);
1026: }
1027: });
1028:
1029: if (MainEditorFrame.enableExperimental) {
1030: JMenuItem detectDepBranch = new JMenuItem(
1031: "Reparse dependencies (debug)");
1032: //utilsMenu.addSeparator();
1033: utilsMenu.add(detectDepBranch);
1034: detectDepBranch.addActionListener(new ActionListener() {
1035: public void actionPerformed(ActionEvent ae) {
1036: MainEditorFrame.instance.outputPanels
1037: .selectToolsTab(true);
1038: MainEditorFrame.instance.editorPanel
1039: .saveChangedFiles(); // important
1040: Thread t = TreeFunctions
1041: .createDetectDependenciesThread(
1042: allSubFiles,
1043: allSubFiles.size() == 1); // write out only if we have a single file.
1044: t.start();
1045: }
1046: });
1047: }
1048:
1049: String jn = sf.getJavaName();
1050: JMenuItem viewMess = new JMenuItem("View all messages"
1051: + (jn.length() > 0 ? " for " + jn : ""));
1052: viewMess.setAccelerator(Accelerators.viewMessagesOfSelected);
1053: utilsMenu.addSeparator();
1054: utilsMenu.add(viewMess);
1055: viewMess.addActionListener(new ActionListener() {
1056: public void actionPerformed(ActionEvent ae) {
1057: MainEditorFrame.instance.outputPanels.filterMessages(sf
1058: .getJavaName());
1059: }
1060: });
1061:
1062: if (MainEditorFrame.enableExperimental) {
1063: JMenuItem viewBPS = new JMenuItem("View all breakpoints");
1064: utilsMenu.add(viewBPS);
1065: viewBPS.addActionListener(new ActionListener() {
1066: public void actionPerformed(ActionEvent ae) {
1067: MainEditorFrame.instance.outputPanels
1068: .filterMessages("BreakPoint");
1069: }
1070: });
1071: }
1072:
1073: //JMenu debugMenu = new JMenu("Debug");
1074: //popup.add(debugMenu);
1075:
1076: JMenu fsMenu = new JMenu("File system");
1077: popup.addSeparator();
1078: popup.add(fsMenu);
1079:
1080: JMenuItem reloadBranch = new JMenuItem(
1081: "Refresh from OS filesystem", Icons.sharedWiz);
1082: reloadBranch.setAccelerator(Accelerators.scanExtFileChanges);
1083: fsMenu.add(reloadBranch);
1084: reloadBranch.addActionListener(new ActionListener() {
1085: public void actionPerformed(ActionEvent ae) {
1086: refreshTreeBranchFromFileSystem(sf);
1087: }
1088: });
1089:
1090: if (sf.isDirectory()) {
1091: FileIcon sdir = new FileIcon(true, 15);
1092: sdir.setType(FileIcon.IconColor.System);
1093: JMenuItem explore = new JMenuItem(
1094: "Open in OS file explorer", sdir);
1095: fsMenu.add(explore);
1096: explore.addActionListener(new ActionListener() {
1097: public void actionPerformed(ActionEvent ae) {
1098: SysUtils.openFileExplorer(sf.getFileOrDirectory());
1099: }
1100: });
1101:
1102: FileIcon dir = new FileIcon(true, 15);
1103: dir.setType(FileIcon.IconColor.RedGreen);
1104: JMenuItem internalexplore = new JMenuItem(
1105: "Internal file explorer", dir);
1106: internalexplore
1107: .setAccelerator(Accelerators.internalFilesExplorer);
1108: fsMenu.addSeparator();
1109: fsMenu.add(internalexplore);
1110: internalexplore.addActionListener(new ActionListener() {
1111: public void actionPerformed(ActionEvent ae) {
1112: new SourcesExplorer(allSubFiles,
1113: MainEditorFrame.instance, "Files in node "
1114: + sf.getJavaName());
1115: }
1116: });
1117:
1118: FileIcon dir2 = new FileIcon(true, 15);
1119: dir2.setType(FileIcon.IconColor.RedGreen);
1120: JMenuItem internalexplore2 = new JMenuItem(
1121: "Internal package explorer", dir2);
1122: //internalexplore.setAccelerator(Accelerators.internalFilesExplorer);
1123: //fsMenu.addSeparator();
1124: fsMenu.add(internalexplore2);
1125: internalexplore2.addActionListener(new ActionListener() {
1126: public void actionPerformed(ActionEvent ae) {
1127: new PackagesExplorer(allSubFiles,
1128: MainEditorFrame.instance);
1129: }
1130: });
1131:
1132: FileIcon dir3 = new FileIcon(true, 15);
1133: dir3.setType(FileIcon.IconColor.RedGreen);
1134: JMenuItem internalResourceExpl = new JMenuItem(
1135: "Internal resources explorer", dir3);
1136: internalResourceExpl
1137: .setAccelerator(Accelerators.internalResourcesExplorer);
1138: //fsMenu.addSeparator();
1139: fsMenu.add(internalResourceExpl);
1140: internalResourceExpl
1141: .addActionListener(new ActionListener() {
1142: public void actionPerformed(ActionEvent ae) {
1143: FileItem viewed = MainEditorFrame.instance.editorPanel
1144: .getActualDisplayedFile();
1145: File editedSrc = (viewed instanceof SourceFile) ? ((SourceFile) viewed)
1146: .getFileOrDirectory()
1147: : null;
1148: new ResourcesExplorer(
1149: MainEditorFrame.instance
1150: .getActualProject()
1151: .getSources_Home(), sf
1152: .getFileOrDirectory(),
1153: editedSrc);
1154: }
1155: });
1156: } else {
1157: FileIcon sdir = new FileIcon(true, 15);
1158: sdir.setType(FileIcon.IconColor.System);
1159: JMenuItem explore = new JMenuItem(
1160: "Open parent folder in OS file explorer", sdir);
1161: fsMenu.add(explore);
1162: explore.addActionListener(new ActionListener() {
1163: public void actionPerformed(ActionEvent ae) {
1164: SysUtils.openFileExplorer(sf.getFileOrDirectory()
1165: .getParentFile());
1166: }
1167: });
1168: }
1169:
1170: //[Feb2008]: seems to work fine when no conflicts... => enable
1171: // if(MainEditorFrame.enableExperimental)
1172: {
1173: JMenu m = SVNOps.create_SourcesTreePopupMenu(sf);
1174: popup.addSeparator();
1175: popup.add(m);
1176: }
1177:
1178: popup.show(tree, me.getX(), me.getY());
1179: } // showPopup
1180:
1181: void addNewSourceDialog(String pack0, String content) {
1182: NewSourceDialog nsd = new NewSourceDialog(
1183: MainEditorFrame.instance, pack0, content); // =package name
1184: if (!nsd.wasAccepted())
1185: return;
1186: if (!nsd.checkNameValidity()) {
1187: // NO
1188: System.out.println("New source NOT valid.");
1189: return;
1190: }
1191:
1192: String cn = nsd.getJavaSimpleName();
1193: //JOptionPane.showInputDialog(SourcesTreePanel.this, "Enter the new class name in package "+sf.getJavaName());
1194: if (cn == null || cn.trim().length() == 0)
1195: return;
1196: String sourceName = cn.trim();
1197: try {
1198: // some checks:
1199: if (sourceName.indexOf(' ') >= 0)
1200: throw new RuntimeException(
1201: "Source name cannot contain spaces !");
1202: if (sourceName.indexOf('.') >= 0)
1203: throw new RuntimeException(
1204: "Source name cannot contain dots !");
1205:
1206: FileItem pack = getTreeModel().getPackage(
1207: nsd.getPackageName());
1208: if (pack == null) {
1209: pack = getTreeModel().createOrGetPackage(null,
1210: nsd.getPackageName());
1211: }
1212:
1213: final SourceFile addedFile = getTreeModel()
1214: .createNewJavaSourceFile((SourceFile) pack,
1215: sourceName, nsd.generateSourceContent());
1216:
1217: // select it !
1218: TreePath tp = new TreePath(addedFile.getPath());
1219: tree.setSelectionPath(tp);
1220: updateTree();
1221: // TODO: give focus to the source editor
1222: MainEditorFrame.instance.editorPanel.getTextPane()
1223: .requestFocus();
1224: } catch (Exception e) {
1225: JOptionPane.showMessageDialog(SourcesTreePanel.this , ""
1226: + e.getMessage(), "Cannot create source file",
1227: JOptionPane.ERROR_MESSAGE);
1228: e.printStackTrace();
1229: }
1230: }
1231:
1232: /** Rescan the tree colors based on structure. and update the UI.
1233: * should be called after edit, compile, detect, create, rename, ...
1234: */
1235: public void updateTree() {
1236: getTreeModel().setFolderColors();
1237: tree.repaint();
1238:
1239: MainEditorFrame.instance.editorPanel.updateHistoryIcons();
1240: }
1241:
1242: /** Looks on the filesystem for differences (partial sync), updates the tree.
1243: */
1244: public void refreshTreeBranchFromFileSystem(final SourceFile sf) {
1245: MainEditorFrame.instance.editorPanel.saveChangedFiles();
1246: this .getTreeModel().deleteCachedEditedContents(sf);
1247:
1248: getTreeModel().scanForDifferencesWithFileSystem(sf);
1249: /*
1250: //[Nov2007]
1251: FileItem fi = MainEditorFrame.instance.editorPanel.getActualDisplayedFile();
1252: if(fi!=null && fi.getHasBeenRemoved())
1253: {
1254: MainEditorFrame.instance.editorPanel.removeTab(fi);
1255: }*/
1256:
1257: MainEditorFrame.instance.editorPanel
1258: .replaceContentWithContentOnDisk();
1259: updateTree();
1260:
1261: MainEditorFrame.instance.editorPanel.updateHistoryIcons();
1262: }
1263:
1264: private void setIgnoredFlagRecurse(SourceFile sf, boolean ignore) {
1265: ProjectSettings project = MainEditorFrame.instance
1266: .getActualProject();
1267: List<SourceFile> allFiles = new ArrayList<SourceFile>();
1268: getTreeModel().getAllSourceFilesRecurse(sf, allFiles, true,
1269: true); // include folders AND ignored files, of course
1270: for (SourceFile sfi : allFiles) {
1271: if (ignore) {
1272: sfi.setIgnoredType(SourcesTreeIcon.Ignored.Yes);
1273: } else {
1274: sfi.setIgnoredType(SourcesTreeIcon.Ignored.No);
1275: }
1276: }
1277:
1278: // also set the dir itself
1279:
1280: if (ignore) {
1281: sf.setIgnoredType(SourcesTreeIcon.Ignored.Yes);
1282: } else {
1283: sf.setIgnoredType(SourcesTreeIcon.Ignored.No);
1284: }
1285: getTreeModel().setFolderColors();
1286: tree.repaint();
1287: }
1288:
1289: public void allowDropFilesFromOS() {
1290: new FileDropTarget(this );
1291: }
1292:
1293: class FileDropTarget extends DropTarget {
1294: public FileDropTarget(JComponent c) {
1295: super (c, DnDConstants.ACTION_COPY,
1296: new FileDropTargetListener(c), true);
1297: c.setDropTarget(this );
1298:
1299: }
1300: }
1301:
1302: class FileDropTargetListener implements DropTargetListener {
1303: JComponent comp;
1304: Border originalBorder = null;
1305: Border redBorder = BorderFactory.createLineBorder(Color.red, 1);
1306: Border greenBorder = BorderFactory.createLineBorder(
1307: Color.green, 1);
1308:
1309: public FileDropTargetListener(JComponent comp) {
1310: this .comp = comp;
1311: this .originalBorder = comp.getBorder();
1312: }
1313:
1314: public boolean isValidCandidate(File f) {
1315: // also accept directories ? => TODO.
1316: String n = f.getName().toLowerCase();
1317: return n.endsWith(".java");
1318: }
1319:
1320: File fileToDrop = null;
1321:
1322: public void dragEnter(DropTargetDragEvent dte) {
1323: //System.out.println("dragEnter");
1324:
1325: boolean accept = false;
1326: fileToDrop = null;
1327: for (DataFlavor df : dte.getCurrentDataFlavors()) {
1328: if (df.isFlavorJavaFileListType()) {
1329: Transferable tr = dte.getTransferable();
1330: try {
1331: Object data = tr
1332: .getTransferData(df.javaFileListFlavor);
1333: //System.out.println(""+data);
1334: @SuppressWarnings("unchecked")
1335: List<File> lf = (List<File>) data;
1336: if (lf.size() == 1) {
1337: if (isValidCandidate(lf.get(0))) {
1338: fileToDrop = lf.get(0);
1339: //pathField.setToolTipText("Droping "+lf.get(0));
1340: dte
1341: .acceptDrag(DnDConstants.ACTION_COPY);
1342: accept = true;
1343: break;
1344: }
1345: }
1346: } catch (Exception e) {
1347: comp.setBorder(redBorder);
1348: e.printStackTrace();
1349: }
1350: } else if (df.isFlavorTextType()) {
1351: Transferable tr = dte.getTransferable();
1352: try {
1353: String data = ""
1354: + tr
1355: .getTransferData(df.javaFileListFlavor);
1356: if (data.toLowerCase().startsWith("file://"))
1357: data = data.substring(6);
1358:
1359: File f = new File(data);
1360: if (isValidCandidate(f)) {
1361: fileToDrop = f;
1362: //pathField.setToolTipText("Droping "+f); // don't work
1363: //ToolTipManager.sharedInstance().setDismissDelay(.showTipWindow();
1364: dte.acceptDrag(DnDConstants.ACTION_COPY);
1365: accept = true;
1366: break;
1367: }
1368:
1369: } catch (Exception e) {
1370: comp.setBorder(redBorder);
1371: e.printStackTrace();
1372: }
1373: }
1374: //System.out.println(""+df);
1375: }
1376:
1377: if (accept) {
1378: comp.setBorder(greenBorder);
1379: } else {
1380: comp.setBorder(redBorder);
1381: }
1382: }
1383:
1384: public void dragExit(DropTargetEvent dte) {
1385: //System.out.println("dragExit");
1386: setToolTipText(null);
1387: setBorder(originalBorder);
1388: }
1389:
1390: public void dragOver(DropTargetDragEvent dte) {
1391: //System.out.println("dragOver");
1392: }
1393:
1394: public void drop(DropTargetDropEvent dte) {
1395: setBorder(originalBorder);
1396: setToolTipText(null);
1397: System.out.println("drop " + fileToDrop);
1398: if (fileToDrop.isFile()) {
1399: try {
1400: String cont = FileUtils
1401: .getFileStringContent(fileToDrop);
1402: addNewSourceDialog("", cont);
1403: } catch (Exception e) {
1404: e.printStackTrace();
1405: }
1406: }
1407: }
1408:
1409: public void dropActionChanged(DropTargetDragEvent dte) {
1410: System.out.println("dropActionChanged");
1411: }
1412: }
1413:
1414: }
|