【问题标题】:Change icon on mouse over鼠标悬停更改图标
【发布时间】:2015-02-26 07:38:20
【问题描述】:

我想创建一个按钮,当我将鼠标移到上面时,它会改变默认图片。我做了这个例子,但它不能正常工作:

public class MainApp extends Application
{
    @Override
    public void start(Stage stage) throws Exception
    {
        StackPane bp = new StackPane();
        bp.getChildren().add(ReportsIcon());
        bp.setPrefSize(600, 600);

        Scene scene = new Scene(bp);
        scene.setFill(Color.ANTIQUEWHITE);

        stage.setTitle("JavaFX and Maven");
        stage.setScene(scene);
        stage.show();
    }

    private static final ImageView ReportsFirstIcon;

    static
    {
        ReportsFirstIcon = new ImageView(MainApp.class.getResource("/images/monitoring-colour.png").toExternalForm());
    }

    private static final ImageView RportsIconsSecond;

    static
    {
        RportsIconsSecond = new ImageView(MainApp.class.getResource("/images/monitoring-green.png").toExternalForm());
    }

    private HBox ReportsIcon()
    {
        HBox bpi = new HBox();
        bpi.setAlignment(Pos.CENTER);
        // Add Label to the Icon
        Text inftx = new Text("Reports");
        inftx.setFont(Font.font("Verdana", FontWeight.NORMAL, 13));   // Set font and font size
        inftx.setFill(Color.BLACK); // Set font color

        // Zoom into the picture and display only selected area
        Rectangle2D viewportRect = new Rectangle2D(0, 0, 0, 0);
        ReportsFirstIcon.setViewport(viewportRect);
        BorderPane pp = new BorderPane();
        pp.setCenter(ReportsFirstIcon);

        bpi.getChildren().addAll(pp, inftx);

        bpi.setOnMouseEntered(new EventHandler<MouseEvent>()
        {
            @Override
            public void handle(MouseEvent t)
            {
                pp.setCenter(ReportsFirstIcon);
            }
        });

        bpi.setOnMouseExited(new EventHandler<MouseEvent>()
        {
            @Override
            public void handle(MouseEvent t)
            {
                pp.setCenter(RportsIconsSecond);
            }
        });

        bpi.setOnMouseClicked(new EventHandler<MouseEvent>()
        {
            @Override
            public void handle(MouseEvent t)
            {
                // Open new window
            }
        });

        return bpi;
    }

    private HBox mouseOver(final HBox bp)
    {
        bp.setOnMouseEntered(new EventHandler<MouseEvent>()
        {
            @Override
            public void handle(MouseEvent t)
            {
                bp.setStyle("-fx-background-color: linear-gradient(#f2f2f2, #f2f2f2);"
                    + "  -fx-background-insets: 0 0 -1 0, 0, 1, 2;"
                    + "  -fx-background-radius: 3px, 3px, 2px, 1px;");
            }
        });

        bp.setOnMouseExited(new EventHandler<MouseEvent>()
        {
            @Override
            public void handle(MouseEvent t)
            {
                bp.setStyle("-fx-background-color: linear-gradient(#f2f2f2, #d4d4d4);"
                    + "  -fx-background-insets: 0 0 -1 0, 0, 1, 2;"
                    + "  -fx-background-radius: 3px, 3px, 2px, 1px;");
            }
        });

        return bp;
    }

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

}

现在,当我将鼠标移到用于保存图片的 Second BorderPane 之外时,无法正常工作的代码不会返回原始图像。 当我将鼠标移到舞台外时,图片会发生变化。任何想法如何解决这个问题?

我想默认显示第一张图片,当我将鼠标移到它上面以将其替换为第二张时。当我将鼠标移到外面时,我想恢复原始图片。

【问题讨论】:

    标签: javafx javafx-2


    【解决方案1】:

    解决方法

    您可以根据按钮的悬停属性将按钮的图形属性绑定到适当的 ImageView。

    button.graphicProperty().bind(
        Bindings.when(
            button.hoverProperty()
        )
            .then(meatView)
            .otherwise(lambView)
    );
    

    悬停:

    悬停:

    可执行样本

    import javafx.application.Application;
    import javafx.beans.binding.Bindings;
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.image.*;
    import javafx.scene.layout.StackPane;
    import javafx.scene.text.*;
    import javafx.stage.Stage;
    
    public class MuttonMorph extends Application {
    
        public static void main(String[] args) {
            launch(args);
        }
    
        @Override
        public void start(Stage stage) {
            ImageView lambView = new ImageView(
                    new Image(
                            lambLoc
                    )
            );
    
            ImageView meatView = new ImageView(
                    new Image(
                            meatLoc
                    )
            );
    
            Button button = new Button("Lamb,\nit's what's for dinner");
            button.setContentDisplay(ContentDisplay.TOP);
            button.setTextAlignment(TextAlignment.CENTER);
            button.setFont(Font.font(16));
    
            button.graphicProperty().bind(
                    Bindings.when(
                            button.hoverProperty()
                    )
                            .then(meatView)
                            .otherwise(lambView)
            );
    
            StackPane layout = new StackPane(button);
            layout.setPadding(new Insets(30));
    
            stage.setScene(new Scene(layout));
            stage.show();
        }
    
        // Icons are Linkware (Backlink to http://icons8.com required)
        private static final String lambLoc = "http://icons.iconarchive.com/icons/icons8/ios7/96/Animals-Sheep-icon.png";
        private static final String meatLoc = "http://icons.iconarchive.com/icons/icons8/ios7/96/Food-Lamb-Rack-icon.png";
    }
    

    替代方法

    您可以通过根据按钮的:hover CSS 伪类和-fx-graphic 属性定义适当的CSS 样式规则进行设置,从而在没有绑定的情况下执行类似的操作。

    【讨论】:

    • 你从哪里得到这么可爱的图片?
    • 你的例子很好!我可以请你给我看 HBox 而不是 Button 的例子吗?
    • @jewelsea 用 HBox 代替按钮可以实现吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 2010-11-30
    • 1970-01-01
    相关资源
    最近更新 更多