Jfxtrans mouseutil draggable limit to a region - jfxtras

I am developing a JavaFX application, used jfxtrans.mouseutil to make an anchor pane draggable, I want to bound or limit the draggable area to its parent, parent is also anchor pane.
I have tried to bound draggable area with checking the layoutx and layouty of the draggable pane but not working any solution?
My code:
MouseControlUtil.makeDraggable (testpane, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
testpane.setLayoutX(1);
}
}, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
}
});

Related

How to handle two different enter event in javafx?

I have Pane and text field. I handled enter event using event handler in both Pane and text field. I have written set of codes to perform when Pane enter pressed and text field enter event also. How to stop one event when another event is processing ? (Note: My TextField is in Pane).
capturePane.addEventFilter(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if(event.getCode()==KeyCode.ENTER){
System.out.println("capture pane enter clicked");
}
}
});
textFiled.addEventFilter(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if(event.getCode()==KeyCode.ENTER){
System.out.println("text field enter clicked");
}
}
});
In my case both print function worked at a time. I have to perform only one operation. How to do this ?
Thanks in advance.
You could do something like this if you are just trying to ignore the first input from the pane but still want to see the capture in the text field. The first one to see the input is the parent node then it continues down which is why you are seeing both print lines when you click enter
public class Main extends Application {
#Override
public void start(Stage stage) {
TextField textField = new TextField();
textField.addEventFilter(KeyEvent.KEY_RELEASED, event -> {
if(event.getCode()==KeyCode.ENTER){
System.out.println("text field enter clicked");
}
});
Pane capturePane = new Pane();
capturePane.addEventFilter(KeyEvent.KEY_RELEASED, event -> {
if(event.getTarget()==textField) {
System.out.println("Caught it and Ignored");
}
else if(event.getCode()== KeyCode.ENTER){
System.out.println("capture pane enter clicked");
//Do stuff
}
});
capturePane.getChildren().add(textField);
Scene scene = new Scene(capturePane);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) { launch(args); }
}

Gluon Charm TextField NPE

When you clear a TextField which is initialized with a floatText by textField.setText(null), the floatText isn't transitioned back to the bottom, and focusing the TextField again causes a NPE.
setText("") doesn't cause the NPE, but the floatText still stays on top.
public class GluonApplication extends MobileApplication {
#Override
public void init() {
addViewFactory(HOME_VIEW, () ->
{
TextField txtFloating = new TextField();
txtFloating.setFloatText("floating");
TextField txtNonFloating = new TextField();
txtNonFloating.setPromptText("non floating");
Button btnClear = new Button("clear text");
btnClear.setOnAction(e -> {
txtFloating.setText(null);
txtNonFloating.setText(null);
});
VBox boxContent = new VBox(20,txtNonFloating, txtFloating, btnClear);
boxContent.setAlignment(Pos.CENTER);
View view = new View(boxContent) {
#Override
protected void updateAppBar(AppBar appBar) {
appBar.setTitleText("Home");
}
};
return view;
});
}

Using one event handler for multiple actions

I was doing some homework today and I've accomplished all of the goals of the assignment, which I'm sure will get me full points.
In an earlier class, however, we used the same Event Handler for more than one action (in this example, you either type a color in the text field, or click a button to change the background color of the box).
I can't figure out how I would do that in this case... do I have to choose a Type in the constructor? If the first parameter could be a button or a textfield then I think that would help.
I'm just trying to figure out how to apply DRY (Don't Repeat Yourself), where ever I can.
public class ColorChooserApplication extends Application
{
#Override
public void start(Stage stage)
{
// Create all UI components
VBox backgroundBox = new VBox(10);
backgroundBox.setPadding(new Insets(10));
HBox topBox = new HBox(10);
HBox bottomBox = new HBox(10);
TextField colorPrompt = new TextField();
colorPrompt.setOnAction(new ColorHandler(colorPrompt, backgroundBox));
Button redButton = new Button("Red");
redButton.setOnAction(new ButtonHandler(redButton, backgroundBox));
Button whiteButton = new Button("White");
whiteButton.setOnAction(new ButtonHandler(whiteButton, backgroundBox));
Button blueButton = new Button("Blue");
blueButton.setOnAction(new ButtonHandler(blueButton, backgroundBox));
// Assemble
topBox.getChildren().add(colorPrompt);
bottomBox.getChildren().addAll(redButton, whiteButton, blueButton);
backgroundBox.getChildren().addAll(topBox, bottomBox);
backgroundBox.setAlignment(Pos.CENTER);
topBox.setAlignment(Pos.CENTER);
bottomBox.setAlignment(Pos.CENTER);
// Set scene and show
stage.setScene(new Scene(backgroundBox));
stage.show();
}
class ColorHandler implements EventHandler<ActionEvent>
{
TextField colorTf;
VBox bgVbox;
public ColorHandler(TextField colorTf, VBox bgVbox)
{
this.colorTf = colorTf;
this.bgVbox = bgVbox;
}
#Override
public void handle(ActionEvent event)
{
String color = colorTf.getText();
bgVbox.setStyle("-fx-background-color:" + color);
}
}
class ButtonHandler implements EventHandler<ActionEvent>
{
Button colorButton;
VBox bgVbox;
public ButtonHandler(Button colorButton, VBox bgVbox)
{
this.colorButton = colorButton;
this.bgVbox = bgVbox;
}
#Override
public void handle(ActionEvent event)
{
String color = colorButton.getText();
bgVbox.setStyle("-fx-background-color:" + color);
}
}
public static void main(String[] args)
{
launch(args);
}
}
If you're using Java 8, you can do
class ColorHandler implements EventHandler<ActionEvent> {
Supplier<String> colorSupplier ;
VBox bgVbox ;
public ColorHandler(Supplier<String> colorSupplier, VBox bgVbox) {
this.colorSupplier = colorSupplier ;
this.bgVbox = bgVbox ;
}
#Override
public void handle(ActionEvent event) {
String color = colorSupplier.get();
bgVbox.setStyle("-fx-background-color: "+color);
}
}
and then
colorPrompt.setOnAction(new ColorHandler(colorPrompt::getText, backgroundBox));
redButton.setOnAction(new ColorHandler(redButton::getText, backgroundBox));
Note that all you need to provide for the first parameter is some function that returns the correct string for use in the css. So you can do things like
whiteButton.setOnAction(new ColorHandler(() -> "#ffffff", backgroundBox));
blueButton.setOnAction(new ColorHandler(() -> "cornflowerblue", backgroundBox));
etc.

