JavaFX JavaFX Resize und DragAndDrop eines Pane

HaukeG

Mitglied
Hallo und guten Morgen,

ich versuche seit einigen Tagen ein Pane, welches auf einem Anchorpane liegt, per Drag and Drop zu verschieben (auf dem Anchorpane) und in alle Richtungen zu vergrößern / verkleinern (wenn man mit der Maus auf den Rand geht).
Nach rechts und unten kann ich vergrößern, da ich dann einfach setMinWidth setzen kann. Aber wenn ich rechts oder oben verkleinern / vergrößern möchte, muss ich ja die X / Y Koordinaten neu setzen. Dann fängt das Pane aber wie wild an zu blinken.

Ich habe das Beispiel hier mal erstellt auf Basis einer Hilfsklasse die ich im Netz gefunden habe.

Vielleicht kann mir ja jemand helfen. Vielen Dank,
Hauke

Java:
package de.hauke.playground.javafx.cargosoft.application;
 
import de.hauke.playground.javafx.cargosoft.testing.DragResizer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
 
public class Testing2 extends Application {
    public static void main(String[] args) {
        launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Hello World!");
        AnchorPane root = new AnchorPane();

        
        Pane pane = new Pane();
        pane.setStyle("-fx-background-color:red");
        pane.setMinWidth(100);
        pane.setMinHeight(100);
        
        DragResizer.makeResizable(pane);
        
        root.getChildren().add(pane);
        primaryStage.setScene(new Scene(root, 600, 600));
        primaryStage.show();
    }
}


Java:
package de.hauke.playground.javafx.cargosoft.testing;

import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;

public class DragResizer {
    
    private static final int RESIZE_MARGIN = 5;

    private final Region region;

    private double y;
    private double x;
    
    private boolean initMinHeight;
    private boolean initMinWidth;
    private boolean moving;
    private boolean dragging;
    
    private DragResizer(Region aRegion) {
        region = aRegion;
    }

    public static void makeResizable(Region region) {
        final DragResizer resizer = new DragResizer(region);
        
        region.setOnMousePressed(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent event) {
                resizer.mousePressed(event);
            }});
        region.setOnMouseDragged(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent event) {
                resizer.mouseDragged(event);
            }});
        region.setOnMouseMoved(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent event) {
                resizer.mouseOver(event);
            }});
        region.setOnMouseReleased(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent event) {
                resizer.mouseReleased(event);
            }});
    }

    protected void mouseReleased(MouseEvent event) {
        dragging = false;
        region.setCursor(Cursor.DEFAULT);
    }

    protected void mouseOver(MouseEvent event) {
    	// wenn cursor null ist, darf nicht vergroesstert / verkleinert werden
    	usedCursor = getCorrectCursor(event);
    	
        if(usedCursor != null || dragging) {
            region.setCursor(usedCursor);
        }
        else {
            region.setCursor(Cursor.DEFAULT);
        }
    }

    private Cursor getCorrectCursor(MouseEvent event) {
        if(event.getY() > (region.getHeight() - RESIZE_MARGIN)) {
        	if(event.getX() > (region.getWidth() - RESIZE_MARGIN)) {
        		return Cursor.SE_RESIZE;
        	}
        	if(event.getX() < RESIZE_MARGIN) {
        		return Cursor.SW_RESIZE;
        	}
        	return Cursor.S_RESIZE;
        } 
        if(event.getY() < RESIZE_MARGIN) {
        	if(event.getX() > (region.getWidth() - RESIZE_MARGIN)) {
        		return Cursor.NE_RESIZE;
        	}
        	if(event.getX() < RESIZE_MARGIN) {
        		return Cursor.NW_RESIZE;
        	}
        	return Cursor.N_RESIZE;
        }
        if(event.getX() < RESIZE_MARGIN) {
        	return Cursor.W_RESIZE;
        }
        if(event.getX() > (region.getWidth() - RESIZE_MARGIN)) {
        	return Cursor.E_RESIZE;
        }
        return null;
	}


    protected void mouseDragged(MouseEvent event) {
    	double mousey = event.getY();
    	double mousex = event.getX();

    	if(moving) {
        	System.out.println("try to move frame");
        	
        	region.setLayoutX(mousex);
        	region.setLayoutY(mousey);
        	
        	return;
        }
    	
    	if(!dragging) {
            return;
        }
        
        
        
        double newHeight = region.getMinHeight() + (mousey - y);
        double newWidth  = region.getMinWidth() + (mousex - x);

        if(usedCursor.equals(Cursor.S_RESIZE) || usedCursor.equals(Cursor.SW_RESIZE) || usedCursor.equals(Cursor.SE_RESIZE)) {
        	region.setMinHeight(newHeight);
        }
        if(usedCursor.equals(Cursor.E_RESIZE) || usedCursor.equals(Cursor.SE_RESIZE) || usedCursor.equals(Cursor.NE_RESIZE)) {
        	region.setMinWidth(newWidth);
        }
        if(usedCursor.equals(Cursor.W_RESIZE)) {
        	region.setLayoutX(mousex);

        }
        
        y = mousey;
        x = mousex;
    }

    private Cursor usedCursor;
    
    protected void mousePressed(MouseEvent event) {
        
        if(getCorrectCursor(event) == null) {
        	moving = true;
        	return;
        }
        moving = false;
        dragging = true;
        
        if (!initMinHeight) {
            region.setMinHeight(region.getHeight());
            region.setMinWidth(region.getWidth());
            initMinHeight = true;
            initMinWidth = true;
        }
        
        y = event.getY();
        x = event.getX();
    }
}
 
