package bluej.editor.moe;
import bluej.Config;
import bluej.editor.moe.MoeEditor.FindNavigator;
import bluej.utility.javafx.JavaFXUtil;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.effect.BlurType;
import javafx.scene.effect.InnerShadow;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polygon;
import org.fxmisc.wellbehaved.event.EventPattern;
import org.fxmisc.wellbehaved.event.InputMap;
import org.fxmisc.wellbehaved.event.Nodes;
import threadchecker.OnThread;
import threadchecker.Tag;
import static javafx.scene.input.KeyCombination.SHIFT_DOWN;
| The FindPanel class implements the find functionality of the MoeEditor.
| It provides both the user interface panel and the high level implementation
| of the find functionality.It also is a link to the replace panel.
|
| @author Marion Zalk
| @author Michael Kölling
|
@OnThread(Tag.FXPlatform)
public class FindPanel
extends GridPane{
private final TextField replaceField;
private final MoeEditor editor;
private final CheckBox matchCaseCheckBox;
private final Button previousButton;
private final Button nextButton;
private final TextField findField;
private FindNavigator currentNavigator;
private final BooleanProperty findResultsFound = new SimpleBooleanProperty(false);
private final SimpleBooleanProperty showingReplace;
| Constructor that creates and displays the different elements of the Find Panel
|
public FindPanel(MoeEditor ed)
{
editor = ed;
JavaFXUtil.addStyleClass(this, "moe-find-panel");
managedProperty().bind(visibleProperty());
JavaFXUtil.addStyleClass(this, "moe-find-grid");
HBox mcBody = new HBox();
BorderPane closeBody = new BorderPane();
JavaFXUtil.addStyleClass(closeBody, "moe-find-close-wrapper");
Label findLabel = new Label(Config.getString("editor.findpanel.findLabel"));
JavaFXUtil.addStyleClass(findLabel, "moe-find-label");
Label replaceDummyLabel = new Label(Config.getString("editor.replacePanel.replaceLabel"));
JavaFXUtil.addStyleClass(replaceDummyLabel, "moe-find-label");
replaceDummyLabel.setVisible(false);
StackPane findLabelPane = new StackPane(replaceDummyLabel, findLabel);
Label replaceFoldOutLabel = new Label(Config.getString("editor.findpanel.replacePanel"));
StackPane.setAlignment(findLabel, Pos.CENTER_RIGHT);
findField = new TextField();
JavaFXUtil.addStyleClass(findField, "moe-find-field");
JavaFXUtil.addChangeListenerPlatform(findField.textProperty(), search -> {
updateFindResult();
});
matchCaseCheckBox = new CheckBox();
matchCaseCheckBox.setText(Config.getString("editor.findpanel.matchCase"));
matchCaseCheckBox.setSelected(false);
JavaFXUtil.addChangeListenerPlatform(matchCaseCheckBox.selectedProperty(), cs -> {
updateFindResult();
});
Label closeIconLabel = new Label();
closeIconLabel.setGraphic(makeCloseIcon());
closeIconLabel.setOnMouseClicked(e -> cancelFind());
previousButton = new Button();
previousButton.setOnAction(e -> {
updateFindResult();
if (currentNavigator != null && currentNavigator.validProperty().get())
{
currentNavigator.selectPrev();
}
});
Label prevShortcut = new Label("\u21e7\u23ce");
previousButton.setText(Config.getString("editor.findpanel.findPrevious"));
previousButton.setGraphic(prevShortcut);
previousButton.setDisable(true);
nextButton = new Button();
nextButton.setOnAction(e -> {
updateFindResult();
if (currentNavigator != null && currentNavigator.validProperty().get())
{
currentNavigator.selectNext(false);
}
});
nextButton.setText(Config.getString("editor.findpanel.findNext"));
Label nextShortcut = new Label("\u23ce");
nextButton.setGraphic(nextShortcut);
nextButton.setDisable(true);
nextShortcut.visibleProperty().bind(findField.focusedProperty());
prevShortcut.visibleProperty().bind(findField.focusedProperty());
Nodes.addInputMap(findField, InputMap.sequence(
InputMap.consume(EventPattern.keyPressed(KeyCode.ESCAPE), e -> cancelFind()),
InputMap.consume(EventPattern.keyPressed(KeyCode.ENTER), e -> nextButton.fire()),
InputMap.consume(EventPattern.keyPressed(KeyCode.ENTER, SHIFT_DOWN), e -> previousButton.fire())
));
showingReplace = new SimpleBooleanProperty(false);
Polygon triangle = new Polygon(0, 0, 8, 5, 0, 10);
triangle.rotateProperty().bind(Bindings.when(showingReplace).then(90).otherwise(0));
replaceFoldOutLabel.setGraphic(triangle);
replaceFoldOutLabel.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
showingReplace.set(!showingReplace.get());
e.consume();
});
GridPane.setHalignment(closeBody, HPos.RIGHT);
closeBody.setMaxWidth(Double.MAX_VALUE);
GridPane.setHgrow(closeBody, Priority.ALWAYS);
closeBody.setCenter(closeIconLabel);
BorderPane.setAlignment(closeIconLabel, Pos.CENTER_RIGHT);
JavaFXUtil.addStyleClass(mcBody, "moe-find-options");
mcBody.setAlignment(Pos.CENTER);
matchCaseCheckBox.setAlignment(Pos.CENTER);
replaceFoldOutLabel.setAlignment(Pos.CENTER);
mcBody.getChildren().add(matchCaseCheckBox);
mcBody.getChildren().add(replaceFoldOutLabel);
Label replaceLabel = new Label(Config.getString("editor.replacePanel.replaceLabel"));
JavaFXUtil.addStyleClass(replaceLabel, "moe-find-label");
replaceField = new TextField();
Nodes.addInputMap(replaceField, InputMap.sequence(
InputMap.consume(EventPattern.keyPressed(KeyCode.ESCAPE), e -> cancelFind())
));
Button replaceOne = new Button(Config.getString("editor.replacePanel.replaceOnce"));
Button replaceAll = new Button(Config.getString("editor.replacePanel.replaceAll"));
replaceOne.setOnAction(e -> {
updateFindResult();
if (currentNavigator.validProperty().get())
{
setCurrentNavigator(currentNavigator.replaceCurrent(replaceField.getText()));
}
});
replaceAll.setOnAction(e -> {
updateFindResult();
if (currentNavigator.validProperty().get())
{
currentNavigator.replaceAll(replaceField.getText());
}
});
replaceOne.disableProperty().bind(findField.textProperty().isEmpty().or(findResultsFound.not()));
replaceAll.disableProperty().bind(replaceOne.disableProperty());
add(findLabelPane, 0, 0);
add(findField, 1, 0);
add(replaceField, 1, 1);
add(previousButton, 2, 0);
add(nextButton, 3, 0);
add(mcBody, 4, 0);
add(closeBody, 5, 0);
add(replaceLabel, 0, 1);
add(replaceOne, 2, 1);
add(replaceAll, 3, 1);
for (Node n : new Node[] {replaceLabel, replaceField, replaceOne, replaceAll
})
{
n.visibleProperty().bind(showingReplace);
n.managedProperty().bind(n.visibleProperty());
}
mcBody.setFillHeight(true);
for (Button b : new Button[]{previousButton, nextButton, replaceOne, replaceAll
})
{
b.setMaxHeight(Double.MAX_VALUE);
b.setMaxWidth(Double.MAX_VALUE);
}
}
| Makes a cross inside a circle for the close icon
|
private static Node makeCloseIcon()
{
Circle circle = new Circle(10);
circle.setEffect(new InnerShadow(BlurType.GAUSSIAN, Color.rgb(128, 128, 128, 0.4), 2, 0.5, 1, 1));
circle.setFill(Color.rgb(190, 190, 190, 1.0));
Line lineA = new Line(0, 0, 7, 7);
lineA.setStrokeWidth(3);
lineA.setStroke(Color.rgb(240, 240, 240));
Line lineB = new Line(0, 7, 7, 0);
lineB.setStrokeWidth(3);
lineB.setStroke(Color.rgb(240, 240, 240));
StackPane stackPane = new StackPane(circle, lineA, lineB);
stackPane.setPickOnBounds(true);
return stackPane;
}
| Hides the panel and clears the text fields.
|
private void cancelFind()
{
findField.clear();
replaceField.clear();
setReplaceEnabled(false);
setVisible(false);
}
| Finds a instance of the search string (forward, from the current selection beginning,
| including the possibility that the search result begins at current selection beginning).
|
private void updateFindResult()
{
setCurrentNavigator(editor.doFind(getSearchString(), !matchCaseCheckBox.isSelected()));
}
| Updates the search state based on the given FindNavigator object.
|
| This occurs either when the search term changes, or a replacement has occurred
| (which basically triggers a new find).
|
| All results will be highlighted, and if there are any results, the first will be selected.
|
private void setCurrentNavigator(FindNavigator navigator)
{
currentNavigator = navigator;
previousButton.disableProperty().unbind();
nextButton.disableProperty().unbind();
if (currentNavigator == null)
{
JavaFXUtil.setPseudoclass("bj-no-find-result", !getSearchString().isEmpty(), findField);
previousButton.setDisable(true);
nextButton.setDisable(true);
findResultsFound.set(false);
}
else
{
JavaFXUtil.setPseudoclass("bj-no-find-result", false, findField);
currentNavigator.highlightAll();
currentNavigator.selectNext(true);
previousButton.disableProperty().bind(findResultsFound.not());
nextButton.disableProperty().bind(findResultsFound.not());
findResultsFound.set(true);
}
}
| Display the find panel and initiate a search. If the selection is null the search
| the previous search String is used (if there is a previous search)
|
public void displayFindPanel(String selection)
{
if (selection == null)
{
selection = getSearchString();
}
this.setVisible(true);
populateFindTextfield(selection);
}
public String getSearchString()
{
return findField.getText();
}
| Display either writes an empty message or a message reflecting the
| number of occurrences found
|
private void writeMessage(boolean emptyMessage, int counter)
{
if (!emptyMessage) {
editor.writeMessage(" ");
return;
}
if (counter > 0) {
editor.writeMessage(Config.getString("editor.highlight.found").trim() + " "
+ counter + " " + Config.getString("editor.replaceAll.intancesOf").trim() + " "
+ getSearchString());
}
else {
if (counter < 1 && getSearchString().length() > 0) {
editor.writeMessage(Config.getString("editor.replaceAll.string").trim() + " "
+ getSearchString() + " " + Config.getString("editor.highlight.notFound").trim());
}
}
}
| Removes the highlights and sets the find and replace panel to invisible
| Also resets the replace icon to closed
|
public void close()
{
editor.removeSearchHighlights();
this.setVisible(false);
editor.getCurrentTextPane().requestFocus();
}
| Puts the focus in the find field
|
protected void requestFindfieldFocus()
{
findField.requestFocus();
}
| Populates the field and puts the focus in the text field
|
protected void populateFindTextfield(String selection)
{
findField.setText(selection);
findField.selectAll();
findField.requestFocus();
}
| Allows the replace button to be en/disabled
| @param isEnable true for enable; false if not
|
protected void setReplaceEnabled(boolean isEnabled)
{
showingReplace.set(isEnabled);
}
}
top,
use,
map,
class FindPanel
. FindPanel
. makeCloseIcon
. cancelFind
. updateFindResult
. setCurrentNavigator
. displayFindPanel
. getSearchString
. writeMessage
. close
. requestFindfieldFocus
. populateFindTextfield
. setReplaceEnabled
398 neLoCode
+ 24 LoComm