2017-07-31 73 views
0

我有一個包含矩形的窗格的JavaFX應用程序。這些矩形可以通過拖動鼠標來移動。當超過一半的重疊時突出顯示矩形

當我在另一個矩形上拖動一個矩形時,我想要第二個(背景)矩形突出顯示。這個工程,看下面的代碼

private boolean moveInProgress; 
private Point2D prevPos; 

public void onMousePressed(MouseEvent event) { 
    setMouseTransparent(true); 
    Point2D point = new Point2D(event.getSceneX(), event.getSceneY()); 

    if (!moveInProgress) { 
     moveInProgress = true; 

     prevPos = point; 
     LOG.debug("Mouse move started on location " + prevPos); 
    } 

    event.consume(); 
} 

public void onMouseDragged(MouseEvent event) { 
    if (moveInProgress) { 
     Point2D point = new Point2D(event.getSceneX(), event.getSceneY()); 
     this.toFront(); 

     double[] translationVector = new double[2]; 
     translationVector[0] = point.getX() - prevPos.getX(); 
     translationVector[1] = point.getY() - prevPos.getY(); 

     setTranslateX(getTranslateX() + translationVector[0]); 
     setTranslateY(getTranslateY() + translationVector[1]); 

     prevPos = point; 
    } 

    event.consume(); 
} 

public void onMouseReleased(MouseEvent event) { 
    setMouseTransparent(false); 

    if (moveInProgress) { 
     moveInProgress = false; 
    } 
    event.consume(); 
} 

public void onDragDetected(MouseEvent event) { 
    startFullDrag(); 
    event.consume(); 
} 

public void onMouseDragEntered(MouseDragEvent event) { 
    getStyleClass().add("drag-target"); 
    event.consume(); 
} 

public void onMouseDragExited(MouseDragEvent event) { 
    if (getStyleClass().contains("drag-target")) { 
     getStyleClass().remove("drag-target"); 
    } 
    event.consume(); 
} 

我想強調我的拖動矩形重疊的一半以上時,下面的矩形。在這幅圖中,我想突出顯示紅色的矩形,因爲灰色的矩形重疊了一半以上。

問題是MouseDragEntered和MouseDragExited事件是基於我的鼠標位置觸發的。當我的鼠標位置是圖片中的黑點時,我的鼠標事件只會在我的鼠標進入紅色矩形時觸發。

誰能給我一些指點如何突出在灰色矩形的拖動動作時,紅色矩形,超過一半是重疊?

Rectangles

+0

沒有測試,但是你可以使用'Shape.intersect(Rect1的,RECT2)'得到'Shape'代表的重疊:通話'getBoundsInLocal()'獲取結果的邊界,getWidth()'和getHeight()'得到重疊區域。然後與矩形本身的面積(或者只是寬度或高度,如果需要)進行比較,以查看是否有一半以上是重疊的。 –

+0

@James_D:你打算什麼時候做這些計算?我的問題是,事件進入和退出發生在我的鼠標指針位置。我可以對這些事件何時被解僱有影響嗎? – Aster

+0

是的,這很棘手;你可以只要在'mouseDragged'監聽器中移動矩形時執行計算;或者可以在拖動開始時創建自定義綁定(每個矩形未拖動一個),並在拖動結束時處理它們。 –

回答

0

一種方法是使每個矩形觀察到被拖動的矩形的邊界。那麼使用Shape.intersect(或通過其他方法)進行計算來查看矩形是否被被拖動的矩形覆蓋了50%是相當容易的。棘手的部分是將偵聽器添加到正在拖動的矩形中,並在矩形停止拖動時再次將其刪除。

下面是一個簡單的例子。我認爲我的設置與您設置的方式有所不同,但您應該能夠輕鬆地將其適用於您的用例。

import java.util.Random; 

import javafx.application.Application; 
import javafx.beans.property.ObjectProperty; 
import javafx.beans.property.SimpleObjectProperty; 
import javafx.beans.value.ChangeListener; 
import javafx.css.PseudoClass; 
import javafx.geometry.Bounds; 
import javafx.geometry.Insets; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.Pane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.scene.shape.Shape; 
import javafx.stage.Stage; 

public class DraggingHighlightRectangles extends Application { 

    private final Random rng = new Random(); 
    private final ObjectProperty<Rectangle> draggingRectangle = new SimpleObjectProperty<>(); 

    @Override 
    public void start(Stage primaryStage) { 
     Pane pane = new Pane(); 
     pane.setMinSize(600, 600); 

     Button newRectButton = new Button("New Rectangle"); 
     newRectButton.setOnAction(e -> pane.getChildren().add(createRectangle())); 

     BorderPane.setAlignment(newRectButton, Pos.CENTER); 
     BorderPane.setMargin(newRectButton, new Insets(5)); 

     BorderPane root = new BorderPane(pane); 
     root.setBottom(newRectButton); 

     Scene scene = new Scene(root); 
     scene.getStylesheets().add("style.css"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private Rectangle createRectangle() { 
     Rectangle rect = new Rectangle(rng.nextInt(400)+100, rng.nextInt(500)+50, 100, 50); 
     rect.setFill(randomColor()); 
     rect.getStyleClass().add("rect"); 

     ChangeListener<Bounds> boundsListener = (obs, oldBounds, newBounds) -> { 
      double myArea = rect.getWidth() * rect.getHeight() ; 
      Shape intersection = Shape.intersect(draggingRectangle.get(), rect); 
      Bounds intersectionBounds = intersection.getBoundsInLocal(); 
      double intersectionArea = intersectionBounds.getWidth() * intersectionBounds.getHeight() ; 
      rect.pseudoClassStateChanged(PseudoClass.getPseudoClass("highlight"), intersectionArea >= 0.5 * myArea); 
     }; 

     draggingRectangle.addListener((obs, oldRect, newRect) -> { 
      if (oldRect != null) { 
       oldRect.boundsInLocalProperty().removeListener(boundsListener); 
      } 
      if (newRect != null && newRect != rect) { 
       newRect.boundsInLocalProperty().addListener(boundsListener); 
      } 
      rect.pseudoClassStateChanged(PseudoClass.getPseudoClass("highlight"), false); 
     }); 

     class MouseLocation { double x, y ; } 
     MouseLocation mouseLocation = new MouseLocation(); 

     rect.setOnMousePressed(e -> { 
      draggingRectangle.set(rect); 
      rect.toFront(); 
      mouseLocation.x = e.getX() ; 
      mouseLocation.y = e.getY() ; 
     }); 

     rect.setOnMouseDragged(e -> { 
      rect.setX(rect.getX() + e.getX() - mouseLocation.x); 
      rect.setY(rect.getY() + e.getY() - mouseLocation.y); 
      mouseLocation.x = e.getX() ; 
      mouseLocation.y = e.getY() ; 
     }); 

     rect.setOnMouseReleased(e -> draggingRectangle.set(null)); 

     return rect ; 
    } 

    private Color randomColor() { 
     return Color.rgb(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256)); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

我的樣式,style.css中,只包含

.rect:highlight { 
    -fx-fill: yellow ; 
} 
+0

聽聽財產界的好主意。這使我找到了我的解決方案。 – Aster