I wanted to give the user the option to use the mouse wheel to zoom in and out of the CodeArea, but I can't figure out how to register a scroll listener. Here is some of what i tried:
CodeArea editor = new CodeArea();
ScaledVirtualized<MplEditor2> scale = new ScaledVirtualized<>(editor);
InputMap<Event> preventDefaultScroll = InputMap.consume(EventPattern.anyOf(//
eventType(ScrollEvent.ANY), //
eventType(ScrollEvent.SCROLL), //
eventType(ScrollEvent.SCROLL_FINISHED), //
eventType(ScrollEvent.SCROLL_STARTED)//
));
Nodes.addInputMap(editor, preventDefaultScroll);
editor.setOnScroll(e -> {
if (e.isControlDown()) {
double delta = e.getDeltaX();
Scale zoom = scale.getZoom();
zoom.setY(zoom.getY() + delta);
zoom.setX(zoom.getY() + delta);
}
});
This answer on StackOverflow suggests that this is not possible :(
It should be possible in 0.8.1. Are you sure you want to use deltaX for both the x and y values?
I'll need to look at this more closely to see why your code isn't working.
So, it looks like the event's target is ParagraphText or an individual Text object. I'm not entirely sure what consumes it, but something is consuming it before the area's scroll handler runs (even when I comment out the "prevent scroll" code).
It seems that the solution is to add an event filter to the area and run your scroll code there. The following code (using an InlineCssTextArea for simplicity) worked for me:
````java
import javafx.application.Application;
import javafx.event.Event;
import javafx.scene.Scene;
import javafx.scene.input.ScrollEvent;
import javafx.scene.transform.Scale;
import javafx.stage.Stage;
import org.fxmisc.flowless.ScaledVirtualized;
import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.InlineCssTextArea;
import org.fxmisc.wellbehaved.event.InputMap;
import org.fxmisc.wellbehaved.event.Nodes;
import static org.fxmisc.wellbehaved.event.EventPattern.anyOf;
import static org.fxmisc.wellbehaved.event.EventPattern.eventType;
import static org.fxmisc.wellbehaved.event.InputMap.consume;
public class ScaleAreaDemo extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
InlineCssTextArea editor = new InlineCssTextArea(String.join("\n", new String[] {
"stuff",
"more stuff",
"lots of more stuff",
"",
"",
"running out of ideas..."
}));
ScaledVirtualized<InlineCssTextArea> scaleVirtualized = new ScaledVirtualized<>(editor);
primaryStage.setScene(new Scene(new VirtualizedScrollPane<>(scaleVirtualized), 400, 400));
primaryStage.show();
// InputMap
// anyOf(
// eventType(ScrollEvent.ANY),
// eventType(ScrollEvent.SCROLL),
// eventType(ScrollEvent.SCROLL_FINISHED),
// eventType(ScrollEvent.SCROLL_STARTED)),
// e -> System.out.println("Scroll detected in override")
// );
// Nodes.addInputMap(editor, preventDefaultScroll);
editor.addEventFilter(ScrollEvent.ANY, e -> {
if (e.isControlDown()) {
double scaleAmount = 0.9;
Scale zoom = scaleVirtualized.getZoom();
if (e.getDeltaX() != 0) {
zoom.setX( e.getDeltaX() > 0 ? zoom.getX() * scaleAmount : zoom.getX() / scaleAmount );
}
if (e.getDeltaY() != 0) {
zoom.setY( e.getDeltaY() > 0 ? zoom.getY() * scaleAmount : zoom.getY() / scaleAmount );
}
}
});
}
}
````
It's amazing!
I use this for zoom:
double scale = e.getDeltaY() < 0 ? zoom.getY() * scaleAmount : zoom.getY() / scaleAmount;
zoom.setX(scale);
zoom.setY(scale);
Most helpful comment
So, it looks like the event's target is
ParagraphTextor an individualTextobject. I'm not entirely sure what consumes it, but something is consuming it before the area's scroll handler runs (even when I comment out the "prevent scroll" code).It seems that the solution is to add an event filter to the area and run your scroll code there. The following code (using an InlineCssTextArea for simplicity) worked for me:
````java
import javafx.application.Application;
import javafx.event.Event;
import javafx.scene.Scene;
import javafx.scene.input.ScrollEvent;
import javafx.scene.transform.Scale;
import javafx.stage.Stage;
import org.fxmisc.flowless.ScaledVirtualized;
import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.InlineCssTextArea;
import org.fxmisc.wellbehaved.event.InputMap;
import org.fxmisc.wellbehaved.event.Nodes;
import static org.fxmisc.wellbehaved.event.EventPattern.anyOf;
import static org.fxmisc.wellbehaved.event.EventPattern.eventType;
import static org.fxmisc.wellbehaved.event.InputMap.consume;
public class ScaleAreaDemo extends Application {
// InputMap preventDefaultScroll = consume(
// anyOf(
// eventType(ScrollEvent.ANY),
// eventType(ScrollEvent.SCROLL),
// eventType(ScrollEvent.SCROLL_FINISHED),
// eventType(ScrollEvent.SCROLL_STARTED)),
// e -> System.out.println("Scroll detected in override")
// );
// Nodes.addInputMap(editor, preventDefaultScroll);
editor.addEventFilter(ScrollEvent.ANY, e -> {
if (e.isControlDown()) {
double scaleAmount = 0.9;
Scale zoom = scaleVirtualized.getZoom();
if (e.getDeltaX() != 0) {
zoom.setX( e.getDeltaX() > 0 ? zoom.getX() * scaleAmount : zoom.getX() / scaleAmount );
}
if (e.getDeltaY() != 0) {
zoom.setY( e.getDeltaY() > 0 ? zoom.getY() * scaleAmount : zoom.getY() / scaleAmount );
}
}
});
}
}
````