Document and organise code
This commit is contained in:
@ -11,6 +11,7 @@ import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.sourceforge.pmd.PMDVersion;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil;
|
||||
|
||||
import javafx.application.Application;
|
||||
@ -23,7 +24,7 @@ import javafx.stage.Stage;
|
||||
|
||||
|
||||
/**
|
||||
* Main class for the designer.
|
||||
* Main class for the designer, launched only if {@link DesignerStarter} detected JavaFX support.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
* @since 6.0.0
|
||||
@ -45,13 +46,12 @@ public class Designer extends Application {
|
||||
|
||||
@Override
|
||||
public void start(Stage stage) throws IOException {
|
||||
boolean developerMode = parseParameters(getParameters());
|
||||
boolean isDeveloperMode = parseParameters(getParameters());
|
||||
|
||||
|
||||
FXMLLoader loader
|
||||
= new FXMLLoader(DesignerUtil.getFxml("designer.fxml"));
|
||||
FXMLLoader loader = new FXMLLoader(DesignerUtil.getFxml("designer.fxml"));
|
||||
|
||||
DesignerRoot owner = new DesignerRoot(stage, developerMode);
|
||||
DesignerRoot owner = new DesignerRoot(stage, isDeveloperMode);
|
||||
MainDesignerController mainController = new MainDesignerController(owner);
|
||||
|
||||
NodeInfoPanelController nodeInfoPanelController = new NodeInfoPanelController(mainController);
|
||||
|
@ -23,14 +23,14 @@ import org.reactfx.value.Val;
|
||||
import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.XPathEvaluationException;
|
||||
import net.sourceforge.pmd.util.fxdesigner.popups.EventLogController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.AbstractController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.ApplicationComponent;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.CompositeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.AbstractController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.CompositeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.LimitedSizeStack;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.NodeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.NodeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.SoftReferenceCache;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.TextAwareNodeWrapper;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.beans.SettingsPersistenceUtil;
|
||||
@ -67,12 +67,7 @@ import javafx.stage.FileChooser;
|
||||
* @since 6.0.0
|
||||
*/
|
||||
@SuppressWarnings("PMD.UnusedPrivateField")
|
||||
public class MainDesignerController extends AbstractController implements CompositeSelectionSource, ApplicationComponent {
|
||||
|
||||
/**
|
||||
* Callback to the owner.
|
||||
*/
|
||||
private final DesignerRoot designerRoot;
|
||||
public class MainDesignerController extends AbstractController<AbstractController<?>> implements CompositeSelectionSource {
|
||||
|
||||
|
||||
/* Menu bar */
|
||||
@ -115,16 +110,11 @@ public class MainDesignerController extends AbstractController implements Compos
|
||||
|
||||
|
||||
public MainDesignerController(DesignerRoot owner) {
|
||||
this.designerRoot = owner;
|
||||
super(owner, null);
|
||||
eventLogController = new SoftReferenceCache<>(() -> new EventLogController(this));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DesignerRoot getDesignerRoot() {
|
||||
return designerRoot;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void beforeParentInit() {
|
||||
@ -142,7 +132,7 @@ public class MainDesignerController extends AbstractController implements Compos
|
||||
openRecentMenu.setOnShowing(e -> updateRecentFilesMenu());
|
||||
fileMenu.setOnShowing(e -> onFileMenuShowing());
|
||||
|
||||
setupAuxclasspathMenuItem.setOnAction(e -> sourceEditorController.showAuxclasspathSetupPopup(designerRoot));
|
||||
setupAuxclasspathMenuItem.setOnAction(e -> sourceEditorController.showAuxclasspathSetupPopup());
|
||||
|
||||
openEventLogMenuItem.setOnAction(e -> eventLogController.getValue().showPopup());
|
||||
openEventLogMenuItem.textProperty().bind(
|
||||
@ -163,12 +153,12 @@ public class MainDesignerController extends AbstractController implements Compos
|
||||
// the xpath panel is forwarded to the treeView, which
|
||||
// forwards back an event, etc.
|
||||
getSelectionEvents().thenIgnoreFor(Duration.ofMillis(20))
|
||||
.subscribe(n -> CompositeSelectionSource.super.select(n));
|
||||
.subscribe(n -> CompositeSelectionSource.super.bubbleDown(n));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ObservableSet<? extends NodeSelectionSource> getComponents() {
|
||||
public ObservableSet<? extends NodeSelectionSource> getSubSelectionSources() {
|
||||
return FXCollections.observableSet(nodeInfoPanelController, sourceEditorController, xpathPanelController);
|
||||
}
|
||||
|
||||
@ -298,7 +288,7 @@ public class MainDesignerController extends AbstractController implements Compos
|
||||
private void onOpenFileClicked() {
|
||||
FileChooser chooser = new FileChooser();
|
||||
chooser.setTitle("Load source from file");
|
||||
File file = chooser.showOpenDialog(designerRoot.getMainStage());
|
||||
File file = chooser.showOpenDialog(getMainStage());
|
||||
loadSourceFromFile(file);
|
||||
}
|
||||
|
||||
@ -396,13 +386,13 @@ public class MainDesignerController extends AbstractController implements Compos
|
||||
|
||||
@PersistentProperty
|
||||
public boolean isMaximized() {
|
||||
return designerRoot.getMainStage().isMaximized();
|
||||
return getMainStage().isMaximized();
|
||||
}
|
||||
|
||||
|
||||
public void setMaximized(boolean b) {
|
||||
designerRoot.getMainStage().setMaximized(!b); // trigger change listener anyway
|
||||
designerRoot.getMainStage().setMaximized(b);
|
||||
getMainStage().setMaximized(!b); // trigger change listener anyway
|
||||
getMainStage().setMaximized(b);
|
||||
}
|
||||
|
||||
|
||||
@ -420,7 +410,7 @@ public class MainDesignerController extends AbstractController implements Compos
|
||||
|
||||
|
||||
@Override
|
||||
public List<AbstractController> getChildren() {
|
||||
public List<AbstractController<MainDesignerController>> getChildren() {
|
||||
return Arrays.asList(xpathPanelController, sourceEditorController, nodeInfoPanelController);
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,8 @@ import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
|
||||
import net.sourceforge.pmd.lang.symboltable.Scope;
|
||||
import net.sourceforge.pmd.lang.symboltable.ScopedNode;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.MetricResult;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.AbstractController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.NodeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.AbstractController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.NodeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.beans.SettingsPersistenceUtil.PersistentProperty;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.controls.ScopeHierarchyTreeCell;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.controls.ScopeHierarchyTreeItem;
|
||||
@ -57,9 +57,8 @@ import javafx.scene.control.TreeView;
|
||||
* @since 6.0.0
|
||||
*/
|
||||
@SuppressWarnings("PMD.UnusedPrivateField")
|
||||
public class NodeInfoPanelController extends AbstractController implements NodeSelectionSource {
|
||||
public class NodeInfoPanelController extends AbstractController<MainDesignerController> implements NodeSelectionSource {
|
||||
|
||||
private final MainDesignerController parent;
|
||||
|
||||
/** List of attribute names that are ignored if {@link #isHideCommonAttributes()} is true. */
|
||||
private static final List<String> IGNORABLE_ATTRIBUTES =
|
||||
@ -85,15 +84,10 @@ public class NodeInfoPanelController extends AbstractController implements NodeS
|
||||
private Node selectedNode;
|
||||
|
||||
public NodeInfoPanelController(MainDesignerController mainController) {
|
||||
parent = mainController;
|
||||
super(mainController);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DesignerRoot getDesignerRoot() {
|
||||
return parent.getDesignerRoot();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void beforeParentInit() {
|
||||
|
@ -32,10 +32,10 @@ import net.sourceforge.pmd.util.ClasspathClassLoader;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.ASTManager;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.ParseAbortedException;
|
||||
import net.sourceforge.pmd.util.fxdesigner.popups.AuxclasspathSetupController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.AbstractController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.CompositeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.AbstractController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.CompositeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.NodeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.NodeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.TextAwareNodeWrapper;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.beans.SettingsPersistenceUtil.PersistentProperty;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.codearea.AvailableSyntaxHighlighters;
|
||||
@ -62,7 +62,7 @@ import javafx.scene.control.ToggleGroup;
|
||||
* @author Clément Fournier
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class SourceEditorController extends AbstractController implements CompositeSelectionSource {
|
||||
public class SourceEditorController extends AbstractController<MainDesignerController> implements CompositeSelectionSource {
|
||||
|
||||
private static final Duration AST_REFRESH_DELAY = Duration.ofMillis(100);
|
||||
|
||||
@ -81,8 +81,6 @@ public class SourceEditorController extends AbstractController implements Compos
|
||||
|
||||
private final ASTManager astManager;
|
||||
|
||||
private final MainDesignerController parent;
|
||||
|
||||
private final Var<Node> currentFocusNode = Var.newSimpleVar(null);
|
||||
|
||||
private final Var<List<File>> auxclasspathFiles = Var.newSimpleVar(emptyList());
|
||||
@ -99,18 +97,12 @@ public class SourceEditorController extends AbstractController implements Compos
|
||||
|
||||
|
||||
public SourceEditorController(MainDesignerController mainController) {
|
||||
parent = mainController;
|
||||
super(mainController);
|
||||
astManager = new ASTManager(mainController.getDesignerRoot());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DesignerRoot getDesignerRoot() {
|
||||
return parent.getDesignerRoot();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void beforeParentInit() {
|
||||
|
||||
@ -200,7 +192,7 @@ public class SourceEditorController extends AbstractController implements Compos
|
||||
|
||||
|
||||
@Override
|
||||
public ObservableSet<? extends NodeSelectionSource> getComponents() {
|
||||
public ObservableSet<? extends NodeSelectionSource> getSubSelectionSources() {
|
||||
return FXCollections.observableSet(astTreeView, focusNodeParentageCrumbBar);
|
||||
}
|
||||
|
||||
@ -230,10 +222,9 @@ public class SourceEditorController extends AbstractController implements Compos
|
||||
}
|
||||
|
||||
|
||||
public void showAuxclasspathSetupPopup(DesignerRoot root) {
|
||||
new AuxclasspathSetupController(root).show(root.getMainStage(),
|
||||
auxclasspathFiles.getValue(),
|
||||
auxclasspathFiles::setValue);
|
||||
public void showAuxclasspathSetupPopup() {
|
||||
new AuxclasspathSetupController(getDesignerRoot())
|
||||
.show(getMainStage(), auxclasspathFiles.getValue(), auxclasspathFiles::setValue);
|
||||
}
|
||||
|
||||
private void setUpToDateCompilationUnit(Node node) {
|
||||
|
@ -27,14 +27,14 @@ import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.rule.XPathRule;
|
||||
import net.sourceforge.pmd.lang.rule.xpath.XPathRuleQuery;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.LogEntry.Category;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.LogEntry.Category;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.ObservableXPathRuleBuilder;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.XPathEvaluationException;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.XPathEvaluator;
|
||||
import net.sourceforge.pmd.util.fxdesigner.popups.ExportXPathWizardController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.AbstractController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.AbstractController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.NodeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.NodeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.TextAwareNodeWrapper;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.autocomplete.CompletionResultSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.autocomplete.XPathAutocompleteProvider;
|
||||
@ -75,10 +75,9 @@ import javafx.stage.StageStyle;
|
||||
* @see ExportXPathWizardController
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class XPathPanelController extends AbstractController implements NodeSelectionSource {
|
||||
public class XPathPanelController extends AbstractController<MainDesignerController> implements NodeSelectionSource {
|
||||
|
||||
private static final Duration XPATH_REFRESH_DELAY = Duration.ofMillis(100);
|
||||
private final MainDesignerController parent;
|
||||
private final XPathEvaluator xpathEvaluator = new XPathEvaluator();
|
||||
private final ObservableXPathRuleBuilder ruleBuilder = new ObservableXPathRuleBuilder();
|
||||
|
||||
@ -103,16 +102,11 @@ public class XPathPanelController extends AbstractController implements NodeSele
|
||||
|
||||
|
||||
public XPathPanelController(MainDesignerController mainController) {
|
||||
parent = mainController;
|
||||
super(mainController);
|
||||
getRuleBuilder().setClazz(XPathRule.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DesignerRoot getDesignerRoot() {
|
||||
return parent.getDesignerRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeParentInit() {
|
||||
xpathExpressionArea.setSyntaxHighlighter(new XPathSyntaxHighlighter());
|
||||
|
@ -2,7 +2,7 @@
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.util.fxdesigner.util;
|
||||
package net.sourceforge.pmd.util.fxdesigner.app;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
@ -16,24 +16,62 @@ import javafx.fxml.Initializable;
|
||||
|
||||
|
||||
/**
|
||||
* Make the initialization cycle of JavaFX clearer. Children controller
|
||||
* are initialized before their parent, but sometimes it should only
|
||||
* Base class for controllers of the app. The main window of the app is split
|
||||
* into regions corresponding to some area of functionality. Each has its own
|
||||
* FXML file that can be found in the fxml resource directory. Each also has
|
||||
* its own independent controller. Since the FXML regions are nested like a
|
||||
* tree (the JavaFX scene graph), it's natural to link the controllers in a
|
||||
* tree too.
|
||||
*
|
||||
* <p>For now controllers mostly communicate by sending messages to their parent
|
||||
* and letting it forward the message to the rest of the app. TODO I'm more and more
|
||||
* convinced we should avoid that and stop having the controllers hold a reference
|
||||
* to their parent. They should only communicate by exposing properties their parent
|
||||
* binds to, but they shouldn't know about their parent.
|
||||
*
|
||||
* <p>This class mainly to make the initialization cycle of JavaFX clearer. Children controllers
|
||||
* are initialized before their parent, but sometimes they should only
|
||||
* perform some actions after its parent has been initialized, e.g. binding
|
||||
* properties that depend on a restored setting or stuff. This is part
|
||||
* of the reason why {@link Platform#runLater(Runnable)} can sometimes
|
||||
* be enough to solve initialization problems.
|
||||
*
|
||||
* This only works if all controllers in the tree extend this class.
|
||||
* <p>This only works if all controllers in the initialization sequence of an
|
||||
* FXML file extend this class.
|
||||
*
|
||||
*
|
||||
* @param <T> Type of the parent controller
|
||||
*
|
||||
* @author Clément Fournier
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public abstract class AbstractController implements Initializable, SettingsOwner, ApplicationComponent {
|
||||
public abstract class AbstractController<T extends AbstractController<?>> implements Initializable, SettingsOwner, ApplicationComponent {
|
||||
|
||||
protected final T parent;
|
||||
private final DesignerRoot designerRoot;
|
||||
|
||||
|
||||
protected AbstractController(DesignerRoot root, T parent) {
|
||||
this.parent = parent;
|
||||
this.designerRoot = root;
|
||||
}
|
||||
|
||||
|
||||
protected AbstractController(T parent) {
|
||||
this(parent.getDesignerRoot(), parent);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DesignerRoot getDesignerRoot() {
|
||||
return designerRoot;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
beforeParentInit();
|
||||
for (AbstractController child : getChildren()) {
|
||||
for (AbstractController<?> child : getChildren()) {
|
||||
child.afterParentInit();
|
||||
}
|
||||
afterChildrenInit();
|
||||
@ -76,7 +114,7 @@ public abstract class AbstractController implements Initializable, SettingsOwner
|
||||
}
|
||||
|
||||
|
||||
protected List<? extends AbstractController> getChildren() {
|
||||
protected List<? extends AbstractController<?>> getChildren() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.util.fxdesigner.app;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.sourceforge.pmd.util.fxdesigner.SourceEditorController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.LogEntry.Category;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.NodeSelectionSource.NodeSelectionEvent;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.beans.SettingsOwner;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.controls.AstTreeView;
|
||||
|
||||
import javafx.scene.control.Control;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
|
||||
/**
|
||||
* Some part of the application, e.g. a controller. Components in an instance of the app are all linked
|
||||
* to the same {@link DesignerRoot}, which hosts utilities globally available to the app, e.g. the logger.
|
||||
*
|
||||
* <p>Components that are not controllers, e.g. {@link Control}s, should be injected with the designer
|
||||
* root at initialization time, eg what {@link SourceEditorController} does with {@link AstTreeView}.
|
||||
*
|
||||
* <p>Some more specific cross-cutting structures for the internals of the app are the {@link SettingsOwner}
|
||||
* tree, which is more or less identical to the {@link AbstractController} tree. {@link NodeSelectionSource}s
|
||||
* form yet another similar tree of related components.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
*/
|
||||
public interface ApplicationComponent {
|
||||
|
||||
|
||||
DesignerRoot getDesignerRoot();
|
||||
|
||||
|
||||
/**
|
||||
* A debug name for this component, used in developer mode to e.g. trace events
|
||||
* handling paths.
|
||||
*/
|
||||
default String getDebugName() {
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the logger of the application. Events pushed to the logger
|
||||
* are filtered then forwarded to the Event Log control.
|
||||
*
|
||||
* @return The logger
|
||||
*/
|
||||
default EventLogger getLogger() {
|
||||
return getDesignerRoot().getLogger();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the main stage of the application.
|
||||
*/
|
||||
default Stage getMainStage() {
|
||||
return getDesignerRoot().getMainStage();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If true, some more events are pushed to the event log, and
|
||||
* console streams are open. This is enabled by the -v or --verbose
|
||||
* option on command line for now.
|
||||
*/
|
||||
default boolean isDeveloperMode() {
|
||||
return getDesignerRoot().isDeveloperMode();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notify the logger of an exception that somewhere in PMD logic. Exceptions raised
|
||||
* by the app logic are considered internal and should be forwarded to the logger
|
||||
* using {@link #logInternalException(Throwable)}. If we're not in developer mode
|
||||
* they will be ignored.
|
||||
*/
|
||||
default void logUserException(Throwable throwable, Category category) {
|
||||
getLogger().logEvent(LogEntry.createUserExceptionEntry(throwable, category));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notify the logger that XPath parsing succeeded and that the last recent failure may be thrown away.
|
||||
* Only logged in developer mode.
|
||||
*/
|
||||
default void raiseParsableXPathFlag() {
|
||||
getLogger().logEvent(LogEntry.createUserFlagEntry(Category.XPATH_OK));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notify the logger that source code parsing succeeded and that the last recent failure may be thrown away.
|
||||
* Only logged in developer mode.
|
||||
*/
|
||||
default void raiseParsableSourceFlag() {
|
||||
getLogger().logEvent(LogEntry.createUserFlagEntry(Category.PARSE_OK));
|
||||
}
|
||||
|
||||
// Internal log handlers
|
||||
|
||||
|
||||
/** Logs an exception that occurred somewhere in the app logic. */
|
||||
default void logInternalException(Throwable throwable) {
|
||||
if (isDeveloperMode()) {
|
||||
getLogger().logEvent(LogEntry.createInternalExceptionEntry(throwable));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Logs an exception that occurred somewhere in the app logic. */
|
||||
default void logInternalDebugInfo(Supplier<String> shortMessage, Supplier<String> details) {
|
||||
if (isDeveloperMode()) {
|
||||
getLogger().logEvent(LogEntry.createInternalDebugEntry(shortMessage.get(), details.get()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Logs a tracing event pushed by a {@link NodeSelectionSource}. */
|
||||
default void logSelectionEventTrace(NodeSelectionEvent event, Supplier<String> details) {
|
||||
if (isDeveloperMode()) {
|
||||
getLogger().logEvent(LogEntry.createNodeSelectionEventTraceEntry(event, details.get()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.util.fxdesigner.util;
|
||||
package net.sourceforge.pmd.util.fxdesigner.app;
|
||||
|
||||
import org.reactfx.EventStream;
|
||||
import org.reactfx.EventStreams;
|
||||
@ -13,17 +13,20 @@ import javafx.collections.ObservableSet;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link NodeSelectionSource} that merges the events of several sub-components. Such a source
|
||||
* can also handle events itself via {@link #setFocusNode(Node)}.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
*/
|
||||
public interface CompositeSelectionSource extends NodeSelectionSource {
|
||||
|
||||
|
||||
ObservableSet<? extends NodeSelectionSource> getComponents();
|
||||
/** Returns the sources to forward to when bubbling down, and from which to merge events when bubbling up. */
|
||||
ObservableSet<? extends NodeSelectionSource> getSubSelectionSources();
|
||||
|
||||
|
||||
@Override
|
||||
default EventStream<NodeSelectionEvent> getSelectionEvents() {
|
||||
return EventStreams.merge(getComponents(), NodeSelectionSource::getSelectionEvents);
|
||||
return EventStreams.merge(getSubSelectionSources(), NodeSelectionSource::getSelectionEvents);
|
||||
}
|
||||
|
||||
|
||||
@ -35,12 +38,12 @@ public interface CompositeSelectionSource extends NodeSelectionSource {
|
||||
|
||||
|
||||
@Override
|
||||
default void select(NodeSelectionEvent selectionEvent) {
|
||||
NodeSelectionSource.super.select(selectionEvent);
|
||||
default void bubbleDown(NodeSelectionEvent selectionEvent) {
|
||||
NodeSelectionSource.super.bubbleDown(selectionEvent);
|
||||
|
||||
for (NodeSelectionSource source : getComponents()) {
|
||||
for (NodeSelectionSource source : getSubSelectionSources()) {
|
||||
logSelectionEventTrace(selectionEvent, () -> getDebugName() + " forwards to " + source.getDebugName());
|
||||
source.select(selectionEvent);
|
||||
source.bubbleDown(selectionEvent);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,9 +2,7 @@
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.util.fxdesigner;
|
||||
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.EventLogger;
|
||||
package net.sourceforge.pmd.util.fxdesigner.app;
|
||||
|
||||
import javafx.stage.Stage;
|
||||
|
||||
@ -19,13 +17,14 @@ public final class DesignerRoot {
|
||||
|
||||
|
||||
private final Stage mainStage;
|
||||
private final EventLogger logger = new EventLogger(this);
|
||||
private final EventLogger logger;
|
||||
private final boolean developerMode;
|
||||
|
||||
|
||||
public DesignerRoot(Stage mainStage, boolean developerMode) {
|
||||
this.mainStage = mainStage;
|
||||
this.developerMode = developerMode;
|
||||
this.logger = new EventLogger(this);
|
||||
}
|
||||
|
||||
|
||||
@ -49,6 +48,11 @@ public final class DesignerRoot {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If true, some more events are pushed to the event log, and
|
||||
* console streams are open. This is enabled by the -v or --verbose
|
||||
* option on command line for now.
|
||||
*/
|
||||
public boolean isDeveloperMode() {
|
||||
return developerMode;
|
||||
}
|
@ -2,13 +2,13 @@
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.util.fxdesigner.model;
|
||||
package net.sourceforge.pmd.util.fxdesigner.app;
|
||||
|
||||
import static net.sourceforge.pmd.util.fxdesigner.model.LogEntry.Category.PARSE_EXCEPTION;
|
||||
import static net.sourceforge.pmd.util.fxdesigner.model.LogEntry.Category.PARSE_OK;
|
||||
import static net.sourceforge.pmd.util.fxdesigner.model.LogEntry.Category.SELECTION_EVENT_TRACING;
|
||||
import static net.sourceforge.pmd.util.fxdesigner.model.LogEntry.Category.XPATH_EVALUATION_EXCEPTION;
|
||||
import static net.sourceforge.pmd.util.fxdesigner.model.LogEntry.Category.XPATH_OK;
|
||||
import static net.sourceforge.pmd.util.fxdesigner.app.LogEntry.Category.PARSE_EXCEPTION;
|
||||
import static net.sourceforge.pmd.util.fxdesigner.app.LogEntry.Category.PARSE_OK;
|
||||
import static net.sourceforge.pmd.util.fxdesigner.app.LogEntry.Category.SELECTION_EVENT_TRACING;
|
||||
import static net.sourceforge.pmd.util.fxdesigner.app.LogEntry.Category.XPATH_EVALUATION_EXCEPTION;
|
||||
import static net.sourceforge.pmd.util.fxdesigner.app.LogEntry.Category.XPATH_OK;
|
||||
import static net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil.countNotMatching;
|
||||
import static net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil.reduceEntangledIfPossible;
|
||||
|
||||
@ -23,12 +23,13 @@ import org.reactfx.collection.LiveArrayList;
|
||||
import org.reactfx.collection.LiveList;
|
||||
import org.reactfx.value.Val;
|
||||
|
||||
import net.sourceforge.pmd.util.fxdesigner.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.LogEntry.Category;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.LogEntry.LogEntryWithData;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.ApplicationComponent;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.LogEntry;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.LogEntry.Category;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.LogEntry.LogEntryWithData;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.ApplicationComponent;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.NodeSelectionSource.NodeSelectionEvent;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.NodeSelectionSource.NodeSelectionEvent;
|
||||
|
||||
|
||||
/**
|
||||
@ -51,7 +52,7 @@ public class EventLogger implements ApplicationComponent {
|
||||
|
||||
|
||||
public EventLogger(DesignerRoot designerRoot) {
|
||||
this.designerRoot = designerRoot;
|
||||
this.designerRoot = designerRoot; // we have to be careful with initialization order here
|
||||
|
||||
EventStream<LogEntryWithData<NodeSelectionEvent>> eventTraces =
|
||||
reduceEntangledIfPossible(filterOnCategory(latestEvent, false, SELECTION_EVENT_TRACING).map(t -> (LogEntryWithData<NodeSelectionEvent>) t),
|
@ -2,17 +2,16 @@
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.util.fxdesigner.model;
|
||||
package net.sourceforge.pmd.util.fxdesigner.app;
|
||||
|
||||
import static net.sourceforge.pmd.util.fxdesigner.model.LogEntry.Category.CategoryType.FLAG;
|
||||
import static net.sourceforge.pmd.util.fxdesigner.app.LogEntry.Category.CategoryType.FLAG;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.reactfx.value.Var;
|
||||
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.NodeSelectionSource.NodeSelectionEvent;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.NodeSelectionSource.NodeSelectionEvent;
|
||||
|
||||
|
||||
/**
|
@ -2,7 +2,7 @@
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.util.fxdesigner.util;
|
||||
package net.sourceforge.pmd.util.fxdesigner.app;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@ -10,28 +10,42 @@ import org.reactfx.EventStream;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.util.fxdesigner.MainDesignerController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.beans.SettingsOwner;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.controls.AstTreeView;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.controls.NodeParentageCrumbBar;
|
||||
|
||||
|
||||
/**
|
||||
* A control or controller that has the ability to push node selection events.
|
||||
* When a node is selected in the control (e.g. {@link AstTreeView}, {@link NodeParentageCrumbBar}, etc),
|
||||
* the whole UI is synchronized to the node. Selection events are merged iteratively into
|
||||
* a global stream for the whole app. Events from that stream are handled by {@link MainDesignerController}.
|
||||
* A control or controller that somehow displays nodes in a form that the user can select.
|
||||
* When a node is selected by the user (e.g. {@link AstTreeView}, {@link NodeParentageCrumbBar}, etc),
|
||||
* the whole UI is synchronized to reflect information about the node. This includes scrolling
|
||||
* the TreeView, the editor, etc. To achieve that uniformly, node selection events are merged
|
||||
* into a global stream for the whole app. Events from that stream are handled by {@link MainDesignerController}.
|
||||
*
|
||||
* <p>Node selection sources form a tree parallel to {@link AbstractController} and {@link SettingsOwner}.
|
||||
* This interface implements behaviour for leaves of the tree. Inner nodes are handled by
|
||||
* {@link CompositeSelectionSource}.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
*/
|
||||
public interface NodeSelectionSource extends ApplicationComponent {
|
||||
|
||||
/**
|
||||
* Returns a stream of nodes that pushes an event every time
|
||||
* this control records a *user* change in selection.
|
||||
* Returns a stream of events that should push an event each time
|
||||
* this source or one of its sub components records a change in node
|
||||
* selection.
|
||||
*/
|
||||
EventStream<NodeSelectionEvent> getSelectionEvents();
|
||||
|
||||
|
||||
default void select(NodeSelectionEvent selectionEvent) {
|
||||
/**
|
||||
* Bubbles a selection event down the tree. First, {@link #setFocusNode(Node)} is called to
|
||||
* handle the event (if the event didn't originate from here). If this is not a leaf of the tree,
|
||||
* then the event is forwarded to the children nodes as well.
|
||||
*
|
||||
* @param selectionEvent Event to handle
|
||||
*/
|
||||
default void bubbleDown(NodeSelectionEvent selectionEvent) {
|
||||
if (alwaysHandleSelection() || selectionEvent.getOrigin() != this) {
|
||||
logSelectionEventTrace(selectionEvent, () -> "\t" + this.getDebugName() + " is handling event");
|
||||
setFocusNode(selectionEvent.getSelection());
|
||||
@ -39,14 +53,24 @@ public interface NodeSelectionSource extends ApplicationComponent {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the UI to react to a change in focus node. This is called whenever some selection source
|
||||
* in the tree records a change. The event is not forwarded to its origin unless {@link #alwaysHandleSelection()}
|
||||
* is overridden to return true.
|
||||
*/
|
||||
void setFocusNode(Node node);
|
||||
|
||||
|
||||
/** Whether to also handle events which originated from this controller. */
|
||||
default boolean alwaysHandleSelection() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An event fired when the user selects a node somewhere in the UI
|
||||
* and bubbled up to the {@link MainDesignerController}.
|
||||
*/
|
||||
final class NodeSelectionEvent {
|
||||
|
||||
private final Node selection;
|
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interfaces and base classes that structure an support the whole app.
|
||||
*/
|
||||
package net.sourceforge.pmd.util.fxdesigner.app;
|
@ -15,13 +15,14 @@ import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
import net.sourceforge.pmd.lang.LanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.util.fxdesigner.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.LogEntry.Category;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.ApplicationComponent;
|
||||
import net.sourceforge.pmd.util.fxdesigner.SourceEditorController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.LogEntry.Category;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.ApplicationComponent;
|
||||
|
||||
|
||||
/**
|
||||
* Main class of the model. Manages a compilation unit.
|
||||
* Manages a compilation unit for {@link SourceEditorController}.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
* @since 6.0.0
|
||||
|
@ -5,7 +5,6 @@
|
||||
package net.sourceforge.pmd.util.fxdesigner.model;
|
||||
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.sourceforge.pmd.lang.metrics.MetricKey;
|
||||
|
||||
@ -23,11 +22,6 @@ public class MetricResult {
|
||||
}
|
||||
|
||||
|
||||
MetricResult(Entry<? extends MetricKey<?>, ? extends Double> entry) {
|
||||
simpleEntry = new SimpleEntry<>(entry);
|
||||
}
|
||||
|
||||
|
||||
public MetricKey<?> getKey() {
|
||||
return simpleEntry.getKey();
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ import net.sourceforge.pmd.lang.Language;
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
import net.sourceforge.pmd.rules.RuleBuilder;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.PropertyDescriptorSpec;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.beans.SettingsOwner;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.beans.SettingsPersistenceUtil.PersistentProperty;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.beans.SettingsPersistenceUtil.PersistentSequence;
|
||||
|
@ -2,7 +2,7 @@
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.util.fxdesigner.util;
|
||||
package net.sourceforge.pmd.util.fxdesigner.model;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
@ -19,7 +19,6 @@ import net.sourceforge.pmd.RuleSets;
|
||||
import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.rule.XPathRule;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.PropertyDescriptorSpec;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* PMD's rule designer. A good starting point to learn about the global structure of the app
|
||||
* is {@link net.sourceforge.pmd.util.fxdesigner.app.ApplicationComponent}, and
|
||||
* {@link net.sourceforge.pmd.util.fxdesigner.app.AbstractController}.
|
||||
*/
|
||||
package net.sourceforge.pmd.util.fxdesigner;
|
@ -15,7 +15,7 @@ import java.util.function.Consumer;
|
||||
import org.reactfx.collection.LiveList;
|
||||
import org.reactfx.value.Val;
|
||||
|
||||
import net.sourceforge.pmd.util.fxdesigner.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
|
@ -22,7 +22,7 @@ import net.sourceforge.pmd.properties.PropertyTypeId;
|
||||
import net.sourceforge.pmd.properties.ValueParser;
|
||||
import net.sourceforge.pmd.properties.ValueParserConstants;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.PropertyDescriptorSpec;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.PropertyDescriptorSpec;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.controls.PropertyTableView;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
@ -19,11 +19,11 @@ import org.reactfx.value.Val;
|
||||
import org.reactfx.value.Var;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.util.fxdesigner.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.MainDesignerController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.LogEntry;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.LogEntry.Category;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.AbstractController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.EventLogger;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.LogEntry;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.LogEntry.Category;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.AbstractController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil;
|
||||
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
@ -47,20 +47,17 @@ import javafx.stage.Stage;
|
||||
|
||||
|
||||
/**
|
||||
* A presenter over the {@link net.sourceforge.pmd.util.fxdesigner.model.EventLogger}.
|
||||
* A presenter over the {@link EventLogger}.
|
||||
* There's not necessarily one in the app, it can be garbage collected and recreated.
|
||||
* Each of these necessarily has a live UI component though.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public final class EventLogController extends AbstractController {
|
||||
public final class EventLogController extends AbstractController<MainDesignerController> {
|
||||
|
||||
private static final PseudoClass NEW_ENTRY = PseudoClass.getPseudoClass("new-entry");
|
||||
|
||||
private final DesignerRoot designerRoot;
|
||||
private final MainDesignerController mediator;
|
||||
|
||||
@FXML
|
||||
private TableView<LogEntry> eventLogTableView;
|
||||
@FXML
|
||||
@ -82,18 +79,12 @@ public final class EventLogController extends AbstractController {
|
||||
|
||||
|
||||
public EventLogController(MainDesignerController mediator) {
|
||||
this.designerRoot = mediator.getDesignerRoot();
|
||||
this.mediator = mediator;
|
||||
super(mediator);
|
||||
// the FXML fields are injected and initialize is called in createStage
|
||||
this.myPopupStage = createStage(designerRoot.getMainStage());
|
||||
this.myPopupStage = createStage(getMainStage());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DesignerRoot getDesignerRoot() {
|
||||
return designerRoot;
|
||||
}
|
||||
|
||||
|
||||
// this is only called each time a popup is created
|
||||
@Override
|
||||
@ -193,18 +184,18 @@ public final class EventLogController extends AbstractController {
|
||||
.successionEnds(Duration.ofMillis(100))
|
||||
.subscribe(b -> {
|
||||
if (b) {
|
||||
mediator.handleSelectedNodeInError(selectedErrorNodes.getValue());
|
||||
parent.handleSelectedNodeInError(selectedErrorNodes.getValue());
|
||||
} else {
|
||||
mediator.resetSelectedErrorNodes();
|
||||
parent.resetSelectedErrorNodes();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
binding = binding.and(
|
||||
selectedErrorNodes.values().subscribe(mediator::handleSelectedNodeInError)
|
||||
selectedErrorNodes.values().subscribe(parent::handleSelectedNodeInError)
|
||||
);
|
||||
|
||||
SortedList<LogEntry> logEntries = new SortedList<>(designerRoot.getLogger().getLog(), Comparator.reverseOrder());
|
||||
SortedList<LogEntry> logEntries = new SortedList<>(getLogger().getLog(), Comparator.reverseOrder());
|
||||
eventLogTableView.itemsProperty().setValue(logEntries);
|
||||
binding = binding.and(
|
||||
() -> eventLogTableView.itemsProperty().setValue(FXCollections.emptyObservableList())
|
||||
@ -228,7 +219,7 @@ public final class EventLogController extends AbstractController {
|
||||
entry.setExamined(true);
|
||||
|
||||
if (entry.getCategory().isUserException()) {
|
||||
DesignerUtil.stackTraceToXPath(entry.getDetails()).map(mediator::runXPathQuery).ifPresent(selectedErrorNodes::setValue);
|
||||
DesignerUtil.stackTraceToXPath(entry.getDetails()).map(parent::runXPathQuery).ifPresent(selectedErrorNodes::setValue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,7 +245,7 @@ public final class EventLogController extends AbstractController {
|
||||
|
||||
|
||||
private Val<String> titleProperty() {
|
||||
return designerRoot.getLogger().numNewLogEntriesProperty().map(i -> "Exception log (" + (i > 0 ? i : "no") + " new)");
|
||||
return parent.getLogger().numNewLogEntriesProperty().map(i -> "Exception log (" + (i > 0 ? i : "no") + " new)");
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,79 +0,0 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.util.fxdesigner.util;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.sourceforge.pmd.util.fxdesigner.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.EventLogger;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.LogEntry;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.LogEntry.Category;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.NodeSelectionSource.NodeSelectionEvent;
|
||||
|
||||
|
||||
/**
|
||||
* Some part of the application, linked to the {@link DesignerRoot}.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
*/
|
||||
public interface ApplicationComponent {
|
||||
|
||||
|
||||
DesignerRoot getDesignerRoot();
|
||||
|
||||
|
||||
default String getDebugName() {
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
|
||||
default EventLogger getLogger() {
|
||||
return getDesignerRoot().getLogger();
|
||||
}
|
||||
|
||||
|
||||
default boolean isDeveloperMode() {
|
||||
return getDesignerRoot().isDeveloperMode();
|
||||
}
|
||||
|
||||
|
||||
default void logUserException(Throwable throwable, Category category) {
|
||||
getLogger().logEvent(LogEntry.createUserExceptionEntry(throwable, category));
|
||||
}
|
||||
|
||||
|
||||
default void raiseParsableXPathFlag() {
|
||||
getLogger().logEvent(LogEntry.createUserFlagEntry(Category.XPATH_OK));
|
||||
}
|
||||
|
||||
|
||||
default void raiseParsableSourceFlag() {
|
||||
getLogger().logEvent(LogEntry.createUserFlagEntry(Category.PARSE_OK));
|
||||
}
|
||||
|
||||
// Internal log handlers
|
||||
|
||||
|
||||
default void logInternalException(Throwable throwable) {
|
||||
if (isDeveloperMode()) {
|
||||
getLogger().logEvent(LogEntry.createInternalExceptionEntry(throwable));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
default void logInternalDebugInfo(Supplier<String> shortMessage, Supplier<String> details) {
|
||||
if (isDeveloperMode()) {
|
||||
getLogger().logEvent(LogEntry.createInternalDebugEntry(shortMessage.get(), details.get()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
default void logSelectionEventTrace(NodeSelectionEvent event, Supplier<String> details) {
|
||||
if (isDeveloperMode()) {
|
||||
getLogger().logEvent(LogEntry.createNodeSelectionEventTraceEntry(event, details.get()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -18,8 +18,8 @@ import org.reactfx.SuspendableEventStream;
|
||||
import org.reactfx.value.Var;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.util.fxdesigner.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.NodeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.NodeSelectionSource;
|
||||
|
||||
import javafx.scene.control.SelectionModel;
|
||||
import javafx.scene.control.TreeItem;
|
||||
|
@ -17,8 +17,8 @@ import org.reactfx.EventStream;
|
||||
import org.reactfx.value.Val;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.util.fxdesigner.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.NodeSelectionSource;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.DesignerRoot;
|
||||
import net.sourceforge.pmd.util.fxdesigner.app.NodeSelectionSource;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.css.PseudoClass;
|
||||
|
@ -13,7 +13,7 @@ import org.reactfx.value.Var;
|
||||
import net.sourceforge.pmd.properties.PropertyTypeId;
|
||||
import net.sourceforge.pmd.util.fxdesigner.popups.EditPropertyDialogController;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.PropertyDescriptorSpec;
|
||||
import net.sourceforge.pmd.util.fxdesigner.model.PropertyDescriptorSpec;
|
||||
import net.sourceforge.pmd.util.fxdesigner.util.SoftReferenceCache;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
Reference in New Issue
Block a user