2014-07-10 3 views
2

사용자 그래픽 (일종의 이미지)을 표시하는 앱을 가지고 있고 사용자가이 이미지에 선을 그릴 수 있도록하고 싶다고 가정 해 보겠습니다. 이러한 상황에 대해 다음과 같은 질문이 있습니다.이미지 JavaFX에 사용자 입력하기

어떻게 수행합니까? 사용자 끌기 이벤트에서 이미지의 픽셀 좌표를 어떻게 얻을 수 있습니까? 실시간으로 이미지를 어떻게 업데이트 하시겠습니까?

답변

2

난 당신에게 내가 가정 [자바 FX의 이미지 삭제]를 정반대의 예를 줄 것이다 당신을 위해 선발 포인트으로 충분합니다

import javafx.application.Application; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.canvas.Canvas; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.image.Image; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.Pane; 
import javafx.scene.paint.Color; 
import javafx.scene.paint.CycleMethod; 
import javafx.scene.paint.LinearGradient; 
import javafx.scene.paint.Stop; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 

public class EraseImageonCanvas extends Application { 
    private Pane root = new Pane(); 
    private void setCanvas(Canvas canvas, Image img) { 
     GraphicsContext gc = canvas.getGraphicsContext2D(); 
     gc.drawImage(img, 0, 0,canvas.getWidth(), canvas.getHeight()); 
    } 

    @Override 
    public void start(Stage primaryStage) { 
     primaryStage.setTitle("Erasing the Image"); 
     Rectangle rect = new Rectangle(400, 400); 
     drawBackground(rect); 
     root.getChildren().add(rect); 
     final Canvas canvas = new Canvas(200, 200); 
     canvas.setTranslateX(100); 
     canvas.setTranslateY(100); 
     //For local images use   
     //image = new Image(getClass().getResource(#Path#).openStream()); 
     final Image image = new Image(
       "http://kyllo.com.br/wp-content/uploads/2013/12/Faroeste-Cabloco.jpg" 
      ); 
     setCanvas(canvas,image); 
     final GraphicsContext gc = canvas.getGraphicsContext2D(); 
     // Clear away portions as the user drags the mouse 
     canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent e) { 
       gc.clearRect(e.getX() - 2, e.getY() - 2, 5, 5); 
      } 
     }); 

     // Reset the Canvas when the user double-clicks 
     canvas.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent t) {    
       if (t.getClickCount() >1) { 
        setCanvas(canvas, image); 
       } 
      } 
     }); 

     // Add the Canvas to the Scene, and show the Stage 
     root.getChildren().add(canvas); 
     primaryStage.setScene(new Scene(root, 400, 400)); 
     primaryStage.show(); 
    } 

    //Draws the background with a RadialGradient 
    private void drawBackground(Rectangle rect) { 
     rect.setFill(new LinearGradient(0, 0, 1, 1, true, 
       CycleMethod.REFLECT, 
       new Stop(0, Color.RED), 
       new Stop(1, Color.YELLOW))); 
    } 
    public static void main(String[] args) { 
     launch(args); 
    } 
} 

gist에 다운로드

+0

Thx하지만 모두 메인 스레드에서 수행되며 자동 업데이트를 위해 솔루션에 바인딩이 없습니다. 시나리오에서는 문제가되지 않지만 많은 계산을해야하는 작업을 고려하십시오. 앱이 멈췄다. – mrangry777

1

Canvas tutorial by Oracle은 "사용자와 상호 작용"섹션에서 수행하려는 작업을 정확히 보여줍니다.

캔버스에 EventHandler를 추가하여 MouseEvent (예 : MouseEvent.MOUSE_DRAGGED)을 처리하는 방법을 보여줍니다. 그런 다음 GraphicsContext을 사용하여 x 및 y 좌표를 가져 와서 캔버스에 그립니다.

의 기본 응용 프로그램 클래스 외부 캔버스를 사용하려면, 당신은 같은 당신의 .fxml 파일에 캔버스를 선언 할 것 :

<BorderPane fx:controller="controllers.MyController" 
    xmlns:fx="http://javafx.com/fxml"> 
    <Canvas fx:id="drawArea" height="..." width="..."/> 
</BorderPane> 

를 그런 다음 MyController에 클래스에 :

public class MyController implements Initializable { 
    @FXML 
    private Canvas drawArea; 
    private GraphicsContext gc; 

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 
    gc = drawArea.getGraphicsContext2D(); 
    // Java 8 syntax, beware! 
    drawArea.setOnMouseDragged(event -> gc.fillRect(event.getX(), event.getY(), 5, 5)); 
    } 
}