自定义最小化按钮不会调用MouseLeave事件

时间:2017-01-04 01:24:38

标签: java javafx

我有一个StageStyle.TRANSPARENT的简单舞台(没有默认按钮)。 因此,我尝试创建自己的自定义按钮,每个按钮由ImageView表示,并激活下一个事件:setOnMouseEnteredsetOnMouseExited,当然还有setOnMouseClicked

问题出在 Minmized 按钮上。是一个简单的实现,如下面

ImageView.setOnMouseClicked((MouseEvent event) -> {
    stage.setIconified(true);
});

让我们想象一下,我的ImageView是一个白色矩形。在鼠标输入事件中,它将其颜色更改为黑色。在鼠标退出时,它将返回白色。

点击ImageView后,窗口将被最小化,一切都完美可行。直到现在。

问题是当应用程序恢复(最大化)时,最小化的自定义按钮会粘贴颜色黑色(代表按钮的颜色悬停),而不是白色(未聚焦时的默认颜色)。

P.S。似乎relocate处理程序中的setImageonMouseClicked等所有内容都被setInconified(true);

删除

非常感谢任何帮助。

感谢您抽出时间阅读本文。

更新以澄清问题

The normal print-screen image (when it is not hovered)

The hover print-screen (when it is hovered)

正如您所看到的,一切都很完美。在按下“ - ”按钮(最小化按钮)的那一刻,当应用程序恢复时,它将保持卡在悬停模式,直到鼠标光标再次悬停按钮(然后一切恢复正常)。遗憾的是,图像视图上的CSS方法或事件监听器似乎都没有解决这个问题。

更新已加载的代码

这是一个简单的源文件,只有一个调用最小化

的按钮
package application;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;


public class Main extends Application {
    private Scene scene;
    private Stage stage;

    @Override
    public void start(Stage stage) {
        try {
            this.stage = stage;
            stage.initStyle(StageStyle.TRANSPARENT);
            stage.setAlwaysOnTop(true);

            stage.setFullScreen(true);
            stage.setFullScreenExitHint("");

            createScene(stage);

            stage.setScene(scene);
            stage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private void createScene(Stage stage) {
        Pane layer = new Pane();
        layer.setPickOnBounds(false);

        scene = new Scene(layer, 800, 600);
        scene.getStylesheets().add("application/application.css");

        layer.getChildren().add(buildMinimizeImage());
    }

    private ImageView buildMinimizeImage() {
        ImageView imv = new ImageView();
        int width = 43 ;
        int height = 36;

        imv.setId("myImage");

        imv.setFitWidth(width);
        imv.setFitHeight(height);

        imv.setOnMouseClicked((MouseEvent event) -> {
            stage.setIconified(true);
        });

        imv.relocate(100, 100);

        return imv;
    }

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

application.css也非常简单

#myImage
{
    -fx-image: url("minimize.png");
}
#myImage:hover
{
    -fx-image: url("minimizeIn.png");
}

问题在Ubuntu 14.04和Windows 10上是可重现的。我不认为是操作系统问题

分辨

请附上Harry Mitchel解决方案(再次感谢您的支持)。这是完全可行的。

如果你想通过添加setOnMousePressed事件修复上面的代码。

imv.setOnMousePressed((MouseEvent event) -> {
    imv.setImage(image);
});

2 个答案:

答案 0 :(得分:1)

您可以聆听Stage类的最大化属性。在changed()方法内,设置ImageView的图像。

stage.maximizedProperty().addListener(new ChangeListener<Boolean>() {

    @Override
    public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
        //Display the desired icon here.
    }
});

这是一个自定义最小化按钮。您提供两个图像和舞台作为参数。当鼠标没有在按钮上时,它将显示构造函数的第一个参数中引用的图像。当鼠标悬停在按钮上时,它将显示构造函数的第二个参数中引用的图像。单击图像时,舞台将被最小化。

import javafx.event.ActionEvent;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;

public class MinimizeButton extends Button {
    /**
     * 
     * @param img the image when the button is NOT selected
     * @param imgHover the image when button is selected
     * @param stage the stage that will be minimized
     */
    public MinimizeButton(Image img, Image imgHover, Stage stage) {
        ImageView imgView = new ImageView(img);
        this.setGraphic(imgView);
        this.addEventHandler(MouseEvent.MOUSE_ENTERED, (MouseEvent e) -> {
            imgView.setImage(imgHover);
        });

        this.addEventHandler(MouseEvent.MOUSE_EXITED, (MouseEvent e) -> {
            imgView.setImage(img);
        });

        this.setOnAction((ActionEvent event) -> {
            stage.setIconified(true);
            imgView.setImage(img);
        });
    }
}

以下是使用MinimizeButton类的示例应用程序。

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class CustomMinimize extends Application {
    @Override
    public void start(Stage stage) {        
        Image imgWhite = new Image(getClass().getResourceAsStream("imgWhite.png"));  //your image here
        Image imgGreen = new Image(getClass().getResourceAsStream("imgGreen.png"));  //your hover image here
        MinimizeButton btnMinimize = new MinimizeButton(imgWhite, imgGreen, stage);
        btnMinimize.setStyle("-fx-background-color: black;");
        btnMinimize.setPrefSize(50, 50);
        Button btnExit = new Button("X");
        btnExit.setMinSize(50,50);
        btnExit.setOnAction((ActionEvent event) -> {
            System.exit(0);
        });
        btnExit.setStyle("-fx-background-color: black;");
        HBox hBox = new HBox();
        hBox.setSpacing(2);
        hBox.getChildren().addAll(btnMinimize, btnExit);

        AnchorPane anchorPane = new AnchorPane();
        anchorPane.getChildren().addAll(hBox);
        AnchorPane.setRightAnchor(hBox, 5.0);
        AnchorPane.setTopAnchor(hBox, 5.0);

        Scene scene = new Scene(anchorPane);
        stage.initStyle(StageStyle.TRANSPARENT);

        stage.setScene(scene);
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}

答案 1 :(得分:0)

你的问题不是很清楚(虽然不是很清楚),所以我会尝试解决你的问题。

我假设您的颜色更改是通过ImageView.setOnMouseEntered()ImageView.setOnMouseExited()完成的。如果是这样,你应该使用CSS。

.myImageView
{
    -fx-image: url("my_white_image.png");
}
.myImageView:hovered
{
    -fx-image: url("my_black_image.png");
}

对于你的&#34; PS&#34;部分,我无法理解,所以我无法就此提出任何建议。