2015-06-19 3 views
1

У меня возникли трудности с попыткой решить эту проблему. В настоящее время я пытаюсь понять, как изменить ImageView на другой ImageView, когда я нажимаю определенный ключ на клавиатуре, но я понятия не имею, как это сделать, Я уже огляделся почти везде, о чем я могу думать, но понятия не имею.Как изменить ImageView на KeyPressed

Heres код, это символьный класс:

import java.io.IOException; 
import java.io.InputStream; 
import java.nio.file.Files; 
import java.nio.file.Paths; 

import javafx.animation.Animation; 
import javafx.application.Application; 
import javafx.geometry.Rectangle2D; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.image.Image; 
import javafx.scene.image.ImageView; 
import javafx.scene.input.KeyCode; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 
import javafx.util.Duration; 


public class Character extends Application{ 

private static final int COLUMNS = 3; 
private static final int COUNT = 3; 
private static final int WIDTH = 48; 
private static final int HEIGHT = 50; 
ImageView imgView; 

public void start(Stage primaryStage) throws Exception { 
    Group root = new Group(); 

    imgView = characterStill(); 
    root.setOnKeyPressed(e -> { 
     if(e.getCode().equals(KeyCode.RIGHT)){ 
      try { 
       imgView = characterWalking(); 
      } catch (IOException ex) {} 
     } 
    }); 
    root.setOnKeyReleased(e -> { 
     if(e.getCode().equals(KeyCode.RIGHT)){ 
      try { 
       imgView = characterStill(); 
      } catch (IOException ex) {} 
     } 
    }); 

    root.getChildren().add(imgView); 
    Scene scene = new Scene(root, Menu.WIDTH, Menu.HEIGHT, Color.GREENYELLOW); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 
public ImageView characterStill() throws IOException{ 
    InputStream is = Files.newInputStream(Paths.get("C:\\Users\\Javier\\Desktop\\StickHero\\StillNinja.png")); 
    Image characterStill = new Image(is); 
    ImageView stillView = new ImageView(characterStill); 

    return stillView; 
} 
public ImageView characterWalking() throws IOException{ 
    final InputStream is = Files.newInputStream(Paths.get("C:\\Users\\Javier\\Desktop\\StickHero\\WalkingNinja.png")); 
    final Image characterWalking = new Image(is); 
    ImageView charView = new ImageView(characterWalking); 

    charView.setViewport(new Rectangle2D(0, 0, WIDTH, HEIGHT)); 

    final Animation animation = new AnimationGen(charView, Duration.millis(300), COUNT, COLUMNS, 0, 0, WIDTH, HEIGHT); 
    animation.setCycleCount(Animation.INDEFINITE); 
    animation.play(); 

    return charView; 
} 
} 

ответ

2

В Java все объекты доступны через ссылки. Важно сохранить различие между объектом в памяти и ссылкой на объект, ясным.

При выполнении

new ImageView(characterStill); 

новый объект ImageView создается в памяти. Когда вы затем (эффективно) сделать

imgView = new ImageView(characterStill); 

присвоить переменную imgViewссылку к этому объекту. Вы можете думать о ссылке как о местоположении памяти объекта (хотя на самом деле это не обязательно должно быть реализовано именно так).

Что происходит в вашем коде при инициализации эффективно следующее:

imgView = new ImageView(characterStill); 
root.getChildren().add(imgView); 

Так imgView содержит ссылку на объект ImageView отображается ваши characterStill изображения. Затем вы передаете эту ссылку на дочерний список root, поэтому теперь список дочерних элементов root содержит ссылку на тот же объект ImageView.

Теперь, когда пользователь нажимает ПРАВЫЙ ключ, вы (эффективно) выполнять

imgView = new ImageView(characterWalking); 

Это создает новый ImageView объект в памяти, и присваивает ссылку на него (думаю: расположение памяти этот новый объект) к переменной imgView.

Однако дочерний список root не изменился: он по-прежнему содержит исходную ссылку на первый объект ImageView. Поэтому в вашем пользовательском интерфейсе ничего не меняется.

Вы можете это исправить, заменив список потомков root с вновь созданной ImageView, т.е .:

root.setOnKeyPressed(e -> { 
    if(e.getCode().equals(KeyCode.RIGHT)){ 
     try { 
      imgView = characterWalking(); 
      root.getChildren().setAll(imgView); 
     } catch (IOException ex) {} 
    } 
}); 

Однако, это не очень эффективно. При каждом нажатии клавиши вы создаете совершенно новый объект в памяти, из изображения, загруженного с жесткого диска. Затем вы отбрасываете предыдущий объект и помещаете новый объект в пользовательский интерфейс.

Лучше всего использовать только один объект ImageView и заменить отображаемое изображение.Вы можете сделать это по телефону

imgView.setImage(...); 

Чтобы сделать еще более эффективным, вместо загрузки изображения с диска каждый раз, вы можете просто загрузить изображения при запуске, а затем использовать их. Этот код выглядит

import java.io.IOException; 
import java.io.InputStream; 
import java.nio.file.Files; 
import java.nio.file.Paths; 

import javafx.animation.Animation; 
import javafx.application.Application; 
import javafx.geometry.Rectangle2D; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.image.Image; 
import javafx.scene.image.ImageView; 
import javafx.scene.input.KeyCode; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 
import javafx.util.Duration; 


public class Character extends Application{ 

    private static final int COLUMNS = 3; 
    private static final int COUNT = 3; 
    private static final int WIDTH = 48; 
    private static final int HEIGHT = 50; 
    private ImageView imgView; 
    private Image characterStill ; 
    private Image characterWalking ; 
    private Animation animation ; 

    public void start(Stage primaryStage) throws Exception { 

     imgView = new ImageView(); 
     characterStill = loadCharacterStill(); 
     characterWalking = loadCharacterWalking(); 
     imgView.setViewport(new Rectangle2D(0, 0, WIDTH, HEIGHT)); 

     animation = new AnimationGen(charView, Duration.millis(300), COUNT, COLUMNS, 0, 0, WIDTH, HEIGHT); 
     animation.setCycleCount(Animation.INDEFINITE); 

     imgView.setImage(characterStill); 

     Group root = new Group(); 

     root.setOnKeyPressed(e -> { 
      if(e.getCode().equals(KeyCode.RIGHT)){ 
       imgView.setImage(characterWalking); 
       animation.play(); 
      } 
     }); 
     root.setOnKeyReleased(e -> { 
      if(e.getCode().equals(KeyCode.RIGHT)){ 
       imgView.setImage(characterStill); 
       animation.stop(); 
      } 
     }); 

     root.getChildren().add(imgView); 
     Scene scene = new Scene(root, Menu.WIDTH, Menu.HEIGHT, Color.GREENYELLOW); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public Image loadCharacterStill() throws IOException{ 
     InputStream is = Files.newInputStream(Paths.get("C:\\Users\\Javier\\Desktop\\StickHero\\StillNinja.png")); 
     Image characterStill = new Image(is); 
     return characterStill ; 
    } 

    public Image loadCharacterWalking() throws IOException{ 
     final InputStream is = Files.newInputStream(Paths.get("C:\\Users\\Javier\\Desktop\\StickHero\\WalkingNinja.png")); 
     final Image characterWalking = new Image(is); 
     return characterWalking ; 
    } 

} 

Очевидно, так как у меня нет доступа к вашим изображениям или ваш AnimationGen класс, я не проверял это; это должно дать вам идею.

+0

Thx! Это не совсем сработало, но вы поместили его таким образом, чтобы проложить путь для меня, чтобы понять это ха-ха (:! – Javier

Смежные вопросы