Hi,

hab deine #mouseDragged()-Methode so angepasst, dass statt event.getX() event.getgetSceneX() verwendet wird. Klappt bei mir mit Java7 wunderbar.

Code:
Java:
	protected void mouseDragged(MouseEvent event) {
		double mousex = event.getSceneX();
		double mousey = event.getSceneY();
		
		if (moving) {
			// System.out.println("try to move frame");
			
			y = mousey;
			x = mousex;
			
			if (x < 0) {
				x = 0;
			}
			if (y < 0) {
				y = 0;
			}
			
			region.setLayoutX(x);
			region.setLayoutY(y);
			
			return;
		}
		
		if (!dragging) {
			return;
		}
		
		double newHeight = region.getMinHeight() + (mousey - y);
		double newWidth = region.getMinWidth() + (mousex - x);
		
		if (usedCursor.equals(Cursor.S_RESIZE) || usedCursor.equals(Cursor.SW_RESIZE) || usedCursor.equals(Cursor.SE_RESIZE)) {
			region.setMinHeight(newHeight);
		}
		if (usedCursor.equals(Cursor.E_RESIZE) || usedCursor.equals(Cursor.SE_RESIZE) || usedCursor.equals(Cursor.NE_RESIZE)) {
			region.setMinWidth(newWidth);
		}
		if (usedCursor.equals(Cursor.W_RESIZE)) {
			region.setLayoutX(mousex);
			
		}
		
		y = mousey;
		x = mousex;
	}
 
Hallo,

schon mal nicht schlecht. Das resizen funktioniert noch nicht und das verschieben ist nicht da wo die Maus ist, aber im Prinzip kann ich damit den Rest selbst lösen. Sobald ich das fertig habe, schicke ich noch einmal die Lösung hier ins Forum. Vielleicht interessiert es ja noch jemand anderen 🙂

Viele Grüße,
Hauke
 
Ja, mach das ruhig mal. Ich hab so was tasächlich auch noch nicht selbst implementiert. Von daher ist es noch recht spannend. War von der Performance überrascht (sowohl resize als auch move) - hatte es doch vorher mit extrem kurzen Animationen versucht (1ms...).
 
Hallo,

ich habe das jetzt soweit fertig bekommen. Eine Kleinigkeit geht noch nicht so richtig, aber das fällt kaum auf. Wenn man die linke Seite verschiebt, macht der zum Anfang einen kleinen Sprung. Das muss ich noch einmal prüfen, aber im Prinzip geht es so. Sehr "gemein" ist das verschieben auf der linken Seite, da man da sowohl das LayoutX neu setzten muss, als auch die Width neu berechnen muss.

Java:
package de.hauke.playground.javafx.cargosoft.testing;

import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;

public class DragResizer {

	private static final int RESIZE_MARGIN = 5;

	private final Region region;

	private double y;
	private double x;

	private boolean initMinHeight;
	private boolean moving;
	private boolean dragging;

	private double lastX;
	private double lastY;

	private Cursor usedCursor;

	private DragResizer(Region aRegion) {
		region = aRegion;
	}

	public static void makeResizable(Region region) {
		final DragResizer resizer = new DragResizer(region);

		region.setOnMousePressed(new EventHandler<MouseEvent>() {
			public void handle(MouseEvent event) {
				resizer.mousePressed(event);
			}
		});
		region.setOnMouseDragged(new EventHandler<MouseEvent>() {
			public void handle(MouseEvent event) {
				resizer.mouseDragged(event);
			}
		});
		region.setOnMouseMoved(new EventHandler<MouseEvent>() {
			public void handle(MouseEvent event) {
				resizer.mouseOver(event);
			}
		});
		region.setOnMouseReleased(new EventHandler<MouseEvent>() {
			public void handle(MouseEvent event) {
				resizer.mouseReleased(event);
			}
		});
	}