JavaFX textarea doesn't display changed value

Hello guys i'm using jdk 1.8 with NetBeans version 8 and SceneBuilder 2.2. I have files Main.fxml and MainController that have 2 tabs and a TextArea at the bottom which is supposed to print out status info.
Login.fxml is a tab which i attached to Main.fxml first tab through include in scenebuilder.
It has its own controllers and a button that need to print info to the TextArea in MainController. I can access the TextArea with FXMLLoader and change the value but it doesn't update in the UI. Let's say #FXML LogID is the TextArea in MainController and this is the code in LoginController:
#FXML
private Button btn;
#Override
public void initialize(URL url, ResourceBundle rb) {
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
try {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("Main.fxml"));
AnchorPane pane = fxmlLoader.load();
MainController control = (MainController) fxmlLoader.getController();
new Thread(new Runnable() {
#Override
public void run() {
Platform.runLater(new Runnable() {
#Override
public void run() {
control.LogID.appendText("Hello");
System.out.println(control.LogID.getText());
//prints "hello" in console but not the ui
}
});
}
}).start();
} catch (IOException ex) {
Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
Any help will be appreciated.
After about a week of trying everything I can I came up with a different solution.
This will update it without using FXMLLoader();
All i did was give the Login.fxml anchorpane an fx:id and kept printing getParent() to console until i got root so..
#FXML AnchorPane paneID; // In LoginController.java
//In platform.runLater i ran the bottom code
TextArea area = (TextArea) paneID.getParent().getParent().getParent().lookup("#LogID");
area.appendText("Hello\n");
first getParent was the tab content area
second tabpane
third the main anchorpane

How to make a VBox with animated "close up"?

I have built a form which has a VBox inside of a VBox. I want to make the internal VBox "close up" from the bottom to the top transitionally.
Afterwards, the next elements from the outer VBox should move up to fill the empty space, like when you remove items from a VBox.
How can I achieve this?
You can try next approach: use clipping to hide "disappearing" content and control height of the inner VBox during animation:
public class ShrinkingVBox extends Application {
private static class SmartVBox extends Region {
private Rectangle clipRect = new Rectangle();
private VBox content = new VBox();
public SmartVBox() {
setClip(clipRect);
getChildren().add(content);
}
// we need next methods to adjust our clipping to inner vbox content
#Override
protected void setWidth(double value) {
super.setWidth(value);
clipRect.setWidth(value);
}
#Override
protected void setHeight(double value) {
super.setHeight(value);
clipRect.setHeight(value);
}
// here we will do all animation
public void closeup() {
setMaxHeight(getHeight());
// animation hides content by moving it out of clipped area
// and reduces control height simultaneously
Timeline animation = TimelineBuilder.create().cycleCount(1).keyFrames(
new KeyFrame(Duration.seconds(1),
new KeyValue(content.translateYProperty(), -getHeight()),
new KeyValue(maxHeightProperty(), 0))).build();
animation.play();
}
protected ObservableList<Node> getContent() {
return content.getChildren();
}
}
#Override
public void start(Stage primaryStage) {
VBox outer = new VBox();
final SmartVBox inner = new SmartVBox();
//some random content for inner vbox
inner.getContent().addAll(
CircleBuilder.create().radius(25).fill(Color.YELLOW).build(),
CircleBuilder.create().radius(25).fill(Color.PINK).build());
// content for outer vbox, including inner vbox and button to run animation
outer.getChildren().addAll(
RectangleBuilder.create().width(50).height(50).fill(Color.GRAY).build(),
inner,
RectangleBuilder.create().width(50).height(50).fill(Color.RED).build(),
RectangleBuilder.create().width(50).height(50).fill(Color.BLUE).build(),
ButtonBuilder.create().text("go").onAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
inner.closeup();
}
}).build());
primaryStage.setScene(new Scene(new Group(outer)));
primaryStage.show();
}
public static void main(String[] args) {
launch();
}
}

Resources