HanSolo / medusa

A JavaFX library for Gauges
Apache License 2.0
688 stars 129 forks source link

Feature Request: Reset/Zero set button for gauges where this makes sense #131

Open WolfgangFahl opened 7 years ago

WolfgangFahl commented 7 years ago

Medus is being used in the can4eve project http://can4eve.bitplan.com/images/can4eve/6/65/ScreenShot_Odometer_2017-08-16_103323.png shows a screenshot of some possible use. For gauges like the "Trip km" it makes sense to offer a reset button. I'll add this now as a separate button - it would be great if it could be integrated to the gauge itself.

HanSolo commented 7 years ago

Did you thought about composing a control made of a Pane, the Gauge and the Button? It does not make sense to add a button to the Gauge for one use case. But you can also add another which is a fork of the Gauge Skin but contains a button with it's own eventhandler.

WolfgangFahl commented 7 years ago

Thank you for your hint. The following code produces a result close to what I'd like to get:

 StackPane odopane = new StackPane();
    ImageButton resetButton = new ImageButton("resetdown.png","resetup.png");
    resetButton.setOnAction(new EventHandler<ActionEvent>() {
      @Override
      public void handle(ActionEvent e) {
        gauge.setValue(0);
      }
    });
    odopane.getChildren().add(cvpane);
    odopane.getChildren().add(resetButton);
    StackPane.setAlignment(resetButton, Pos.TOP_RIGHT);
grafik grafik

But now I am stuck - how do i position and resize the button in sync with the gauge?

WolfgangFahl commented 7 years ago

This code now works as expected. It would be great if #135 would be fixed that I woulnd't have to access the pane of the LCD Skin via getChildren().get(0) and a cast.

 /**
   * a resetable Gauge Skin
   * 
   * @author wf
   *
   */
  public static class ResetableGaugeSkin extends LcdSkin {

    private Pane pane;
    // private StackPane stackpane;

    /**
     * construct me for the given gauge
     * 
     * @param rgauge
     */
    public ResetableGaugeSkin(ResetableGauge rgauge) {
      super(rgauge);
      pane = (Pane) this.getChildren().get(0);
      ImageButton rb = rgauge.getResetButton();
      pane.getChildren().add(rb);
      rb.translateXProperty().set(10);
      rb.translateYProperty().set(5);
      rb.imageHeightProperty().bind(pane.heightProperty().multiply(0.225));
      rb.imageWidthProperty().bind(pane.widthProperty().multiply(0.15));
    }

  }

  /**
   * a Gauge with a ResetButton
   * 
   * @author wf
   *
   */
  public static class ResetableGauge extends Gauge {

    private ImageButton resetButton;
    private ResetableGaugeSkin skin;

    public ImageButton getResetButton() {
      return resetButton;
    }

    public void setResetButton(ImageButton resetButton) {
      this.resetButton = resetButton;
    }

    /**
     * construct me
     * 
     * @param title
     * @param unit
     */
    public ResetableGauge(String title, String unit) {
      super(SkinType.LCD);
      super.oldValueVisibleProperty().set(false);
      super.maxMeasuredValueVisibleProperty().set(false);
      super.minMeasuredValueVisibleProperty().set(false);
      super.tickLabelDecimalsProperty().set(0);

      super.decimalsProperty().set(0);
      super.titleProperty().set(title);
      super.unitProperty().set(unit);
      super.lcdDesignProperty().set(LcdGauge.lcdDesign);
      super.lcdFontProperty().set(LcdGauge.lcdFont);
      initResetButton();
      skin = new ResetableGaugeSkin(this);
      this.setSkin(skin);
    }

    /**
     * initialize my reset button
     */
    private void initResetButton() {
      setResetButton(new ImageButton("resetdown.png", "resetup.png"));
      getResetButton().setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent e) {
          DoubleProperty vp = ResetableGauge.this.valueProperty();
          if (vp.isBound()) {
            // a bound value can not be set

          } else {
            setValue(0);
          }
        }
      });
    }

    @Override
    public String getUserAgentStylesheet() {
      URL u = getClass().getResource("gauge.css");
      if (u != null)
        return u.toExternalForm();
      else
        return null;
    }

  }