From ad078fad59b1c0c1911afde35dce8ed567168754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 30 Dec 2018 16:14:55 +0100 Subject: [PATCH 01/26] Deprecate StatisticalRule --- docs/pages/release_notes.md | 9 +++++++++ .../lang/apex/rule/AbstractStatisticalApexRule.java | 5 +++++ .../src/main/java/net/sourceforge/pmd/Report.java | 4 ++++ .../sourceforge/pmd/ThreadSafeReportListener.java | 2 ++ .../pmd/lang/rule/stat/StatisticalRule.java | 12 ++++++++++++ .../pmd/lang/rule/stat/StatisticalRuleHelper.java | 2 ++ .../java/net/sourceforge/pmd/stat/DataPoint.java | 4 ++++ .../main/java/net/sourceforge/pmd/stat/Metric.java | 5 +++++ .../lang/java/rule/AbstractStatisticalJavaRule.java | 5 +++++ .../plsql/rule/AbstractStatisticalPLSQLRule.java | 5 +++++ .../pmd/lang/vm/rule/AbstractStatisticalVmRule.java | 5 +++++ 11 files changed, 58 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b6f74252f8..ee18caec85 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -55,6 +55,15 @@ This is a {{ site.pmd.release_type }} release. ### API Changes +#### Deprecated API + +* {% jdoc core::lang.rule.stat.StatisticalRule %} and the related helper classes and base rule classes +are deprecated for removal in 7.0.0. This includes all of {% jdoc_package core::stat %} and {% jdoc_package core::lang.rule.stat %}, +and also {% jdoc java::lang.java.rule.AbstractStatisticalJavaRule %}, {% jdoc apex::lang.apex.rule.AbstractStatisticalApexRule %} and the like. +The methods {% jdoc !c!core::Report#addMetric(core::stat.Metric) %} and {% jdoc core::ThreadSafeReportListener#metricAdded(core::stat.Metric) %} +will also be removed. + + ### External Contributions * [#1503](https://github.com/pmd/pmd/pull/1503): \[java] Fix for ReturnFromFinallyBlock false-positives - [RishabhDeep Singh](https://github.com/rishabhdeepsingh) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/AbstractStatisticalApexRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/AbstractStatisticalApexRule.java index 054bea94c9..8ca4a8b4a5 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/AbstractStatisticalApexRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/AbstractStatisticalApexRule.java @@ -12,6 +12,11 @@ import net.sourceforge.pmd.lang.rule.stat.StatisticalRule; import net.sourceforge.pmd.lang.rule.stat.StatisticalRuleHelper; import net.sourceforge.pmd.stat.DataPoint; + +/** + * @deprecated see {@link StatisticalRule} + */ +@Deprecated public abstract class AbstractStatisticalApexRule extends AbstractApexRule implements StatisticalRule { private final StatisticalRuleHelper helper = new StatisticalRuleHelper(this); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/Report.java b/pmd-core/src/main/java/net/sourceforge/pmd/Report.java index 694a8b657e..04f7dd2a18 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/Report.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/Report.java @@ -20,6 +20,7 @@ import java.util.Set; import org.apache.commons.lang3.StringUtils; import net.sourceforge.pmd.lang.dfa.report.ReportTree; +import net.sourceforge.pmd.lang.rule.stat.StatisticalRule; import net.sourceforge.pmd.renderers.AbstractAccumulatingRenderer; import net.sourceforge.pmd.stat.Metric; import net.sourceforge.pmd.util.DateTimeUtil; @@ -340,7 +341,10 @@ public class Report implements Iterable { * * @param metric * the metric to add + * + * @deprecated see {@link StatisticalRule} */ + @Deprecated public void addMetric(Metric metric) { metrics.add(metric); for (ThreadSafeReportListener listener : listeners) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/ThreadSafeReportListener.java b/pmd-core/src/main/java/net/sourceforge/pmd/ThreadSafeReportListener.java index 3fed51da6a..28abb9beb5 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/ThreadSafeReportListener.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/ThreadSafeReportListener.java @@ -27,6 +27,8 @@ public interface ThreadSafeReportListener { * * @param metric * the metric + * @deprecated see {@link net.sourceforge.pmd.lang.rule.stat.StatisticalRule} */ + @Deprecated void metricAdded(Metric metric); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/stat/StatisticalRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/stat/StatisticalRule.java index 73b06e6570..1bb01ec055 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/stat/StatisticalRule.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/stat/StatisticalRule.java @@ -17,12 +17,24 @@ import net.sourceforge.pmd.stat.Metric; * @see DataPoint * @see Metric * @see StatisticalRuleHelper + * @deprecated Statistical rules can be implemented much more easily with plain + * rules, and this framework is confusing and under-documented. All interfaces + * and classes related to this rule will be removed by 7.0.0. See also #483. */ +@Deprecated public interface StatisticalRule extends Rule { + // These property descriptors can't map to the new properties framework and + // should be removed before removing the concrete property classes as part of #1432 + + /** @deprecated Not useful, will not be replaced. */ + @Deprecated DoubleProperty SIGMA_DESCRIPTOR = new DoubleProperty("sigma", "Sigma value", -10000000d, 1000000d, null, 1.0f); + // TODO we should have one such property descriptor pro rule, and *not* share it, to allow setting specific defaults DoubleProperty MINIMUM_DESCRIPTOR = new DoubleProperty("minimum", "Minimum reporting threshold", -10000000d, 1000000000d, null, 2.0f); + /** @deprecated Not useful, will not be replaced. */ + @Deprecated IntegerProperty TOP_SCORE_DESCRIPTOR = new IntegerProperty("topscore", "Top score value", 1, 100, null, 3.0f); void addDataPoint(DataPoint point); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/stat/StatisticalRuleHelper.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/stat/StatisticalRuleHelper.java index 4f89a3565c..867ec3141b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/stat/StatisticalRuleHelper.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/stat/StatisticalRuleHelper.java @@ -22,7 +22,9 @@ import net.sourceforge.pmd.stat.Metric; * Rule implementations should delegate to an instance of this class. * * @author David Dixon-Peugh Aug 8, 2002 StatisticalRule.java + * @deprecated see {@link StatisticalRule} */ +@Deprecated public class StatisticalRuleHelper { public static final double DELTA = 0.000005; // Within this range. . . diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/stat/DataPoint.java b/pmd-core/src/main/java/net/sourceforge/pmd/stat/DataPoint.java index d4ad758f2d..78112e8e30 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/stat/DataPoint.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/stat/DataPoint.java @@ -7,13 +7,17 @@ package net.sourceforge.pmd.stat; import java.util.Random; import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.rule.stat.StatisticalRule; + /** * Datapoint used for rules that deal with metrics. * * @author David Dixon-Peugh * @since Aug 8, 2002 + * @deprecated see {@link StatisticalRule} */ +@Deprecated public class DataPoint implements Comparable { private Node node; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/stat/Metric.java b/pmd-core/src/main/java/net/sourceforge/pmd/stat/Metric.java index 2d3de2aa54..71a1700ec0 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/stat/Metric.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/stat/Metric.java @@ -4,11 +4,16 @@ package net.sourceforge.pmd.stat; +import net.sourceforge.pmd.lang.rule.stat.StatisticalRule; + + /** * This class holds all sorts of statistical information. * * @author David Dixon-Peugh + * @deprecated see {@link StatisticalRule} */ +@Deprecated public class Metric { private String metricName = null; private int count = 0; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/AbstractStatisticalJavaRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/AbstractStatisticalJavaRule.java index d4b65dbd1b..45db7882be 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/AbstractStatisticalJavaRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/AbstractStatisticalJavaRule.java @@ -12,6 +12,11 @@ import net.sourceforge.pmd.lang.rule.stat.StatisticalRule; import net.sourceforge.pmd.lang.rule.stat.StatisticalRuleHelper; import net.sourceforge.pmd.stat.DataPoint; + +/** + * @deprecated see {@link StatisticalRule} + */ +@Deprecated public abstract class AbstractStatisticalJavaRule extends AbstractJavaRule implements StatisticalRule { private final StatisticalRuleHelper helper = new StatisticalRuleHelper(this); diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/AbstractStatisticalPLSQLRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/AbstractStatisticalPLSQLRule.java index 440aaf8463..5469585d1b 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/AbstractStatisticalPLSQLRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/AbstractStatisticalPLSQLRule.java @@ -12,6 +12,11 @@ import net.sourceforge.pmd.lang.rule.stat.StatisticalRule; import net.sourceforge.pmd.lang.rule.stat.StatisticalRuleHelper; import net.sourceforge.pmd.stat.DataPoint; + +/** + * @deprecated see {@link StatisticalRule} + */ +@Deprecated public abstract class AbstractStatisticalPLSQLRule extends AbstractPLSQLRule implements StatisticalRule { private final StatisticalRuleHelper helper = new StatisticalRuleHelper(this); diff --git a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/rule/AbstractStatisticalVmRule.java b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/rule/AbstractStatisticalVmRule.java index dc78c1a85e..959b112fe5 100644 --- a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/rule/AbstractStatisticalVmRule.java +++ b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/rule/AbstractStatisticalVmRule.java @@ -12,6 +12,11 @@ import net.sourceforge.pmd.lang.rule.stat.StatisticalRule; import net.sourceforge.pmd.lang.rule.stat.StatisticalRuleHelper; import net.sourceforge.pmd.stat.DataPoint; + +/** + * @deprecated see {@link StatisticalRule} + */ +@Deprecated public abstract class AbstractStatisticalVmRule extends AbstractVmRule implements StatisticalRule { private final StatisticalRuleHelper helper = new StatisticalRuleHelper(this); From 8d874e39feed4df90c24e8b8b01a3134a6b1cb4e Mon Sep 17 00:00:00 2001 From: Will Herrmann Date: Wed, 2 Jan 2019 15:18:43 -0600 Subject: [PATCH 02/26] Upgrading Google Gson from 2.5 to 2.8.5 --- pmd-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index fb994723a8..3e3c6f51fc 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -140,7 +140,7 @@ com.google.code.gson gson - 2.5 + 2.8.5 From 3120f6a0f4ce763a29bae2837351f5833947c688 Mon Sep 17 00:00:00 2001 From: Will Herrmann Date: Wed, 2 Jan 2019 15:32:37 -0600 Subject: [PATCH 03/26] Upgrading System Rules from 1.8.0 to 1.19.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 83d19a51cf..9a3572f0f5 100644 --- a/pom.xml +++ b/pom.xml @@ -906,7 +906,7 @@ Additionally it includes CPD, the copy-paste-detector. CPD finds duplicated code com.github.stefanbirkner system-rules - 1.8.0 + 1.19.0 org.assertj From be12946bdd42218cee03529e171fcd4ed0a7426a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 9 Jan 2019 21:58:51 +0100 Subject: [PATCH 04/26] Make the XPath version local to the rule builder --- pmd-ui/pom.xml | 2 +- .../fxdesigner/MainDesignerController.java | 18 +++---- .../util/fxdesigner/XPathPanelController.java | 36 +++++++++---- .../model/ObservableXPathRuleBuilder.java | 8 +++ .../popups/EditPropertyDialogController.java | 9 ++-- .../util/fxdesigner/util/DesignerUtil.java | 22 ++++++-- .../pmd/util/fxdesigner/fxml/xpath.fxml | 54 +++++++++++++++---- .../pmd/util/fxdesigner/less/designer.less | 4 +- 8 files changed, 110 insertions(+), 43 deletions(-) diff --git a/pmd-ui/pom.xml b/pmd-ui/pom.xml index 6c097dfd19..bbf0d5102f 100644 --- a/pmd-ui/pom.xml +++ b/pmd-ui/pom.xml @@ -112,7 +112,7 @@ org.fxmisc.richtext richtextfx - 0.9.0 + 0.9.2 org.controlsfx diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java index 2f5f7fcd4b..c21babd58a 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java @@ -123,7 +123,6 @@ public class MainDesignerController implements Initializable, SettingsOwner { private Stack recentFiles = new LimitedSizeStack<>(5); // Properties private Val languageVersion = Val.constant(DesignerUtil.defaultLanguageVersion()); - private Val xpathVersion = Val.constant(DesignerUtil.defaultXPathVersion()); public MainDesignerController(DesignerRoot owner) { @@ -147,13 +146,8 @@ public class MainDesignerController implements Initializable, SettingsOwner { xpathPanelController.initialiseVersionChoiceBox(xpathVersionChoiceBox); languageVersion = Val.wrap(languageChoiceBox.getSelectionModel().selectedItemProperty()); - DesignerUtil.rewire(sourceEditorController.languageVersionProperty(), - languageVersion, this::setLanguageVersion); - - xpathVersion = Val.wrap(xpathVersionChoiceBox.getSelectionModel().selectedItemProperty()); - DesignerUtil.rewire(xpathPanelController.xpathVersionProperty(), - xpathVersion, this::setXpathVersion); - + DesignerUtil.rewireInit(sourceEditorController.languageVersionProperty(), + languageVersion, this::setLanguageVersion); licenseMenuItem.setOnAction(e -> showLicensePopup()); openFileMenuItem.setOnAction(e -> onOpenFileClicked()); @@ -434,19 +428,19 @@ public class MainDesignerController implements Initializable, SettingsOwner { public String getXpathVersion() { - return xpathVersion.getValue(); + return xpathPanelController.getXpathVersion(); } public void setXpathVersion(String version) { - if (xpathVersionChoiceBox.getItems().contains(version)) { - xpathVersionChoiceBox.getSelectionModel().select(version); + if ("1.0".equals(version) || "2.0".equals(version)) { + xpathPanelController.setXpathVersion(version); } } public Val xpathVersionProperty() { - return xpathVersion; + return xpathPanelController.xpathVersionProperty(); } diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java index cadf8dea07..772b0003ea 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java @@ -40,7 +40,6 @@ import net.sourceforge.pmd.util.fxdesigner.popups.ExportXPathWizardController; import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil; import net.sourceforge.pmd.util.fxdesigner.util.TextAwareNodeWrapper; 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.codearea.SyntaxHighlightingCodeArea; import net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.XPathSyntaxHighlighter; import net.sourceforge.pmd.util.fxdesigner.util.controls.ContextMenuWithNoArrows; @@ -64,6 +63,7 @@ import javafx.scene.control.ListView; import javafx.scene.control.MenuItem; import javafx.scene.control.TextArea; import javafx.scene.control.TitledPane; +import javafx.scene.control.ToggleButton; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseButton; @@ -77,7 +77,8 @@ import javafx.stage.StageStyle; /** - * XPath panel controller. + * XPath panel controller. One such controller is a presenter for an {@link ObservableXPathRuleBuilder}, + * which stores all data about one currently edited rule. * * @author Clément Fournier * @see ExportXPathWizardController @@ -90,6 +91,8 @@ public class XPathPanelController implements Initializable, SettingsOwner { private final MainDesignerController parent; private final XPathEvaluator xpathEvaluator = new XPathEvaluator(); private final ObservableXPathRuleBuilder ruleBuilder = new ObservableXPathRuleBuilder(); + public Button exportButton; + public ToggleButton xpath20ToggleButton; @FXML private PropertyTableView propertyTableView; @@ -105,6 +108,9 @@ public class XPathPanelController implements Initializable, SettingsOwner { private ChoiceBox xpathVersionChoiceBox; + private Var myXpathVersion = Var.newSimpleVar(XPathRuleQuery.XPATH_2_0); + + public XPathPanelController(DesignerRoot owner, MainDesignerController mainController) { this.designerRoot = owner; parent = mainController; @@ -119,6 +125,18 @@ public class XPathPanelController implements Initializable, SettingsOwner { initGenerateXPathFromStackTrace(); + Var xpathVersionUIProp = DesignerUtil.booleanVar(xpath20ToggleButton.selectedProperty()) + .mapBidirectional( + is20 -> is20 ? "2.0" : "1.0", + "2.0"::equals + ); + + DesignerUtil.rewireInit(xpathVersionProperty(), xpathVersionUIProp); + + Var xpathExprUIProp = Var.fromVal(xpathExpressionArea.textProperty(), xpathExpressionArea::replaceText); + + DesignerUtil.rewireInit(getRuleBuilder().xpathExpressionProperty(), xpathExprUIProp); + xpathResultListView.setCellFactory(v -> new XpathViolationListCell()); EventStreams.valuesOf(xpathResultListView.getSelectionModel().selectedItemProperty()) @@ -268,8 +286,8 @@ public class XPathPanelController implements Initializable, SettingsOwner { DesignerUtil.rewire(getRuleBuilder().xpathVersionProperty(), parent.xpathVersionProperty()); DesignerUtil.rewire(getRuleBuilder().xpathExpressionProperty(), xpathExpressionProperty()); - DesignerUtil.rewire(getRuleBuilder().rulePropertiesProperty(), - propertyTableView.rulePropertiesProperty(), propertyTableView::setRuleProperties); + DesignerUtil.rewireInit(getRuleBuilder().rulePropertiesProperty(), + propertyTableView.rulePropertiesProperty(), propertyTableView::setRuleProperties); } @@ -356,23 +374,21 @@ public class XPathPanelController implements Initializable, SettingsOwner { } - @PersistentProperty public String getXpathExpression() { - return xpathExpressionArea.getText(); + return getRuleBuilder().getXpathExpression(); } public void setXpathExpression(String expression) { - xpathExpressionArea.replaceText(expression); + getRuleBuilder().setXpathExpression(expression); } - public Val xpathExpressionProperty() { - return Val.wrap(xpathExpressionArea.textProperty()); + public Var xpathExpressionProperty() { + return Var.fromVal(xpathExpressionArea.textProperty(), this::setXpathExpression); } - @PersistentProperty public String getXpathVersion() { return getRuleBuilder().getXpathVersion(); } diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/model/ObservableXPathRuleBuilder.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/model/ObservableXPathRuleBuilder.java index 368bf99926..dc6543c603 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/model/ObservableXPathRuleBuilder.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/model/ObservableXPathRuleBuilder.java @@ -7,6 +7,7 @@ package net.sourceforge.pmd.util.fxdesigner.model; import org.reactfx.value.Var; import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil; +import net.sourceforge.pmd.util.fxdesigner.util.beans.SettingsPersistenceUtil.PersistentProperty; /** @@ -22,6 +23,7 @@ public class ObservableXPathRuleBuilder extends ObservableRuleBuilder { private final Var xpathExpression = Var.newSimpleVar(""); + @PersistentProperty public String getXpathVersion() { return xpathVersion.getValue(); } @@ -32,6 +34,7 @@ public class ObservableXPathRuleBuilder extends ObservableRuleBuilder { } + @PersistentProperty public Var xpathVersionProperty() { return xpathVersion; } @@ -42,6 +45,11 @@ public class ObservableXPathRuleBuilder extends ObservableRuleBuilder { } + public void setXpathExpression(String value) { + xpathExpression.setValue(value); + } + + public Var xpathExpressionProperty() { return xpathExpression; } diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/popups/EditPropertyDialogController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/popups/EditPropertyDialogController.java index ae025478f4..89ea1081f2 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/popups/EditPropertyDialogController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/popups/EditPropertyDialogController.java @@ -6,7 +6,6 @@ package net.sourceforge.pmd.util.fxdesigner.popups; import static net.sourceforge.pmd.properties.MultiValuePropertyDescriptor.DEFAULT_DELIMITER; import static net.sourceforge.pmd.properties.MultiValuePropertyDescriptor.DEFAULT_NUMERIC_DELIMITER; -import static net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil.rewire; import java.net.URL; import java.util.Objects; @@ -127,10 +126,10 @@ public class EditPropertyDialogController implements Initializable { public void bindToDescriptor(PropertyDescriptorSpec spec, ObservableList allDescriptors) { backingDescriptor.setValue(spec); backingDescriptorList.setValue(allDescriptors); - rewire(spec.nameProperty(), this.nameProperty(), this::setName); - rewire(spec.typeIdProperty(), this.typeIdProperty(), this::setTypeId); - rewire(spec.valueProperty(), this.valueProperty(), this::setValue); - rewire(spec.descriptionProperty(), this.descriptionProperty(), this::setDescription); + DesignerUtil.rewireInit(spec.nameProperty(), this.nameProperty(), this::setName); + DesignerUtil.rewireInit(spec.typeIdProperty(), this.typeIdProperty(), this::setTypeId); + DesignerUtil.rewireInit(spec.valueProperty(), this.valueProperty(), this::setValue); + DesignerUtil.rewireInit(spec.descriptionProperty(), this.descriptionProperty(), this::setDescription); } diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/DesignerUtil.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/DesignerUtil.java index 9179e718e6..e28ec1c466 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/DesignerUtil.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/DesignerUtil.java @@ -23,6 +23,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import org.apache.commons.lang3.exception.ExceptionUtils; +import org.reactfx.value.Var; import net.sourceforge.pmd.lang.Language; import net.sourceforge.pmd.lang.LanguageRegistry; @@ -30,6 +31,7 @@ import net.sourceforge.pmd.lang.LanguageVersion; import net.sourceforge.pmd.lang.Parser; import net.sourceforge.pmd.lang.rule.xpath.XPathRuleQuery; +import javafx.beans.property.BooleanProperty; import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; import javafx.scene.control.ListCell; @@ -172,20 +174,27 @@ public final class DesignerUtil { } + /** Like the other overload, using the setter of the ui property. */ + public static void rewireInit(Property underlying, Property ui) { + rewireInit(underlying, ui, ui::setValue); + } + /** - * Binds the underlying property to a source of values. The source property is also initialised using the setter. + * Binds the underlying property to a source of values (UI property). The UI + * property is also initialised using a setter. * * @param underlying The underlying property * @param ui The property exposed to the user (the one in this wizard) * @param setter Setter to initialise the UI value * @param Type of values */ - public static void rewire(Property underlying, ObservableValue ui, Consumer setter) { + public static void rewireInit(Property underlying, ObservableValue ui, Consumer setter) { setter.accept(underlying.getValue()); rewire(underlying, ui); } - - /** Like rewire, with no initialisation. */ + + + /** Like rewireInit, with no initialisation. */ public static void rewire(Property underlying, ObservableValue source) { underlying.unbind(); underlying.bind(source); // Bindings are garbage collected after the popup dies @@ -230,4 +239,9 @@ public final class DesignerUtil { public static Optional stackTraceToXPath(Throwable e) { return stackTraceToXPath(ExceptionUtils.getStackTrace(e)); } + + + public static Var booleanVar(BooleanProperty p) { + return Var.mapBidirectional(p, Boolean::booleanValue, Function.identity()); + } } diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml index b6281032a1..2c07fb0a3f 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml @@ -1,14 +1,25 @@ + + + - + + @@ -30,22 +41,47 @@ - - + + + + + + + + + + + - - + diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less index c490bfbad2..add445fc33 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less @@ -156,8 +156,8 @@ // This is used for buttons that have just an icon and no text .button.icon-button { - -fx-pref-width: 20; - -fx-pref-height: 20; + .fix-width(20); + .fix-height(20); } /* This is the special button to reduce the lower split pane. */ From 9e6481b2757310febd492c55c52b03245a792f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 9 Jan 2019 22:38:17 +0100 Subject: [PATCH 05/26] Introduce AbstractController --- .../util/fxdesigner/EventLogController.java | 9 +- .../fxdesigner/MainDesignerController.java | 13 ++- .../fxdesigner/NodeInfoPanelController.java | 9 +- .../fxdesigner/SourceEditorController.java | 10 +-- .../util/fxdesigner/XPathPanelController.java | 85 ++++++++++--------- .../fxdesigner/util/AbstractController.java | 70 +++++++++++++++ .../util/beans/RestorePropertyVisitor.java | 5 +- .../fxdesigner/util/beans/SettingsOwner.java | 2 +- .../pmd/util/fxdesigner/fxml/xpath.fxml | 2 +- .../pmd/util/fxdesigner/less/designer.less | 2 + 10 files changed, 137 insertions(+), 70 deletions(-) create mode 100644 pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/AbstractController.java diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/EventLogController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/EventLogController.java index 60a0172639..62c1d57e3f 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/EventLogController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/EventLogController.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.util.fxdesigner; -import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.time.Duration; @@ -12,7 +11,6 @@ import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Objects; -import java.util.ResourceBundle; import org.reactfx.EventStream; import org.reactfx.EventStreams; @@ -21,11 +19,11 @@ import org.reactfx.value.Var; import net.sourceforge.pmd.lang.ast.Node; 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.util.DesignerUtil; import javafx.beans.property.SimpleObjectProperty; import javafx.fxml.FXML; -import javafx.fxml.Initializable; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn.SortType; @@ -38,7 +36,7 @@ import javafx.scene.control.cell.PropertyValueFactory; * @author Clément Fournier * @since 6.0.0 */ -public class EventLogController implements Initializable { +public class EventLogController extends AbstractController { /** * Exceptions from XPath evaluation or parsing are never emitted @@ -70,7 +68,8 @@ public class EventLogController implements Initializable { @Override - public void initialize(URL location, ResourceBundle resources) { + protected void beforeParentInit() { + logCategoryColumn.setCellValueFactory(new PropertyValueFactory<>("category")); logMessageColumn.setCellValueFactory(new PropertyValueFactory<>("message")); final DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java index c21babd58a..ffd6971f3f 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java @@ -6,7 +6,6 @@ package net.sourceforge.pmd.util.fxdesigner; import java.io.File; import java.io.IOException; -import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.ArrayList; @@ -14,7 +13,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.ResourceBundle; import java.util.Stack; import java.util.stream.Collectors; @@ -26,6 +24,7 @@ import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.symboltable.NameDeclaration; import net.sourceforge.pmd.lang.symboltable.NameOccurrence; import net.sourceforge.pmd.util.fxdesigner.model.XPathEvaluationException; +import net.sourceforge.pmd.util.fxdesigner.util.AbstractController; import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil; import net.sourceforge.pmd.util.fxdesigner.util.LimitedSizeStack; import net.sourceforge.pmd.util.fxdesigner.util.TextAwareNodeWrapper; @@ -39,7 +38,6 @@ import javafx.animation.Timeline; import javafx.application.Platform; import javafx.beans.property.DoubleProperty; import javafx.fxml.FXML; -import javafx.fxml.Initializable; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.ChoiceBox; @@ -70,7 +68,7 @@ import javafx.util.Duration; * @since 6.0.0 */ @SuppressWarnings("PMD.UnusedPrivateField") -public class MainDesignerController implements Initializable, SettingsOwner { +public class MainDesignerController extends AbstractController { /** * Callback to the owner. @@ -129,9 +127,8 @@ public class MainDesignerController implements Initializable, SettingsOwner { this.designerRoot = owner; } - @Override - public void initialize(URL location, ResourceBundle resources) { + protected void beforeParentInit() { try { SettingsPersistenceUtil.restoreProperties(this, DesignerUtil.getSettingsFile()); } catch (Exception e) { @@ -490,7 +487,7 @@ public class MainDesignerController implements Initializable, SettingsOwner { @Override - public List getChildrenSettingsNodes() { - return Arrays.asList(xpathPanelController, sourceEditorController); + public List getChildren() { + return Arrays.asList(xpathPanelController, sourceEditorController, nodeInfoPanelController, eventLogPanelController); } } diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/NodeInfoPanelController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/NodeInfoPanelController.java index 2acbff2c9a..677231b47e 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/NodeInfoPanelController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/NodeInfoPanelController.java @@ -4,11 +4,9 @@ package net.sourceforge.pmd.util.fxdesigner; -import java.net.URL; import java.util.Collections; import java.util.Iterator; import java.util.Objects; -import java.util.ResourceBundle; import org.reactfx.EventStreams; @@ -18,13 +16,13 @@ import net.sourceforge.pmd.lang.java.ast.TypeNode; import net.sourceforge.pmd.lang.symboltable.NameDeclaration; import net.sourceforge.pmd.util.fxdesigner.model.MetricEvaluator; import net.sourceforge.pmd.util.fxdesigner.model.MetricResult; +import net.sourceforge.pmd.util.fxdesigner.util.AbstractController; import net.sourceforge.pmd.util.fxdesigner.util.controls.ScopeHierarchyTreeCell; import net.sourceforge.pmd.util.fxdesigner.util.controls.ScopeHierarchyTreeItem; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; -import javafx.fxml.Initializable; import javafx.scene.control.Label; import javafx.scene.control.ListView; import javafx.scene.control.Tab; @@ -40,7 +38,7 @@ import javafx.scene.control.TreeView; * @since 6.0.0 */ @SuppressWarnings("PMD.UnusedPrivateField") -public class NodeInfoPanelController implements Initializable { +public class NodeInfoPanelController extends AbstractController { private final MainDesignerController parent; @@ -65,9 +63,8 @@ public class NodeInfoPanelController implements Initializable { parent = mainController; } - @Override - public void initialize(URL location, ResourceBundle resources) { + protected void beforeParentInit() { EventStreams.valuesOf(scopeHierarchyTreeView.getSelectionModel().selectedItemProperty()) .filter(Objects::nonNull) .map(TreeItem::getValue) diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/SourceEditorController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/SourceEditorController.java index 0e7f6b60f2..dabfd22629 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/SourceEditorController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/SourceEditorController.java @@ -11,7 +11,6 @@ import static net.sourceforge.pmd.util.fxdesigner.util.IteratorUtil.toIterable; import java.io.File; import java.io.IOException; -import java.net.URL; import java.time.Duration; import java.util.Arrays; import java.util.Collection; @@ -19,7 +18,6 @@ import java.util.List; import java.util.Locale; import java.util.Objects; import java.util.Optional; -import java.util.ResourceBundle; import java.util.function.BiConsumer; import java.util.function.IntFunction; import java.util.stream.Collectors; @@ -38,8 +36,8 @@ 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.TextAwareNodeWrapper; -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.codearea.AvailableSyntaxHighlighters; import net.sourceforge.pmd.util.fxdesigner.util.codearea.HighlightLayerCodeArea; @@ -51,7 +49,6 @@ import net.sourceforge.pmd.util.fxdesigner.util.controls.TreeViewWrapper; import javafx.application.Platform; import javafx.css.PseudoClass; import javafx.fxml.FXML; -import javafx.fxml.Initializable; import javafx.scene.control.Label; import javafx.scene.control.SelectionModel; import javafx.scene.control.TreeItem; @@ -64,7 +61,7 @@ import javafx.scene.control.TreeView; * @author Clément Fournier * @since 6.0.0 */ -public class SourceEditorController implements Initializable, SettingsOwner { +public class SourceEditorController extends AbstractController { private static final Duration AST_REFRESH_DELAY = Duration.ofMillis(100); @@ -100,8 +97,7 @@ public class SourceEditorController implements Initializable, SettingsOwner { } @Override - public void initialize(URL location, ResourceBundle resources) { - + protected void beforeParentInit() { treeViewWrapper = new TreeViewWrapper<>(astTreeView); astTreeView.setCellFactory(treeView -> new ASTTreeCell(parent)); diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java index 772b0003ea..8637cf5583 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java @@ -6,14 +6,12 @@ package net.sourceforge.pmd.util.fxdesigner; import java.io.IOException; -import java.net.URL; import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; -import java.util.ResourceBundle; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -37,6 +35,7 @@ import net.sourceforge.pmd.util.fxdesigner.model.XPathEvaluationException; import net.sourceforge.pmd.util.fxdesigner.model.XPathEvaluator; import net.sourceforge.pmd.util.fxdesigner.model.XPathSuggestions; import net.sourceforge.pmd.util.fxdesigner.popups.ExportXPathWizardController; +import net.sourceforge.pmd.util.fxdesigner.util.AbstractController; import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil; import net.sourceforge.pmd.util.fxdesigner.util.TextAwareNodeWrapper; import net.sourceforge.pmd.util.fxdesigner.util.beans.SettingsOwner; @@ -51,7 +50,6 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; -import javafx.fxml.Initializable; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.Button; @@ -64,6 +62,7 @@ import javafx.scene.control.MenuItem; import javafx.scene.control.TextArea; import javafx.scene.control.TitledPane; import javafx.scene.control.ToggleButton; +import javafx.scene.control.Tooltip; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseButton; @@ -84,7 +83,7 @@ import javafx.stage.StageStyle; * @see ExportXPathWizardController * @since 6.0.0 */ -public class XPathPanelController implements Initializable, SettingsOwner { +public class XPathPanelController extends AbstractController { private static final Duration XPATH_REFRESH_DELAY = Duration.ofMillis(100); private final DesignerRoot designerRoot; @@ -118,24 +117,20 @@ public class XPathPanelController implements Initializable, SettingsOwner { getRuleBuilder().setClazz(XPathRule.class); } - @Override - public void initialize(URL location, ResourceBundle resources) { + protected void beforeParentInit() { xpathExpressionArea.setSyntaxHighlighter(new XPathSyntaxHighlighter()); initGenerateXPathFromStackTrace(); - Var xpathVersionUIProp = DesignerUtil.booleanVar(xpath20ToggleButton.selectedProperty()) - .mapBidirectional( - is20 -> is20 ? "2.0" : "1.0", - "2.0"::equals - ); + myXpathVersion = DesignerUtil.booleanVar(xpath20ToggleButton.selectedProperty()) + .mapBidirectional( + is20 -> is20 ? "2.0" : "1.0", + "2.0"::equals + ); - DesignerUtil.rewireInit(xpathVersionProperty(), xpathVersionUIProp); - - Var xpathExprUIProp = Var.fromVal(xpathExpressionArea.textProperty(), xpathExpressionArea::replaceText); - - DesignerUtil.rewireInit(getRuleBuilder().xpathExpressionProperty(), xpathExprUIProp); + Val tooltipVar = xpathVersionProperty().map(v -> "Using XPath " + v).map(Tooltip::new); + xpath20ToggleButton.tooltipProperty().bind(tooltipVar); xpathResultListView.setCellFactory(v -> new XpathViolationListCell()); @@ -145,8 +140,6 @@ public class XPathPanelController implements Initializable, SettingsOwner { .map(TextAwareNodeWrapper::getNode) .subscribe(parent::onNodeItemSelected); - Platform.runLater(this::bindToParent); - xpathExpressionArea.richChanges() .filter(t -> !t.isIdentity()) .successionEnds(XPATH_REFRESH_DELAY) @@ -157,6 +150,16 @@ public class XPathPanelController implements Initializable, SettingsOwner { initialiseAutoCompletion(); } + + @Override + protected void afterParentInit() { + + DesignerUtil.rewireInit(getRuleBuilder().xpathVersionProperty(), xpathVersionProperty()); + DesignerUtil.rewireInit(getRuleBuilder().xpathExpressionProperty(), xpathExpressionProperty()); + bindToParent(); + } + + private void initialiseAutoCompletion() { EventStream changesEventStream = xpathExpressionArea.plainTextChanges() @@ -224,17 +227,6 @@ public class XPathPanelController implements Initializable, SettingsOwner { } - private static TextFlow highlightXPathSuggestion(String text, String match) { - int filterIndex = text.toLowerCase(Locale.ROOT).indexOf(match.toLowerCase(Locale.ROOT)); - - Text textBefore = new Text(text.substring(0, filterIndex)); - Text textAfter = new Text(text.substring(filterIndex + match.length())); - Text textFilter = new Text(text.substring(filterIndex, filterIndex + match.length())); //instead of "filter" to keep all "case sensitive" - textFilter.setFill(Color.ORANGE); - return new TextFlow(textBefore, textFilter, textAfter); - } - - private void initGenerateXPathFromStackTrace() { ContextMenu menu = new ContextMenu(); @@ -283,7 +275,7 @@ public class XPathPanelController implements Initializable, SettingsOwner { DesignerUtil.rewire(getRuleBuilder().languageProperty(), Val.map(parent.languageVersionProperty(), LanguageVersion::getLanguage)); - DesignerUtil.rewire(getRuleBuilder().xpathVersionProperty(), parent.xpathVersionProperty()); + DesignerUtil.rewire(getRuleBuilder().xpathVersionProperty(), xpathVersionProperty()); DesignerUtil.rewire(getRuleBuilder().xpathExpressionProperty(), xpathExpressionProperty()); DesignerUtil.rewireInit(getRuleBuilder().rulePropertiesProperty(), @@ -323,11 +315,11 @@ public class XPathPanelController implements Initializable, SettingsOwner { } ObservableList results - = FXCollections.observableArrayList(xpathEvaluator.evaluateQuery(compilationUnit, - version, - getXpathVersion(), - xpath, - ruleBuilder.getRuleProperties())); + = FXCollections.observableArrayList(xpathEvaluator.evaluateQuery(compilationUnit, + version, + getXpathVersion(), + xpath, + ruleBuilder.getRuleProperties())); xpathResultListView.setItems(results.stream().map(parent::wrapNode).collect(Collectors.toCollection(LiveArrayList::new))); parent.highlightXPathResults(results); violationsTitledPane.setText("Matched nodes\t(" + results.size() + ")"); @@ -356,7 +348,7 @@ public class XPathPanelController implements Initializable, SettingsOwner { public void showExportXPathToRuleWizard() throws IOException { ExportXPathWizardController wizard - = new ExportXPathWizardController(xpathExpressionProperty()); + = new ExportXPathWizardController(xpathExpressionProperty()); FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/xpath-export-wizard.fxml")); loader.setController(wizard); @@ -375,12 +367,12 @@ public class XPathPanelController implements Initializable, SettingsOwner { public String getXpathExpression() { - return getRuleBuilder().getXpathExpression(); + return xpathExpressionArea.getText(); } public void setXpathExpression(String expression) { - getRuleBuilder().setXpathExpression(expression); + xpathExpressionArea.replaceText(expression); } @@ -390,17 +382,17 @@ public class XPathPanelController implements Initializable, SettingsOwner { public String getXpathVersion() { - return getRuleBuilder().getXpathVersion(); + return xpathVersionProperty().getValue(); } public void setXpathVersion(String xpathVersion) { - getRuleBuilder().setXpathVersion(xpathVersion); + xpathVersionProperty().setValue(xpathVersion); } public Var xpathVersionProperty() { - return getRuleBuilder().xpathVersionProperty(); + return myXpathVersion; } @@ -413,4 +405,15 @@ public class XPathPanelController implements Initializable, SettingsOwner { public List getChildrenSettingsNodes() { return Collections.singletonList(getRuleBuilder()); } + + + private static TextFlow highlightXPathSuggestion(String text, String match) { + int filterIndex = text.toLowerCase(Locale.ROOT).indexOf(match.toLowerCase(Locale.ROOT)); + + Text textBefore = new Text(text.substring(0, filterIndex)); + Text textAfter = new Text(text.substring(filterIndex + match.length())); + Text textFilter = new Text(text.substring(filterIndex, filterIndex + match.length())); //instead of "filter" to keep all "case sensitive" + textFilter.setFill(Color.ORANGE); + return new TextFlow(textBefore, textFilter, textAfter); + } } diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/AbstractController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/AbstractController.java new file mode 100644 index 0000000000..d93de1913b --- /dev/null +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/AbstractController.java @@ -0,0 +1,70 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.util.fxdesigner.util; + +import java.net.URL; +import java.util.Collections; +import java.util.List; +import java.util.ResourceBundle; + +import net.sourceforge.pmd.util.fxdesigner.util.beans.SettingsOwner; + +import javafx.application.Platform; +import javafx.fxml.Initializable; + + +/** + * Make the initialization cycle of JavaFX clearer. Children controller + * are initialized before their parent, but sometimes it 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. + * + * @author Clément Fournier + * @since 7.0.0 + */ +public class AbstractController implements Initializable, SettingsOwner { + + @Override + public final void initialize(URL url, ResourceBundle resourceBundle) { + beforeParentInit(); + for (AbstractController child : getChildren()) { + Platform.runLater(child::afterParentInit); + } + } + + + /** + * Executed before the parent's initialization. + * Always executed once. + */ + protected void beforeParentInit() { + + } + + + /** + * Executed after the parent's initialization. This also means, + * after persistent settings restoration. If this node has no + * parent, then this is never executed. + */ + protected void afterParentInit() { + + } + + + @Override + public List getChildrenSettingsNodes() { + return getChildren(); + } + + + protected List getChildren() { + return Collections.emptyList(); + } +} diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/beans/RestorePropertyVisitor.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/beans/RestorePropertyVisitor.java index 19a00dff74..7550852472 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/beans/RestorePropertyVisitor.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/beans/RestorePropertyVisitor.java @@ -65,7 +65,10 @@ public class RestorePropertyVisitor extends BeanNodeVisitor { } for (SettingsOwner child : target.getChildrenSettingsNodes()) { - model.getChildrenByType().get(child.getClass()).accept(this, child); + BeanModelNode childModel = model.getChildrenByType().get(child.getClass()); + if (childModel != null) { + childModel.accept(this, child); + } } } diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/beans/SettingsOwner.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/beans/SettingsOwner.java index 2eb05b141e..c87e20ca5a 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/beans/SettingsOwner.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/beans/SettingsOwner.java @@ -21,7 +21,7 @@ public interface SettingsOwner { /** Gets the children of this node in order. */ - default List getChildrenSettingsNodes() { + default List getChildrenSettingsNodes() { return Collections.emptyList(); } diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml index 2c07fb0a3f..0d72a6f247 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml @@ -49,7 +49,7 @@ AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="0.0"> - + - - - - - + diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/constants.less b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/constants.less index 21353aced4..2de2da41c8 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/constants.less +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/constants.less @@ -57,6 +57,11 @@ -fx-max-height: @height; } +.force-square(@side) { + .fix-width(@side); + .fix-height(@side); +} + // Mixin to iterate over the range [0, @i] // * The selector in which the mixin is called is appended with a class depth-x, // where x is the index of the color in the stack diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less index e986b6366d..c31fc57f12 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less @@ -127,6 +127,57 @@ } +.titled-pane.tool-bar-title > .title > .tool-bar { + -fx-background-color: transparent; + + & > .container { + + .fix-height(12); + + -fx-background-insets: 0; + -fx-border-insets: 0; + -fx-border-image-insets: 0; + + -fx-padding: 0 0 -12 0; + + & > .label { + -fx-background-color: transparent; + -fx-font-size: 9pt; + } + + .menu-bar { + -fx-background-color: transparent; + } + } +} + + +.menu-button.menu-button-no-arrow { + .arrow-button { + -fx-padding: 0; + } + + .arrow-button > .arrow { + -fx-padding: 0; + } +} + +.menu-button.icon-menu-button { + -fx-background-color: transparent; + -fx-border-width: 0; + -fx-border-insets: 0; + -fx-padding: 0; + + &:showing, &:hover { + -fx-background-color: @selection-focus-color; + } + + .label { + -fx-background-color: transparent; + //-fx-padding: 0; + } +} + #main-horizontal-split-pane > .split-pane-divider { -fx-background-color: @darker-accent-focus; } From dec18daf734eabb3780be29c231b70153585c2aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 10 Jan 2019 04:56:27 +0100 Subject: [PATCH 08/26] Add menu items and wire it in --- .../util/fxdesigner/XPathPanelController.java | 55 +++++++------------ .../pmd/util/fxdesigner/fxml/xpath.fxml | 15 ++++- 2 files changed, 32 insertions(+), 38 deletions(-) diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java index 13465a3e4c..d1bfac394d 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java @@ -9,15 +9,16 @@ import java.io.IOException; import java.time.Duration; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.controlsfx.validation.ValidationSupport; import org.controlsfx.validation.Validator; -import org.kordamp.ikonli.javafx.FontIcon; import org.reactfx.EventStream; import org.reactfx.EventStreams; import org.reactfx.collection.LiveArrayList; @@ -50,28 +51,22 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; -import javafx.geometry.Insets; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.Button; -import javafx.scene.control.ChoiceBox; import javafx.scene.control.ContextMenu; import javafx.scene.control.CustomMenuItem; import javafx.scene.control.Label; import javafx.scene.control.ListView; -import javafx.scene.control.Menu; -import javafx.scene.control.MenuBar; import javafx.scene.control.MenuItem; import javafx.scene.control.TextArea; import javafx.scene.control.TitledPane; -import javafx.scene.control.ToggleButton; -import javafx.scene.control.ToolBar; -import javafx.scene.control.Tooltip; +import javafx.scene.control.Toggle; +import javafx.scene.control.ToggleGroup; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; -import javafx.scene.layout.HBox; import javafx.scene.paint.Color; import javafx.scene.text.Text; import javafx.scene.text.TextFlow; @@ -107,13 +102,11 @@ public class XPathPanelController extends AbstractController { private TitledPane violationsTitledPane; @FXML private ListView xpathResultListView; + @FXML + ToggleGroup xpathVersionToggleGroup; - // Actually a child of the main view toolbar, but this controller is responsible for it - @SuppressWarnings("PMD.SingularField") - private ChoiceBox xpathVersionChoiceBox; - - - private Var myXpathVersion = Var.newSimpleVar(XPathRuleQuery.XPATH_2_0); + // ui property + private Var xpathVersionUIProperty = Var.newSimpleVar(XPathRuleQuery.XPATH_2_0); public XPathPanelController(DesignerRoot owner, MainDesignerController mainController) { @@ -129,14 +122,17 @@ public class XPathPanelController extends AbstractController { initGenerateXPathFromStackTrace(); -// myXpathVersion = DesignerUtil.booleanVar(xpath20ToggleButton.selectedProperty()) -// .mapBidirectional( -// is20 -> is20 ? "2.0" : "1.0", -// "2.0"::equals -// ); + Map stringToButton = new HashMap<>(); - Val tooltipVar = xpathVersionProperty().map(v -> "Using XPath " + v).map(Tooltip::new); -// xpath20ToggleButton.tooltipProperty().bind(tooltipVar); + xpathVersionUIProperty = Var.fromVal(xpathVersionToggleGroup.selectedToggleProperty(), xpathVersionToggleGroup::selectToggle) + .mapBidirectional( + toggle -> toggle.getUserData().toString(), + str -> xpathVersionToggleGroup.getToggles() + .stream() + .filter(t -> t.getUserData().equals(str)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Unknown XPath version")) + ); xpathResultListView.setCellFactory(v -> new XpathViolationListCell()); @@ -290,19 +286,6 @@ public class XPathPanelController extends AbstractController { } - public void initialiseVersionChoiceBox(ChoiceBox choiceBox) { - this.xpathVersionChoiceBox = choiceBox; - - ObservableList versionItems = choiceBox.getItems(); - versionItems.add(XPathRuleQuery.XPATH_1_0); - versionItems.add(XPathRuleQuery.XPATH_1_0_COMPATIBILITY); - versionItems.add(XPathRuleQuery.XPATH_2_0); - - xpathVersionChoiceBox.getSelectionModel().select(XPathRuleQuery.XPATH_2_0); - choiceBox.setConverter(DesignerUtil.stringConverter(s -> "XPath " + s, s -> s.substring(6))); - } - - /** * Evaluate the contents of the XPath expression area * on the given compilation unit. This updates the xpath @@ -399,7 +382,7 @@ public class XPathPanelController extends AbstractController { public Var xpathVersionProperty() { - return myXpathVersion; + return xpathVersionUIProperty; } diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml index 330d313af1..8aab3bcce5 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml @@ -8,9 +8,10 @@ - + + - + + + + + From 5601a78b4c4edb5fed43f5505489668f46cd48e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 10 Jan 2019 18:30:05 +0100 Subject: [PATCH 09/26] Also remove the language version choicebox --- .../fxdesigner/MainDesignerController.java | 35 ++-------- .../fxdesigner/SourceEditorController.java | 56 +++++++++++++-- .../util/fxdesigner/util/DesignerUtil.java | 19 +++++ .../pmd/util/fxdesigner/fxml/designer.fxml | 26 ++----- .../pmd/util/fxdesigner/fxml/editor.fxml | 70 ++++++++++++++----- .../pmd/util/fxdesigner/less/designer.less | 3 +- 6 files changed, 135 insertions(+), 74 deletions(-) diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java index fda622b779..0e625fb2c7 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java @@ -39,7 +39,6 @@ import javafx.beans.property.DoubleProperty; import javafx.fxml.FXML; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.ChoiceBox; import javafx.scene.control.CustomMenuItem; import javafx.scene.control.Label; import javafx.scene.control.Menu; @@ -92,8 +91,6 @@ public class MainDesignerController extends AbstractController { private Menu fileMenu; /* Center toolbar */ @FXML - private ChoiceBox languageChoiceBox; - @FXML private ToggleButton bottomTabsToggle; /* Bottom panel */ @FXML @@ -116,8 +113,6 @@ public class MainDesignerController extends AbstractController { // Other fields private Stack recentFiles = new LimitedSizeStack<>(5); - // Properties - private Val languageVersion = Val.constant(DesignerUtil.defaultLanguageVersion()); public MainDesignerController(DesignerRoot owner) { @@ -134,13 +129,8 @@ public class MainDesignerController extends AbstractController { e.printStackTrace(); } - initializeLanguageVersionMenu(); initializeViewAnimation(); - languageVersion = Val.wrap(languageChoiceBox.getSelectionModel().selectedItemProperty()); - DesignerUtil.rewireInit(sourceEditorController.languageVersionProperty(), - languageVersion, this::setLanguageVersion); - licenseMenuItem.setOnAction(e -> showLicensePopup()); openFileMenuItem.setOnAction(e -> onOpenFileClicked()); openRecentMenu.setOnAction(e -> updateRecentFilesMenu()); @@ -160,24 +150,9 @@ public class MainDesignerController extends AbstractController { Platform.runLater(this::refreshAST); // initial refreshing Platform.runLater(() -> sourceEditorController.moveCaret(0, 0)); - Platform.runLater(() -> { // fixes choicebox bad rendering on first opening - languageChoiceBox.show(); - languageChoiceBox.hide(); - }); } - private void initializeLanguageVersionMenu() { - List supported = DesignerUtil.getSupportedLanguageVersions(); - supported.sort(LanguageVersion::compareTo); - languageChoiceBox.getItems().addAll(supported); - - languageChoiceBox.setConverter(DesignerUtil.languageVersionStringConverter()); - - languageChoiceBox.getSelectionModel().select(DesignerUtil.defaultLanguageVersion()); - languageChoiceBox.show(); - } - private void initializeViewAnimation() { @@ -346,7 +321,7 @@ public class MainDesignerController extends AbstractController { sourceEditorController.setText(source); LanguageVersion guess = DesignerUtil.getLanguageVersionFromExtension(file.getName()); if (guess != null) { // guess the language from the extension - languageChoiceBox.getSelectionModel().select(guess); + sourceEditorController.setLanguageVersion(guess); refreshAST(); } @@ -403,19 +378,17 @@ public class MainDesignerController extends AbstractController { public LanguageVersion getLanguageVersion() { - return languageVersion.getValue(); + return sourceEditorController.getLanguageVersion(); } public void setLanguageVersion(LanguageVersion version) { - if (languageChoiceBox.getItems().contains(version)) { - languageChoiceBox.getSelectionModel().select(version); - } + sourceEditorController.setLanguageVersion(version); } public Val languageVersionProperty() { - return languageVersion; + return sourceEditorController.languageVersionProperty(); } diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/SourceEditorController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/SourceEditorController.java index 7f8505e442..8b76d9f921 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/SourceEditorController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/SourceEditorController.java @@ -37,6 +37,7 @@ 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.DesignerUtil; 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; @@ -50,7 +51,10 @@ import javafx.application.Platform; import javafx.css.PseudoClass; import javafx.fxml.FXML; import javafx.scene.control.Label; +import javafx.scene.control.MenuButton; +import javafx.scene.control.RadioMenuItem; import javafx.scene.control.SelectionModel; +import javafx.scene.control.ToggleGroup; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeView; @@ -65,6 +69,10 @@ public class SourceEditorController extends AbstractController { private static final Duration AST_REFRESH_DELAY = Duration.ofMillis(100); + @FXML + private MenuButton languageSelectionMenuButton; + @FXML + private Label sourceCodeTitleLabel; @FXML private Label astTitleLabel; @FXML @@ -90,6 +98,9 @@ public class SourceEditorController extends AbstractController { } }); + private Var languageVersionUIProperty; + + public SourceEditorController(DesignerRoot owner, MainDesignerController mainController) { parent = mainController; astManager = new ASTManager(owner); @@ -101,11 +112,19 @@ public class SourceEditorController extends AbstractController { treeViewWrapper = new TreeViewWrapper<>(astTreeView); astTreeView.setCellFactory(treeView -> new ASTTreeCell(parent)); + initializeLanguageSelector(); // languageVersionProperty() must be initialized + languageVersionProperty().values() .filterMap(Objects::nonNull, LanguageVersion::getLanguage) .distinct() .subscribe(this::updateSyntaxHighlighter); + languageVersionProperty().values() + .filter(Objects::nonNull) + .map(LanguageVersion::getShortName) + .map(lang -> "Source Code (" + lang + ")") + .subscribe(sourceCodeTitleLabel::setText); + EventStreams.valuesOf(astTreeView.getSelectionModel().selectedItemProperty()) .filterMap(Objects::nonNull, TreeItem::getValue) .subscribe(parent::onNodeItemSelected); @@ -126,6 +145,33 @@ public class SourceEditorController extends AbstractController { } + private void initializeLanguageSelector() { + + ToggleGroup languageToggleGroup = new ToggleGroup(); + + DesignerUtil.getSupportedLanguageVersions() + .stream() + .sorted(LanguageVersion::compareTo) + .map(lv -> { + RadioMenuItem item = new RadioMenuItem(lv.getShortName()); + item.setUserData(lv); + return item; + }) + .forEach(item -> { + languageToggleGroup.getToggles().add(item); + languageSelectionMenuButton.getItems().add(item); + }); + + languageVersionUIProperty = DesignerUtil.mapToggleGroupToUserData(languageToggleGroup); + } + + + @Override + protected void afterParentInit() { + DesignerUtil.rewire(astManager.languageVersionProperty(), languageVersionUIProperty); + } + + private IntFunction lineNumberFactory() { IntFunction base = LineNumberFactory.get(codeEditorArea); Val activePar = Val.wrap(codeEditorArea.currentParagraphProperty()); @@ -337,20 +383,19 @@ public class SourceEditorController extends AbstractController { @PersistentProperty public LanguageVersion getLanguageVersion() { - return astManager.getLanguageVersion(); + return languageVersionUIProperty.getValue(); } public void setLanguageVersion(LanguageVersion version) { - astManager.setLanguageVersion(version); + languageVersionUIProperty.setValue(version); } public Var languageVersionProperty() { - return astManager.languageVersionProperty(); + return languageVersionUIProperty; } - /** * Returns the most up-to-date compilation unit, or empty if it can't be parsed. */ @@ -388,7 +433,7 @@ public class SourceEditorController extends AbstractController { /** Style layers for the code area. */ - public enum StyleLayerIds implements LayerId { + private enum StyleLayerIds implements LayerId { // caution, the name of the constants are used as style classes /** For the currently selected node. */ @@ -414,5 +459,4 @@ public class SourceEditorController extends AbstractController { return styleClass; } } - } diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/DesignerUtil.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/DesignerUtil.java index e28ec1c466..6f25015009 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/DesignerUtil.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/DesignerUtil.java @@ -36,6 +36,7 @@ import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; import javafx.scene.control.ListCell; import javafx.scene.control.ListView; +import javafx.scene.control.ToggleGroup; import javafx.scene.control.Tooltip; import javafx.util.Callback; import javafx.util.StringConverter; @@ -128,6 +129,24 @@ public final class DesignerUtil { } + /** + * Given a toggle group whose toggles all have user data of type T, + * maps the selected toggle property to a Var<T> + */ + @SuppressWarnings("unchecked") + public static Var mapToggleGroupToUserData(ToggleGroup toggleGroup) { + return Var.fromVal(toggleGroup.selectedToggleProperty(), toggleGroup::selectToggle) + .mapBidirectional( + item -> (T) item.getUserData(), + t -> toggleGroup.getToggles() + .stream() + .filter(toggle -> toggle.getUserData().equals(t)) + .findFirst() + .orElseThrow(() -> new IllegalStateException("Unknown toggle " + t)) + ); + } + + public static StringConverter languageVersionStringConverter() { return DesignerUtil.stringConverter(LanguageVersion::getShortName, s -> LanguageRegistry.findLanguageVersionByTerseName(s.toLowerCase(Locale.ROOT))); diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/designer.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/designer.fxml index 4f969cd3ee..746e92e25e 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/designer.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/designer.fxml @@ -18,16 +18,14 @@ - + + - + @@ -41,16 +39,15 @@ - + - - + + @@ -74,17 +71,6 @@ - - - - diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml index 3981a382ea..360f210d56 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml @@ -2,42 +2,80 @@ + + + - + - + - -
- + + + + + + + + + + + + + + + + + + + -
- - - - - - -
+ + +
- +
diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less index c31fc57f12..a003f99125 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less @@ -127,6 +127,7 @@ } +// Titled panes that have a toolbar in their header region .titled-pane.tool-bar-title > .title > .tool-bar { -fx-background-color: transparent; @@ -138,7 +139,7 @@ -fx-border-insets: 0; -fx-border-image-insets: 0; - -fx-padding: 0 0 -12 0; + -fx-padding: 0 0 -10 0; & > .label { -fx-background-color: transparent; From 265d9aea68d093d6dd83e7f664524356246e68fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 10 Jan 2019 18:55:36 +0100 Subject: [PATCH 10/26] Fix height --- .../pmd/util/fxdesigner/fxml/editor.fxml | 2 +- .../pmd/util/fxdesigner/less/constants.less | 3 +++ .../pmd/util/fxdesigner/less/designer.less | 20 +++++++++++++++++-- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml index 360f210d56..f77b33f417 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml @@ -27,7 +27,7 @@ .title { + .fix-height(30); + } + + &.tool-bar-title > .title > .tool-bar > .container { + -fx-padding: 0 0 -4 0; + + & > .label { + -fx-font-size: @smaller-font-size; // TODO + -fx-padding: 0 0 1 0; + } + } } // Titled panes that have a toolbar in their header region @@ -143,7 +158,7 @@ & > .label { -fx-background-color: transparent; - -fx-font-size: 9pt; + -fx-font-size: @smaller-font-size; } .menu-bar { @@ -307,3 +322,4 @@ .corner { -fx-background-color: white; } + From 3988941cc3408ab5bf980bd62262936ebe740918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 10 Jan 2019 19:45:37 +0100 Subject: [PATCH 11/26] Add ToolbarTitledPane --- .../fxdesigner/SourceEditorController.java | 5 +- .../util/controls/ToolbarTitledPane.java | 97 +++++++++++++++++++ .../pmd/util/fxdesigner/fxml/editor.fxml | 38 +++----- .../pmd/util/fxdesigner/fxml/xpath.fxml | 72 ++++++-------- .../pmd/util/fxdesigner/less/designer.less | 56 +++++------ 5 files changed, 169 insertions(+), 99 deletions(-) create mode 100644 pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/controls/ToolbarTitledPane.java diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/SourceEditorController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/SourceEditorController.java index 8b76d9f921..dcd244e569 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/SourceEditorController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/SourceEditorController.java @@ -45,6 +45,7 @@ import net.sourceforge.pmd.util.fxdesigner.util.codearea.HighlightLayerCodeArea; import net.sourceforge.pmd.util.fxdesigner.util.codearea.HighlightLayerCodeArea.LayerId; import net.sourceforge.pmd.util.fxdesigner.util.controls.ASTTreeCell; import net.sourceforge.pmd.util.fxdesigner.util.controls.ASTTreeItem; +import net.sourceforge.pmd.util.fxdesigner.util.controls.ToolbarTitledPane; import net.sourceforge.pmd.util.fxdesigner.util.controls.TreeViewWrapper; import javafx.application.Platform; @@ -69,6 +70,8 @@ public class SourceEditorController extends AbstractController { private static final Duration AST_REFRESH_DELAY = Duration.ofMillis(100); + @FXML + private ToolbarTitledPane editorTitledPane; @FXML private MenuButton languageSelectionMenuButton; @FXML @@ -123,7 +126,7 @@ public class SourceEditorController extends AbstractController { .filter(Objects::nonNull) .map(LanguageVersion::getShortName) .map(lang -> "Source Code (" + lang + ")") - .subscribe(sourceCodeTitleLabel::setText); + .subscribe(editorTitledPane::setTitle); EventStreams.valuesOf(astTreeView.getSelectionModel().selectedItemProperty()) .filterMap(Objects::nonNull, TreeItem::getValue) diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/controls/ToolbarTitledPane.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/controls/ToolbarTitledPane.java new file mode 100644 index 0000000000..f928ccf2e6 --- /dev/null +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/controls/ToolbarTitledPane.java @@ -0,0 +1,97 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.util.fxdesigner.util.controls; + +import java.util.Collection; +import java.util.Objects; + +import org.reactfx.value.Val; +import org.reactfx.value.Var; + +import javafx.collections.ObservableList; +import javafx.geometry.Insets; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.control.TitledPane; +import javafx.scene.control.ToolBar; +import javafx.scene.layout.StackPane; + + +/** + * A Titled pane that has a toolbar in its header region. + * Supported by some CSS in designer.less. + * + * @author Clément Fournier + * @since 7.0.0 + */ +public final class ToolbarTitledPane extends TitledPane { + + + private ToolBar toolBar = new ToolBar(); + private Var title = Var.newSimpleVar("Title"); + + + public ToolbarTitledPane() { + + getStyleClass().add("tool-bar-title"); + + toolBar.setPadding(Insets.EMPTY); + + Label titleLabel = new Label("Title"); + titleLabel.textProperty().bind(title); + + toolBar.getItems().add(titleLabel); + + setGraphic(toolBar); + + // should be an empty string, binding prevents to set it + textProperty().bind(Val.constant("")); + + // The toolbar is too large for the title region and is not + // centered unless we bind the height, like follows + + Val.wrap(toolBar.parentProperty()) + .values() + .filter(Objects::nonNull) + .subscribe(parent -> { + // The title region is provided by the skin, + // this is the only way to access it outside of css + StackPane titleRegion = (StackPane) parent; + toolBar.maxHeightProperty().unbind(); + toolBar.maxHeightProperty().bind(titleRegion.heightProperty()); + toolBar.minHeightProperty().unbind(); + toolBar.minHeightProperty().bind(titleRegion.heightProperty()); + toolBar.prefHeightProperty().unbind(); + toolBar.prefHeightProperty().bind(titleRegion.heightProperty()); + }); + + } + + + public ObservableList getToolbarItems() { + return toolBar.getItems(); + } + + + public void setToolbarItems(Collection nodes) { + toolBar.getItems().setAll(nodes); + } + + + public String getTitle() { + return title.getValue(); + } + + + public void setTitle(String title) { + this.title.setValue(title); + } + + + /** Title of the pane, not equivalent to {@link #textProperty()}. */ + public Var titleProperty() { + return title; + } +} diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml index f77b33f417..28f21eb6c3 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml @@ -4,11 +4,11 @@ + - @@ -25,24 +25,16 @@ - - - - + + @@ -52,11 +44,7 @@ - - - - - + - +
diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml index 8aab3bcce5..8c4735cd8d 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml @@ -14,6 +14,7 @@ + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - + diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less index b55a3e794b..e0ff160019 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less @@ -132,42 +132,38 @@ .fix-height(30); } - &.tool-bar-title > .title > .tool-bar > .container { - -fx-padding: 0 0 -4 0; - - & > .label { - -fx-font-size: @smaller-font-size; // TODO - -fx-padding: 0 0 1 0; - } - } -} - -// Titled panes that have a toolbar in their header region -.titled-pane.tool-bar-title > .title > .tool-bar { - -fx-background-color: transparent; - - & > .container { - - .fix-height(12); - - -fx-background-insets: 0; - -fx-border-insets: 0; - -fx-border-image-insets: 0; - - -fx-padding: 0 0 -10 0; - - & > .label { - -fx-background-color: transparent; + &.tool-bar-title > .title > .tool-bar > .container > .label { + // TODO we can make that bigger when all titled panes rely on ToolbarTitledPane -fx-font-size: @smaller-font-size; } +} - .menu-bar { - -fx-background-color: transparent; +// Supports the ToolbarTitledPane +.titled-pane.tool-bar-title > .title { + + -fx-padding: 0 6 0 6; + + & > .tool-bar { + -fx-background-color: transparent; + + & > .container { + + -fx-background-insets: 0; + -fx-border-insets: 0; + -fx-border-image-insets: 0; + + & > .label { + -fx-background-color: transparent; + -fx-font-size: @smaller-font-size; + } + + .menu-bar { + -fx-background-color: transparent; + } } } } - .menu-button.menu-button-no-arrow { .arrow-button { -fx-padding: 0; @@ -204,7 +200,6 @@ -fx-background-color: @app-darker-slate-color; } - .tool-bar { .fix-height(30); -fx-border-color: transparent; @@ -244,7 +239,6 @@ } } - .tab { -fx-background-insets: 0.0; -fx-background-radius: 0.0; From 75d8081876929af2115634b9de4cc36d3cb5f316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 10 Jan 2019 19:48:52 +0100 Subject: [PATCH 12/26] Cleanup --- .../util/fxdesigner/MainDesignerController.java | 17 ----------------- .../util/fxdesigner/XPathPanelController.java | 15 +++++---------- .../pmd/util/fxdesigner/fxml/xpath.fxml | 2 +- 3 files changed, 6 insertions(+), 28 deletions(-) diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java index 0e625fb2c7..823f93a3ba 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java @@ -392,23 +392,6 @@ public class MainDesignerController extends AbstractController { } - public String getXpathVersion() { - return xpathPanelController.getXpathVersion(); - } - - - public void setXpathVersion(String version) { - if ("1.0".equals(version) || "2.0".equals(version)) { - xpathPanelController.setXpathVersion(version); - } - } - - - public Val xpathVersionProperty() { - return xpathPanelController.xpathVersionProperty(); - } - - @PersistentProperty public String getRecentFiles() { return recentFiles.stream().map(File::getAbsolutePath).collect(Collectors.joining(File.pathSeparator)); diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java index d1bfac394d..34f7524ed8 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java @@ -45,6 +45,7 @@ import net.sourceforge.pmd.util.fxdesigner.util.codearea.SyntaxHighlightingCodeA import net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.XPathSyntaxHighlighter; import net.sourceforge.pmd.util.fxdesigner.util.controls.ContextMenuWithNoArrows; import net.sourceforge.pmd.util.fxdesigner.util.controls.PropertyTableView; +import net.sourceforge.pmd.util.fxdesigner.util.controls.ToolbarTitledPane; import net.sourceforge.pmd.util.fxdesigner.util.controls.XpathViolationListCell; import javafx.collections.FXCollections; @@ -93,7 +94,7 @@ public class XPathPanelController extends AbstractController { @FXML - public TitledPane centerTitledPane; + public ToolbarTitledPane expressionTitledPane; @FXML private PropertyTableView propertyTableView; @FXML @@ -124,15 +125,9 @@ public class XPathPanelController extends AbstractController { Map stringToButton = new HashMap<>(); - xpathVersionUIProperty = Var.fromVal(xpathVersionToggleGroup.selectedToggleProperty(), xpathVersionToggleGroup::selectToggle) - .mapBidirectional( - toggle -> toggle.getUserData().toString(), - str -> xpathVersionToggleGroup.getToggles() - .stream() - .filter(t -> t.getUserData().equals(str)) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("Unknown XPath version")) - ); + xpathVersionUIProperty = DesignerUtil.mapToggleGroupToUserData(xpathVersionToggleGroup); + + expressionTitledPane.titleProperty().bind(xpathVersionUIProperty.map(v -> "XPath Expression (XPath " + v + ")")); xpathResultListView.setCellFactory(v -> new XpathViolationListCell()); diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml index 8c4735cd8d..fd203e2298 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml @@ -57,7 +57,7 @@ - Date: Thu, 10 Jan 2019 21:04:52 +0100 Subject: [PATCH 13/26] Fix PMD warnings --- .../sourceforge/pmd/util/fxdesigner/XPathPanelController.java | 2 -- .../pmd/util/fxdesigner/util/AbstractController.java | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java index 34f7524ed8..0e84652b4a 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java @@ -123,8 +123,6 @@ public class XPathPanelController extends AbstractController { initGenerateXPathFromStackTrace(); - Map stringToButton = new HashMap<>(); - xpathVersionUIProperty = DesignerUtil.mapToggleGroupToUserData(xpathVersionToggleGroup); expressionTitledPane.titleProperty().bind(xpathVersionUIProperty.map(v -> "XPath Expression (XPath " + v + ")")); diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/AbstractController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/AbstractController.java index d93de1913b..a7bdf92336 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/AbstractController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/AbstractController.java @@ -44,7 +44,7 @@ public class AbstractController implements Initializable, SettingsOwner { * Always executed once. */ protected void beforeParentInit() { - + // by default do nothing } @@ -54,7 +54,7 @@ public class AbstractController implements Initializable, SettingsOwner { * parent, then this is never executed. */ protected void afterParentInit() { - + // by default do nothing } From f17aeba2f91fdae057c279ce538fbbd80e3cc29a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 11 Jan 2019 15:13:59 +0100 Subject: [PATCH 14/26] Move export XPath to rule button --- .../fxdesigner/MainDesignerController.java | 11 ---- .../util/fxdesigner/XPathPanelController.java | 18 ++++--- .../pmd/util/fxdesigner/fxml/designer.fxml | 3 -- .../pmd/util/fxdesigner/fxml/editor.fxml | 2 +- .../pmd/util/fxdesigner/fxml/xpath.fxml | 28 ++++++++-- .../pmd/util/fxdesigner/less/designer.less | 52 ++++++++++--------- 6 files changed, 65 insertions(+), 49 deletions(-) diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java index 823f93a3ba..b842c9b421 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/MainDesignerController.java @@ -84,10 +84,6 @@ public class MainDesignerController extends AbstractController { @FXML private Menu openRecentMenu; @FXML - private MenuItem exportToTestCodeMenuItem; - @FXML - private MenuItem exportXPathMenuItem; - @FXML private Menu fileMenu; /* Center toolbar */ @FXML @@ -136,13 +132,6 @@ public class MainDesignerController extends AbstractController { openRecentMenu.setOnAction(e -> updateRecentFilesMenu()); openRecentMenu.setOnShowing(e -> updateRecentFilesMenu()); fileMenu.setOnShowing(e -> onFileMenuShowing()); - exportXPathMenuItem.setOnAction(e -> { - try { - xpathPanelController.showExportXPathToRuleWizard(); - } catch (IOException e1) { - e1.printStackTrace(); - } - }); setupAuxclasspathMenuItem.setOnAction(e -> sourceEditorController.showAuxclasspathSetupPopup(designerRoot)); diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java index 0e84652b4a..1771ac7cca 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/XPathPanelController.java @@ -9,10 +9,8 @@ import java.io.IOException; import java.time.Duration; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; @@ -62,7 +60,6 @@ import javafx.scene.control.ListView; import javafx.scene.control.MenuItem; import javafx.scene.control.TextArea; import javafx.scene.control.TitledPane; -import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; @@ -96,6 +93,8 @@ public class XPathPanelController extends AbstractController { @FXML public ToolbarTitledPane expressionTitledPane; @FXML + public Button exportXpathToRuleButton; + @FXML private PropertyTableView propertyTableView; @FXML private SyntaxHighlightingCodeArea xpathExpressionArea; @@ -125,10 +124,12 @@ public class XPathPanelController extends AbstractController { xpathVersionUIProperty = DesignerUtil.mapToggleGroupToUserData(xpathVersionToggleGroup); - expressionTitledPane.titleProperty().bind(xpathVersionUIProperty.map(v -> "XPath Expression (XPath " + v + ")")); + expressionTitledPane.titleProperty().bind(xpathVersionUIProperty.map(v -> "XPath Expression (" + v + ")")); xpathResultListView.setCellFactory(v -> new XpathViolationListCell()); + exportXpathToRuleButton.setOnAction(e -> showExportXPathToRuleWizard()); + EventStreams.valuesOf(xpathResultListView.getSelectionModel().selectedItemProperty()) .conditionOn(xpathResultListView.focusedProperty()) .filter(Objects::nonNull) @@ -329,7 +330,7 @@ public class XPathPanelController extends AbstractController { } - public void showExportXPathToRuleWizard() throws IOException { + public void showExportXPathToRuleWizard() { ExportXPathWizardController wizard = new ExportXPathWizardController(xpathExpressionProperty()); @@ -341,7 +342,12 @@ public class XPathPanelController extends AbstractController { dialog.setOnCloseRequest(e -> wizard.shutdown()); dialog.initModality(Modality.WINDOW_MODAL); - Parent root = loader.load(); + Parent root; + try { + root = loader.load(); + } catch (IOException e) { + throw new RuntimeException(e); + } Scene scene = new Scene(root); //stage.setTitle("PMD Rule Designer (v " + PMD.VERSION + ')'); dialog.setScene(scene); diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/designer.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/designer.fxml index 746e92e25e..ded75513ed 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/designer.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/designer.fxml @@ -31,9 +31,6 @@ - - - diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml index 28f21eb6c3..2ddd52b1c3 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/editor.fxml @@ -35,7 +35,7 @@ AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> - diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml index fd203e2298..89cf022c68 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml @@ -4,17 +4,18 @@ + - + + - + - - + + + + + + + + @@ -84,6 +92,18 @@ toggleGroup="$xpathVersionToggleGroup" /> + diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less index e0ff160019..e1a840503c 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/designer.less @@ -157,6 +157,19 @@ -fx-font-size: @smaller-font-size; } + .separator { + //-fx-background-color: transparent; + + -fx-padding: 4 2 4 2; + + .line { + -fx-border-style: none solid none none; + -fx-border-width: 0.5px; + -fx-border-color: @fx-text-fill; + } + } + + .menu-bar { -fx-background-color: transparent; } @@ -174,11 +187,21 @@ } } -.menu-button.icon-menu-button { +// This is used for buttons that have just an icon and no text +.icon-button { + -fx-background-color: transparent; -fx-border-width: 0; -fx-border-insets: 0; - -fx-padding: 0; + .force-square(24); + + &, * { + -fx-graphic-text-gap: 0; + } + + .ikonli-font-icon { + -fx-fill: @fx-text-fill; + } &:showing, &:hover { -fx-background-color: @selection-focus-color; @@ -194,34 +217,15 @@ -fx-background-color: @darker-accent-focus; } +// TODO use ToolbarTitledPane everywhere and simplify stylesheets + #main-toolbar, .tool-bar.accent-header, .split-pane.accent-header > .split-pane-divider { + .fix-height(30); -fx-background-color: @app-darker-slate-color; } -.tool-bar { - .fix-height(30); - -fx-border-color: transparent; - -fx-border-width: .6; - - .button, .choice-box { - -fx-background-color: @app-base-color; - -fx-border-color: @darker-accent-border; - -fx-border-radius: 3; - } - - .button { - -fx-padding: -3 5 -3 5; - } -} - -// This is used for buttons that have just an icon and no text -.button.icon-button { - .fix-width(20); - .fix-height(20); - -fx-padding: 3; -} /* This is the special button to reduce the lower split pane. */ .toggle-button.expand-toggle { From 9111e257c44ea9e9388841430a7e74714768f2fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 11 Jan 2019 15:30:29 +0100 Subject: [PATCH 15/26] Change icon --- .../net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml index 89cf022c68..d1497ba022 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/fxml/xpath.fxml @@ -94,7 +94,7 @@