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

q1qsirdb  于 2021-07-09  发布在  Java
关注(0)|答案(2)|浏览(302)

我有一个简单的舞台 StageStyle.TRANSPARENT (没有默认按钮)。因此,我尝试创建自己的自定义按钮,每个按钮由一个 ImageView 激活下一个事件: setOnMouseEntered , setOnMouseExited 当然了 setOnMouseClicked .
问题是最小化按钮。下面是一个简单的实现

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

假设我的imageview是一个白色的矩形。在鼠标输入事件时,它会将其颜色更改为黑色。在鼠标退出时,它将返回白色。
ImageView 单击,窗口将最小化,直到现在一切都可以正常工作。
问题是,当应用程序被还原(最大化)时,最小化的自定义按钮会被黑色(表示按钮的颜色被悬停)而不是白色(未聚焦时的默认颜色)粘住。
p、 似乎一切都像 relocate , setImage 等内部 onMouseClicked 处理程序被 setInconified(true); 任何帮助都将不胜感激。
谢谢你花时间读这篇文章。
更新来澄清一点问题
正常打印屏幕图像(不悬停时)
悬停打印屏幕(悬停时)
正如你所观察到的,一切都很完美。当按下“-”按钮(最小化按钮)时,当应用程序恢复时,它将保持在悬停模式,直到鼠标光标再次悬停按钮(然后一切恢复正常)。遗憾的是,css方法和事件侦听器在图像视图中似乎都不能解决这个问题。
已加载更新代码
这是一个简单的单源文件,只有一个调用minimize的按钮

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");
}

这个问题可以在ubuntu14.04和windows10上重现。我不认为这是操作系统的问题
断然的
请查收并附上harry mitchel解决方案(再次感谢)。这是完全可行的。
如果您想通过添加setonmousespressed事件来修复上面的代码。

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

92dk7w1h1#

您可以监听stage类的maximized属性。在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);
    }
}
vyswwuz2

vyswwuz22#

你的问题不是很清楚(虽然不是很清楚),所以我会尽力解决你的问题。
我想你的颜色变化是通过 ImageView.setOnMouseEntered() 以及 ImageView.setOnMouseExited() . 如果是这样,您应该改用css。

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

对于你的“ps”部分的内容,我不明白,所以我不能给出任何建议。

相关问题