	protected void mouseReleased(MouseEvent event) {
		dragging = false;
		region.setCursor(Cursor.DEFAULT);
	}

	protected void mouseOver(MouseEvent event) {
		// wenn cursor null ist, darf nicht vergroesstert / verkleinert werden
		usedCursor = getCorrectCursor(event);

		if (usedCursor != null || dragging) {
			region.setCursor(usedCursor);
		} else {
			region.setCursor(Cursor.DEFAULT);
		}
	}

	private Cursor getCorrectCursor(MouseEvent event) {
		if (event.getY() > (region.getHeight() - RESIZE_MARGIN)) {
			if (event.getX() > (region.getWidth() - RESIZE_MARGIN)) {
				return Cursor.SE_RESIZE;
			}
			if (event.getX() < RESIZE_MARGIN) {
				return Cursor.SW_RESIZE;
			}
			return Cursor.S_RESIZE;
		}
		if (event.getY() < RESIZE_MARGIN) {
			if (event.getX() > (region.getWidth() - RESIZE_MARGIN)) {
				return Cursor.NE_RESIZE;
			}
			if (event.getX() < RESIZE_MARGIN) {
				return Cursor.NW_RESIZE;
			}
			return Cursor.N_RESIZE;
		}
		if (event.getX() < RESIZE_MARGIN) {
			return Cursor.W_RESIZE;
		}
		if (event.getX() > (region.getWidth() - RESIZE_MARGIN)) {
			return Cursor.E_RESIZE;
		}
		return null;
	}

	
	
	protected void mouseDragged(MouseEvent event) {

		double diffX = event.getX() - x;
		double diffY = event.getY() - y;

		if (moving) {
			region.setLayoutX(region.getLayoutX() + diffX);
			region.setLayoutY(region.getLayoutY() + diffY);
			return;
		}

		if (!dragging) {
			return;
		}

		if (usedCursor.equals(Cursor.S_RESIZE)
				|| usedCursor.equals(Cursor.SW_RESIZE)
				|| usedCursor.equals(Cursor.SE_RESIZE)) {
	
			region.setMinHeight(event.getY());
			region.setMaxHeight(event.getY());
			region.setPrefHeight(event.getY());
		}
		if (usedCursor.equals(Cursor.E_RESIZE)
				|| usedCursor.equals(Cursor.SE_RESIZE)
				|| usedCursor.equals(Cursor.NE_RESIZE)) {
			region.setMinWidth(event.getSceneX() - region.getLayoutX());
			region.setMaxWidth(event.getSceneX() - region.getLayoutX());
			region.setPrefWidth(event.getSceneX() - region.getLayoutX());
		}
		if (usedCursor.equals(Cursor.W_RESIZE) || usedCursor.equals(Cursor.SW_RESIZE) || usedCursor.equals(Cursor.NW_RESIZE)) {
			region.setLayoutX(event.getSceneX());
		
			region.setMinWidth(region.getMinWidth() + (lastX - event.getSceneX()));
			region.setMaxWidth(region.getMaxWidth() + (lastX - event.getSceneX()));
			region.setPrefWidth(region.getPrefWidth() + (lastX - event.getSceneX()));
		
		}
		if (usedCursor.equals(Cursor.N_RESIZE) || usedCursor.equals(Cursor.NE_RESIZE) || usedCursor.equals(Cursor.NW_RESIZE)) {
			region.setLayoutY(region.getLayoutY() + (event.getSceneY() - lastY));
			region.setMinHeight(region.getMinHeight() + (lastY - event.getSceneY()));
			region.setMaxHeight(region.getMaxHeight() + (lastY - event.getSceneY()));
			region.setPrefHeight(region.getPrefHeight() + (lastY - event.getSceneY()));
		}
		
		lastX = event.getSceneX();
		lastY = event.getSceneY();
	}
	

	protected void mousePressed(MouseEvent event) {
		lastX = event.getSceneX();
		lastY = event.getSceneY();
		
		y = event.getY();
		x = event.getX();
		
		if (getCorrectCursor(event) == null) {
			moving = true;
			return;
		}
		moving = false;
		dragging = true;

		if (!initMinHeight) {
			region.setMinHeight(region.getHeight());
			region.setMinWidth(region.getWidth());
			initMinHeight = true;
			initMinWidth = true;
		}

		
	}
}


Viele Grüße,
Hauke
 

Zurück
Oben