2016-06-27 9 views
1

Ich möchte eine Anwendung mit einer Schaltfläche und einem Farbwähler auf der Oberseite und einer Leinwand in der Mitte einer BorderPane erstellen. Ich habe eine Hauptklasse TestSceneBuilder und 2 Listener erstellt: einen für den Button und einen für den ColorPicker. Die Frage ist: Wenn ich Farbveränderungen erkenne, wie gebe ich sie an meinen CerchioListener weiter?Kommunikation zwischen Klassen/Listener

Hauptklasse:

public class TestSceneBuilder extends Application { 
    final int H = 300, W = 300; //height and width 
    BorderPane root; 
    @Override 
    public void start(Stage primaryStage) { 
     root = this.setScene(); 
     Scene scene = new Scene(root, H, W); 

     primaryStage.setTitle("Test"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 
    /** 
    * This method is supposed to build the scene with all components: 
    * a button "Draw" that draws the rectangle 
    * a canvas 
    * a colorPicker 
    * @return 
    */ 
    BorderPane setScene(){ 
     BorderPane border = new BorderPane(); 
     final ColorPicker cp = new ColorPicker(Color.AQUA); 
     Canvas canvas = new Canvas(H, W); 
     Button btn = new Button("Draw"); 
     /*CerchioListner should get the mouse clicked event and draw the circle*/ 
     final CerchioListner l = new CerchioListner(canvas, cp.getValue()); 
     btn.addEventHandler(MouseEvent.MOUSE_CLICKED, l); 

     /*ColorListener intercept the color change in ColorPicker cp and change the color of the 
     shape drawn*/ 
     ColorListener cl = new ColorListener(cp); 
     cp.setOnAction(cl); 

     HBox hb = new HBox(); 
     hb.getChildren().addAll(btn, cp); 
     border.setTop(hb); 
     BorderPane.setAlignment(hb, Pos.CENTER); 

     border.setCenter(canvas); 
     return border; 
    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     launch(args); 
    } 

} 

Button-Hörer: CerchioListener

public class CerchioListner implements javafx.event.EventHandler{ 
Canvas canvas = null; 
Color colore; 
public CerchioListner(Canvas c, Color colore) { 
    this.canvas = c; 
    this.colore = colore; 
} 

public void changeColor(Color c) { 
    this.colore = c; 
} 
@Override 
public void handle(Event t) { 
    disegna(); 
} 
public void disegna(){ 
    canvas.getGraphicsContext2D().setFill(colore); 
    canvas.getGraphicsContext2D().fillOval(20, 20, 20, 20); 
    } 
} 

Color Picker Zuhörer: ColorListener

public class ColorListener implements javafx.event.EventHandler{ 
ColorPicker cp = null; 
public ColorListener(ColorPicker cp) { 
    this.cp = cp; 
} 

@Override 
public void handle(Event t) { 
    Color c = cp.getValue(); 
    System.out.println("handle CP "+cp.getValue()); 

    //restituisciColoreSelezionato(c); 
} 

/*public Color restituisciColoreSelezionato(Color c){ 
    return c; 
}*/ 
} 

Antwort

1

Es gibt mehrere Dinge, die nicht das Beste ist, Sie haben können:

  • Sie haben eine Canvas, die nicht Mitglied der Main ist, nur eine lokale Variable in setScene(), daher ist es in diesem Verfahren nur zugänglich ist. Da der Canvas der wichtigste Teil Ihrer Klasse ist, sollten Sie ihn als Klassenmitglied haben, weil Sie von der Klasse aus auf ihn zugreifen möchten.

  • Der Zuhörer für die Button sollte jede Bezugnahme auf die ausgewählte Farbe nicht speichern und zum Canvas, wird es durch Main und der Hörer soll das Mitglied zur Verwendung gelagert.

  • Der Listener der ColorPicker sollte keine Referenz auf die ColorPicker selbst speichern. Die ColorPicker sollte ein Mitglied sein, damit es überall in Main auf die aktuell ausgewählte Farbe zugreifen kann.

Ich habe Ihren Code enthalten diese Änderungen aktualisiert:

public class TestSceneBuilder extends Application { 
    final int H = 300, W = 300; 
    BorderPane root; 
    Canvas canvas; 
    ColorPicker cp; 
    Button btn; 

    @Override 
    public void start(Stage primaryStage) { 
     root = this.setScene(); 
     Scene scene = new Scene(root, H, W); 

     primaryStage.setTitle("Test"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    BorderPane setScene(){ 
     BorderPane border = new BorderPane(); 

     cp = new ColorPicker(Color.AQUA); 
     canvas = new Canvas(H, W); 
     btn = new Button("Draw"); 

     btn.setOnAction((event) -> { 
      canvas.getGraphicsContext2D().setFill(cp.getValue()); 
      canvas.getGraphicsContext2D().fillOval(20, 20, 20, 20); 
     }); 


     HBox hb = new HBox(); 
     hb.getChildren().addAll(btn, cp); 
     border.setTop(hb); 
     BorderPane.setAlignment(hb, Pos.CENTER); 

     border.setCenter(canvas); 
     return border; 
    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     launch(args); 
    } 
} 

Wenn Sie mit externen Hörer bleiben wollen:

Austausch dies:

btn.setOnAction((event) -> { 
    canvas.getGraphicsContext2D().setFill(cp.getValue()); 
    canvas.getGraphicsContext2D().fillOval(20, 20, 20, 20); 
}); 

w

ith
CerchioListener cerchioListener = new CerchioListener(canvas); 
btn.setOnAction(cerchioListener); 
cerchioListener.colorProperty.bind(cp.valueProperty()); 

und fügen Sie den Hörer:

CerchioListener.java

public class CerchioListener implements EventHandler<ActionEvent> { 

    private Canvas canvas = null; 
    public ObjectProperty<Color> colorProperty = new SimpleObjectProperty<Color>(Color.WHITE); 

    public CerchioListener(Canvas c) { 
     this.canvas = c; 
    } 

    public Canvas getCanvas() { 
     return canvas; 
    } 

    public void setCanvas(Canvas canvas) { 
     this.canvas = canvas; 
    } 

    @Override 
    public void handle(ActionEvent t) { 
     canvas.getGraphicsContext2D().setFill(colorProperty.get()); 
     canvas.getGraphicsContext2D().fillOval(20, 20, 20, 20); 
    } 

} 
+0

Danke, lassen Sie mich überprüfen, ob ich es verstanden 1) jedes Mal, wenn ich will, ein Objekt verwenden (in In diesem Fall möchte ich auf 'Canvas' in verschiedenen Listeners malen) Ich sollte es als Objekt der Hauptklasse deklarieren? (In meinem Fall ist die Hauptklasse 'TestSceneBuilder'). 2) Der Listener für den Button sollte seine eigene 'Color color' Variable und nicht' Canvas' haben, da er bereits in 'TestSceneBuilder' gespeichert ist und ich vom ganzen Package darauf zugreifen kann, oder?2) Mein 'ColorPicker' benötigt kein' ColorPicker' Objekt im Inneren, auf das ich in 'TestSceneBuilder' zugreifen kann. Recht? – bogALT

+0

1) Korrigieren. 2) Nicht korrekt (ich habe mich vertippt): Der Listener sollte nichts speichern, sondern nur die Mitglieder von 'TestSceneBuilder' verwenden - wie im Beispiel es cp und canvas verwendet, die Mitglieder von' TestSceneBuilder' sind. 3) Der! Zuhörer! für die Wertänderung des 'ColorPickers' darf keine Referenz gespeichert werden. Wie Sie im Beispiel sehen können, habe ich nicht einmal einen Listener für den 'ColorPicker'. – DVarga

+0

Ich bin vielleicht langweilig, aber sagen wir, ich muss einen externen Listener verwenden und ich möchte, dass der Listener auf die 'Leinwand' zugreifen kann, ich muss' Leinwand' als 'final' in meiner Hauptklasse deklarieren, richtig? Sonst bekomme ich die Fehlermeldung "nicht statische Variable kann von statischen Umgebung zugegriffen werden", wenn ich versuche, mit 'TestClassCommunication.canvas' in' handle' Methode von meinem Listener zugreifen – bogALT