forked from phoedos/pmd
commited a patch provided by Andrei Badea <andrei.badea@movzx.net>:
1. Fixes the bug where if you slide the results window and invoke Run PMD the results window is docked in the output mode again. 2. Adds a Window - PMD Output action which opens the results window. 3. Allows jumping to a problem by pressing Enter in the results window. 4. Fixes the threading of OutputWindow. 5. Some minor cleanup in RunPMDAction. git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@4827 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
@ -25,14 +25,15 @@
|
||||
# DAMAGE.
|
||||
#
|
||||
|
||||
CTL_ShowOutputWindowAction=PMD Output
|
||||
LBL_Action=Run PM&D
|
||||
|
||||
OpenIDE-Module-Name=PMD
|
||||
OpenIDE-Module-Display-Category=Java
|
||||
OpenIDE-Module-Short-Description=Runs the PMD source code scanner tool.
|
||||
OpenIDE-Module-Long-Description=Runs the PMD source code scanner tool. \
|
||||
Finds various problems in your code and reports them to you easily. \
|
||||
Hyperlinked Output Window display.
|
||||
Finds various problems in your code and reports them to you \
|
||||
in a tabular output window.
|
||||
|
||||
LBL_pmd_annotation=PMD Error
|
||||
|
||||
|
@ -49,8 +49,8 @@ class GotoProblemAction extends AbstractAction {
|
||||
|
||||
protected boolean action(){
|
||||
return next?
|
||||
!OutputWindow.getInstance().selectNextResult():
|
||||
!OutputWindow.getInstance().selectPreviousResult();
|
||||
!OutputWindow.findInstance().selectNextResult():
|
||||
!OutputWindow.findInstance().selectPreviousResult();
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
@ -28,28 +28,37 @@
|
||||
package pmd;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.Serializable;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.ActionMap;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import org.openide.ErrorManager;
|
||||
import org.openide.awt.StatusDisplayer;
|
||||
import org.openide.cookies.LineCookie;
|
||||
import org.openide.loaders.DataObject;
|
||||
import org.openide.text.Line;
|
||||
import org.openide.text.Line.Set;
|
||||
import org.openide.windows.Mode;
|
||||
import org.openide.windows.TopComponent;
|
||||
import org.openide.windows.WindowManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Tomasz Slota <tomslot@gmail.com>
|
||||
* @author Andrei Badea <andrei.badea@movzx.net>
|
||||
*/
|
||||
public class OutputWindow extends TopComponent {
|
||||
|
||||
private static final String PREFERRED_ID = "PMDOutputWindow";
|
||||
|
||||
private JTable tblResults = new JTable();
|
||||
private ViolationsTableModel tblMdlResults = new ViolationsTableModel();
|
||||
private TableSorter tblSorter = null;
|
||||
@ -57,6 +66,8 @@ public class OutputWindow extends TopComponent {
|
||||
|
||||
/** Creates a new instance of OutputWindow */
|
||||
private OutputWindow() {
|
||||
setDisplayName("PMD Output");
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
tblSorter = new TableSorter(tblMdlResults);
|
||||
@ -80,6 +91,25 @@ public class OutputWindow extends TopComponent {
|
||||
}
|
||||
});
|
||||
initActions();
|
||||
|
||||
tblResults.getActionMap().put("selectViolation", new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
int row = tblResults.getSelectedRow();
|
||||
if (row != -1) {
|
||||
selectResultRow(row);
|
||||
}
|
||||
}
|
||||
});
|
||||
tblResults.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
|
||||
"selectViolation");
|
||||
}
|
||||
|
||||
public void requestActive() {
|
||||
super.requestActive();
|
||||
if (tblResults != null) {
|
||||
tblResults.requestFocusInWindow();
|
||||
}
|
||||
}
|
||||
|
||||
/** Map F12/S-F12 to next/prev error */
|
||||
@ -126,7 +156,12 @@ public class OutputWindow extends TopComponent {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static OutputWindow getInstance(){
|
||||
/**
|
||||
* Gets default instance. Do not use directly: reserved for *.settings files only,
|
||||
* i.e. deserialization routines; otherwise you could get a non-deserialized instance.
|
||||
* To obtain the singleton instance, use {@link findInstance}.
|
||||
*/
|
||||
public static synchronized OutputWindow getDefault(){
|
||||
if (instance == null){
|
||||
instance = new OutputWindow();
|
||||
}
|
||||
@ -134,32 +169,55 @@ public class OutputWindow extends TopComponent {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void open() {
|
||||
Mode m = WindowManager.getDefault().findMode("output");
|
||||
if (m != null) {
|
||||
m.dockInto(this);
|
||||
/**
|
||||
* Obtain the OutputWindow_Generated instance. Never call {@link #getDefault} directly!
|
||||
*/
|
||||
public static synchronized OutputWindow findInstance() {
|
||||
TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
|
||||
if (win == null) {
|
||||
ErrorManager.getDefault().log(ErrorManager.WARNING,
|
||||
"Cannot find PMDOutputWindow component. It will not be located properly in the window system.");
|
||||
return getDefault();
|
||||
}
|
||||
super.open();
|
||||
if (win instanceof OutputWindow) {
|
||||
return (OutputWindow)win;
|
||||
}
|
||||
ErrorManager.getDefault().log(ErrorManager.WARNING,
|
||||
"There seem to be multiple components with the '" + PREFERRED_ID +
|
||||
"' ID. That is a potential source of errors and unexpected behavior.");
|
||||
return getDefault();
|
||||
}
|
||||
|
||||
public void promote() {
|
||||
open();
|
||||
requestActive();
|
||||
}
|
||||
|
||||
protected String preferredID(){
|
||||
return "PMDOutput";
|
||||
return PREFERRED_ID;
|
||||
}
|
||||
|
||||
public int getPersistenceType(){
|
||||
return PERSISTENCE_NEVER;
|
||||
return PERSISTENCE_ALWAYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Avoids serializing the properties of this top component,
|
||||
* which is not really necessary. Instead, getDefault() will get called
|
||||
* when the component (or actually the replacer returned by this method)
|
||||
* is deserialized.
|
||||
*/
|
||||
public Object writeReplace() {
|
||||
return new ResolvableHelper();
|
||||
}
|
||||
|
||||
public void setViolations(Fault violations[]){
|
||||
tblMdlResults.setViolations(violations);
|
||||
|
||||
if (violations.length > 0){
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
selectResultRow(0);
|
||||
tblResults.getSelectionModel().setSelectionInterval(0, 0);
|
||||
}
|
||||
});
|
||||
selectResultRow(0);
|
||||
tblResults.getSelectionModel().setSelectionInterval(0, 0);
|
||||
tblResults.getColumnModel().getSelectionModel().setSelectionInterval(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,4 +300,13 @@ public class OutputWindow extends TopComponent {
|
||||
String msg = fault.getMessage();
|
||||
return msg.substring(msg.indexOf(",") + 1);
|
||||
}
|
||||
|
||||
final static class ResolvableHelper implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Object readResolve() {
|
||||
return OutputWindow.getDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
8
pmd-netbeans/src/pmd/OutputWindowSettings.xml
Normal file
8
pmd-netbeans/src/pmd/OutputWindowSettings.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
|
||||
<settings version="1.0">
|
||||
<module name="pmd" spec="1.8.1"/>
|
||||
<instanceof class="org.openide.windows.TopComponent"/>
|
||||
<instanceof class="pmd.OutputWindow"/>
|
||||
<instance class="pmd.OutputWindow" method="getDefault"/>
|
||||
</settings>
|
7
pmd-netbeans/src/pmd/OutputWindowWstcref.xml
Normal file
7
pmd-netbeans/src/pmd/OutputWindowWstcref.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE tc-ref PUBLIC "-//NetBeans//DTD Top Component in Mode Properties 2.0//EN" "http://www.netbeans.org/dtds/tc-ref2_0.dtd">
|
||||
<tc-ref version="2.0" >
|
||||
<module name="pmd" spec="1.8.1"/>
|
||||
<tc-id id="PMDOutputWindow"/>
|
||||
<state opened="false"/>
|
||||
</tc-ref>
|
@ -263,7 +263,6 @@ public class RunPMDAction extends CookieAction {
|
||||
*/
|
||||
protected void performAction( Node[] node ) {
|
||||
FaultRegistry.getInstance().clearRegistry();
|
||||
OutputWriter out = null;
|
||||
try {
|
||||
StatusDisplayer.getDefault().setStatusText("PMD checking for rule violations");
|
||||
List<DataObject> list = getDataObjects(node);
|
||||
@ -275,23 +274,19 @@ public class RunPMDAction extends CookieAction {
|
||||
else {
|
||||
StatusDisplayer.getDefault().setStatusText("PMD found rule violations");
|
||||
}
|
||||
|
||||
final OutputWindow wnd = OutputWindow.getInstance();
|
||||
wnd.setViolations(violations.toArray(new Fault[violations.size()]));
|
||||
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable(){
|
||||
public void run(){
|
||||
OutputWindow wnd = OutputWindow.findInstance();
|
||||
wnd.setViolations(violations.toArray(new Fault[violations.size()]));
|
||||
wnd.setDisplayName("PMD Output: found " + violations.size() + " violations");
|
||||
wnd.open();
|
||||
wnd.requestActive();
|
||||
if (violations.size() > 0 ) {
|
||||
wnd.promote();
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch(IOException e) {
|
||||
ErrorManager.getDefault().notify(e);
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
59
pmd-netbeans/src/pmd/ShowOutputWindowAction.java
Normal file
59
pmd-netbeans/src/pmd/ShowOutputWindowAction.java
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2006, the pmd-netbeans team
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*/
|
||||
package pmd;
|
||||
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
|
||||
/**
|
||||
* @author Andrei Badea <andrei.badea@movzx.net>
|
||||
*/
|
||||
public final class ShowOutputWindowAction extends CallableSystemAction {
|
||||
|
||||
public void performAction() {
|
||||
OutputWindow.findInstance().promote();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return NbBundle.getMessage(ShowOutputWindowAction.class, "CTL_ShowOutputWindowAction");
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
super.initialize();
|
||||
// see org.openide.util.actions.SystemAction.iconResource() javadoc for more details
|
||||
putValue("noIconInMenu", Boolean.TRUE);
|
||||
}
|
||||
|
||||
public HelpCtx getHelpCtx() {
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
}
|
||||
|
||||
protected boolean asynchronous() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -15,10 +15,22 @@
|
||||
<attr name="SystemFileSystem.icon" urlvalue="nbresloc:/pmd/resources/PMDOptionsSettingsIcon.gif"/>
|
||||
</file>
|
||||
</folder>
|
||||
<folder name="Menu">
|
||||
<folder name="Window">
|
||||
<attr name="ResultWindowOpenAction.shadow/pmd-ShowOutputWindowAction.shadow" boolvalue="true"/>
|
||||
<file name="pmd-ShowOutputWindowAction.shadow">
|
||||
<attr name="originalFile" stringvalue="Actions/Window/pmd-ShowOutputWindowAction.instance"/>
|
||||
</file>
|
||||
<attr name="pmd-ShowOutputWindowAction.shadow/Debug" boolvalue="true"/>
|
||||
</folder>
|
||||
</folder>
|
||||
<folder name="Actions">
|
||||
<folder name="Tools">
|
||||
<file name="pmd-RunPMDAction.instance"/>
|
||||
</folder>
|
||||
<folder name="Window">
|
||||
<file name="pmd-ShowOutputWindowAction.instance"/>
|
||||
</folder>
|
||||
</folder>
|
||||
<folder name="Editors">
|
||||
<folder name="AnnotationTypes">
|
||||
@ -30,5 +42,18 @@
|
||||
<file name="D-O-P.instance">
|
||||
<attr name="instanceClass" stringvalue="pmd.RunPMDAction"/>
|
||||
</file>
|
||||
<file name="DOS-P.shadow">
|
||||
<attr name="originalFile" stringvalue="Actions/Window/pmd-ShowOutputWindowAction.instance"/>
|
||||
</file>
|
||||
</folder>
|
||||
<folder name="Windows2">
|
||||
<folder name="Components">
|
||||
<file name="PMDOutputWindow.settings" url="OutputWindowSettings.xml"/>
|
||||
</folder>
|
||||
<folder name="Modes">
|
||||
<folder name="output">
|
||||
<file name="PMDOutputWindow.wstcref" url="OutputWindowWstcref.xml"/>
|
||||
</folder>
|
||||
</folder>
|
||||
</folder>
|
||||
</filesystem>
|
||||
|
Reference in New Issue
Block a user