如何将ImageView包含在窗格内?

时间:2018-04-01 10:29:21

标签: java image javafx

情况

我有一个包含由多个Panes组成的GridPane的应用程序。每个窗格内部都有一个ImageView,它允许我在窗格内显示一个图像。我的应用程序遵循MVC模式,我希望我的setPaneImage()函数动态更改一个Pane的ImageView图像。

问题

我不知道如何访问Pane的ImageView?我知道你可以使用ImageView的setImage()来改变它的图像。要访问Pane中包含的ImageView,我想你必须使用.getChildren()方法,但我无法弄清楚如何实现它......

以下是简化代码:

public class ViewController extends Application implements EventHandler
{
    final Image paneVide = new Image( "sample/img/paneVide.png" );

    @Override
    public void start(Stage primaryStage) throws Exception
    {
        // Initializing attributes
        BorderPane borderPane = new BorderPane( );
        gridPane = new GridPane( );

        Pane p = new Pane( );

        // Adding ImageView to the Pane
        ImageView imv = new ImageView( );
        imv.setPreserveRatio( true );
        imv.setFitHeight( p.getHeight() );
        imv.setFitWidth( p.getWidth() );
        p.getChildren().add( imv );

        // Setting handler
        p.setOnMouseEntered( this );

        // Adding to GridPane
        gridPane.add( p, i, j );

        // [...] Rest of the display code
    }


    @Override
    public void handle(Event event)
    {
        Pane p;

        if( event.getSource() instanceof Pane ) {
            p = (Pane) event.getSource();

            // MOUSE HOVER
            if( event.getEventType().toString() == "MOUSE_ENTERED" )
                setPaneImage( p, "VIDE" );
        }
    }


    // Here's the function where I don't really know what to do...
    // How do I access the Pane's ImageView so that I can dynamically
    // change its image ??
    public void setPaneImage( Pane p, String img )
    {
        switch( img )
        {
            case "VIDE":
                p.getChildren().add( new ImageView(paneVide) );  // Setting pane's image
                break;
        }
    }
}

非常感谢!

1 个答案:

答案 0 :(得分:0)

最简单的方法是在字段中存储对(Get-Command mkdir) CommandType Name Version Source ----------- ---- ------- ------ Function mkdir (Get-Command mkdir).ScriptBlock #Returns the functions script-block, listing parameters ++ #... $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('New-Item', [System.Management.Automation.CommandTypes]::Cmdlet) $scriptCmd = {& $wrappedCmd -Type Directory @PSBoundParameters } 的引用:

ImageView

假设private ImageView imv; public void start(Stage primaryStage) throws Exception { ... this.imv = new ImageView(); ... } public void setPaneImage(Pane p, String img) { ... imv.setImage(paneVide); ... } ImageView的唯一子项,您还可以从子列表中检索Pane

ImageView

附加说明:

您的代码的某些部分可能被视为不良做法:

public void setPaneImage(Pane p, String img) {
    ImageView imv = (ImageView) p.getChildren().get(0);
    ...
}
  1. 您使用if(event.getEventType().toString() == "MOUSE_ENTERED") 而非String
  2. ==进行比较
  3. 您应该与事件类型进行比较,而不是将转换为equals的类型进行比较:String
  4. 您不需要检查。这是处理程序监听的唯一事件。应使用不同的处理程序处理不同类型的事件。您可以轻松地使用匿名类或lambda表达式创建这样的处理程序。您可以使用相同的策略来避免源检查。
  5. event.getEventType() == MouseEvent.MOUSE_ENTERED

    使用魔术字符串是一个坏主意。如果字符串中有拼写错误,很难找到错误。您只需传递public void setPaneImage(Pane p, String img) { switch( img ) { case "VIDE": 本身(Image)即可。通过这种方式,您根本不需要paneVide,任何拼写错误都会在编译时变得明显。

    switch

    在第一次布局传递之前执行此操作。那时imv.setFitHeight(p.getHeight()); imv.setFitWidth(p.getWidth()); 的大小仍为0.您应该使用绑定来适应以后属性的更新:

    p

    确保imv.fitHeightProperty.bind(p.heightProperty()); imv.fitWidthProperty.bind(p.widthProperty()); imv.setManaged(false); // make sure p can shrink 调整GridPane的大小也是有益的。

    p

    public class ViewController extends Application implements EventHandler 类是程序的入口点。使用它作为控制器和事件处理程序违反了关注点分离原则。另外,最好为Application指定类型参数。