2017-08-23 3 views
0

内部のウィンドウのタイトルの3つのボタンの1つをクリックして、その色を黒に変更したいとします。しかし時にはうまくいくし、時にはうまくいきません。 私のコードを見てください私に何が間違ってそれを教えてください!?なぜonMouseClickはjavafxの円の形で機能しませんか?

javac 1.8u20を使用してコンパイルし、1.9を実行すると、... イベントの処理方法の枠内に3つのレイヤーを使用すると、そこに問題はありますか?

package core.windowManager; 

import javafx.geometry.Insets; 
import javafx.geometry.Pos; 
import javafx.scene.Cursor; 
import javafx.scene.Node; 
import javafx.scene.control.Label; 
import javafx.scene.effect.DropShadow; 
import javafx.scene.layout.*; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Circle; 
import javafx.stage.Screen; 

import static javafx.scene.paint.Color.rgb; 

/** 
* Created by yn on 22/08/17. 
* just declare a win not more ... 
*/ 
public class win { 

/** 
* where we add the win to it in scene 
*/ 
private final AnchorPane root; 
/** 
* just the title and a hashCode from instance will be the win ID 
*/ 
private final String winId; 
/** 
* win pane contains title and content pane 
*/ 
private final AnchorPane winPane = new AnchorPane(); 
/** 
* title pane to add title label and some three [close-min-max] buttons maybe... 
*/ 
private final AnchorPane titlePane = new AnchorPane(); 
/** 
* where the content goes there ... 
*/ 
private final AnchorPane content = new AnchorPane(); 

/** 
* win title pane height 
*/ 
private final int winTitlePaneH = 30; 
/** 
* three close-min-max buttons 
*/ 
private final Circle closeShape = new Circle(); 
private final Circle minShape = new Circle(); 
private final Circle maxShape = new Circle(); 


/** 
* initialize the win class with some important params 
* 
* @param root //where the win add to scene 
* @param title // and String ID make by title+hashCode and used in windowManager 
* @param winW //win width 
* @param winH // win height 
*/ 
public win(AnchorPane root, String title, int winW, int winH) { 

    //init some final vars 
    this.root = root; 
    this.winId = title + "--" + this.hashCode(); 

    // make the winPane 
    winPane.setEffect(new DropShadow(20, rgb(0, 0, 0, 0.9))); 
    winPane.setPrefSize(winW, winH); 
    winPane.setStyle("-fx-background-color: #abcdef"); 
    // put winPane center of scene 
    double screenW = Screen.getPrimary().getVisualBounds().getWidth(); 
    double screenH = Screen.getPrimary().getVisualBounds().getHeight(); 
    double deltaW = (screenW - winW)/2; 
    double deltaH = (screenH - winH)/2; 
    winPane.setLayoutX(deltaW); 
    winPane.setLayoutY(deltaH); 
    // put it to top on click 
    winPane.setOnMouseClicked(e -> { 
     winPane.toFront(); 
    }); 

    //make title and top of window ... 
    titlePane.setPrefHeight(winTitlePaneH); 
    AnchorPane.setTopAnchor(titlePane, 0.0); 
    AnchorPane.setLeftAnchor(titlePane, 0.0); 
    AnchorPane.setRightAnchor(titlePane, 0.0); 

    // make winPane draggable by titlePane 
    makeDragable(titlePane); 
    makeResizable(50); 

    // add close and min buttons to title pane 
    closeShape.setRadius(winTitlePaneH/3); 
    closeShape.setFill(Color.RED); //red-yellow-green 
    closeShape.setOnMouseClicked(e -> { 
     closeShape.setFill(Color.BLACK); 
     e.consume(); 
    }); 

    //add min button to title pane 
    minShape.setRadius(winTitlePaneH/3); 
    minShape.setFill(Color.YELLOW); //red-yellow-green 
    minShape.setOnMouseClicked(e -> { 
     minShape.setFill(Color.BLACK); 
    }); 

    // add max button to title pane 
    maxShape.setRadius(winTitlePaneH/3); 
    maxShape.setFill(Color.GREEN); //red-yellow-green 
    maxShape.setOnMouseClicked(e -> { 
     maxShape.setFill(Color.BLACK); 

    }); 

    HBox bb = new HBox(); 
    //bb.setBackground(new Background(new BackgroundFill(Color.BLACK, null, Insets.EMPTY))); 
    AnchorPane.setLeftAnchor(bb, 0d); 
    AnchorPane.setTopAnchor(bb, winTitlePaneH/4.5); 
    AnchorPane.setBottomAnchor(bb, 0d); 
    bb.getChildren().addAll(closeShape, minShape, maxShape); 
    titlePane.getChildren().addAll(bb); 


    // add a label to show title 
    Label titleL = new Label(title); 
    titleL.setTextFill(Color.BLACK); 
    titleL.setAlignment(Pos.BASELINE_CENTER); 
    AnchorPane.setTopAnchor(titleL, 5.0); 
    AnchorPane.setLeftAnchor(titleL, 0.0); 
    AnchorPane.setRightAnchor(titleL, 0.0); 
    titlePane.getChildren().add(titleL); 


    titlePane.setBackground(new Background(new BackgroundFill(Color.web("#E2E0E2"), CornerRadii.EMPTY, Insets.EMPTY))); 

    winPane.getChildren().add(titlePane); 
    root.getChildren().add(winPane); 


} 


/** 
* titlePane to drag and win move behavior 
* 
* @param what 
*/ 
public void makeDragable(Node what) { 
    final Delta dragDelta = new Delta(); 

    what.setOnMousePressed(mouseEvent -> { 
     dragDelta.x = winPane.getLayoutX() - mouseEvent.getScreenX(); 
     dragDelta.y = winPane.getLayoutY() - mouseEvent.getScreenY(); 
     //also bring to front when moving 
     winPane.toFront(); 

    }); 

    what.setOnMouseDragged(mouseEvent -> { 
     winPane.setLayoutX(mouseEvent.getScreenX() + dragDelta.x); 
     winPane.setLayoutY(mouseEvent.getScreenY() + dragDelta.y); 

    }); 
} 

//current state 
private boolean RESIZE_BOTTOM; 
private boolean RESIZE_RIGHT; 

public void makeResizable(double mouseBorderWidth) { 
    winPane.setOnMouseMoved(mouseEvent -> { 
     //local window's coordiantes 
     double mouseX = mouseEvent.getX(); 
     double mouseY = mouseEvent.getY(); 
     //window size 
     double width = winPane.boundsInLocalProperty().get().getWidth(); 
     double height = winPane.boundsInLocalProperty().get().getHeight(); 
     //if we on the edge, change state and cursor 
     if (Math.abs(mouseX - width) < mouseBorderWidth 
       && Math.abs(mouseY - height) < mouseBorderWidth) { 
      RESIZE_RIGHT = true; 
      RESIZE_BOTTOM = true; 
      winPane.setCursor(Cursor.NW_RESIZE); 
     } else { 
      RESIZE_BOTTOM = false; 
      RESIZE_RIGHT = false; 
      winPane.setCursor(Cursor.DEFAULT); 
     } 

    }); 
    winPane.setOnMouseDragged(mouseEvent -> { 
     //resize root 
     Region region = (Region) winPane; 
     //resize logic depends on state 
     if (RESIZE_BOTTOM && RESIZE_RIGHT) { 
      region.setPrefSize(mouseEvent.getX(), mouseEvent.getY()); 
     } else if (RESIZE_RIGHT) { 
      region.setPrefWidth(mouseEvent.getX()); 
     } else if (RESIZE_BOTTOM) { 
      region.setPrefHeight(mouseEvent.getY()); 
     } 
    }); 
} 

//just for encapsulation 
private static class Delta { 
    double x, y; 
} 

}

答えて

2

マウスクリックはJavaFXのCircleで完璧に動作します。コードの問題は、タイトルに追加するラベルがサークルの上にあり、マウスのクリックをキャッチすることです。一番下の円をクリックするだけで、「時には」動作すると思うことができました。ここで画像を確認してください:

Inspected with ScenicView

をあなたが持つラベルにマウスを透明にすることによってそれを解決することができます

titleL.setMouseTransparent(true); 

やサークルと最初のラベルと、その後HBoxを加えます。

この種の問題の場合、ScenicViewは本当に便利なツールです。

0

私はそれがグループにのHBoxを使用して、3つのボタンレイアウト[近い分マックス]、次いでtoFront()。彼らはタイトルペインを越え、イベントは正しく動作します...

関連する問題