Una forma sencilla y rápida de aprender JAVA, observando y deduciendo cómo se comporta el lenguaje a través de ejemplos prácticos.

Archivo del blog

sábado, 7 de noviembre de 2020

Gráficos en 2D. Diagrama de Voronoi.

Código Java (voronoi.java):


package voronoi;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

public class Voronoi extends javax.swing.JFrame {
    
    BufferedImage imagen;
    int px[], py[], color[], zonas = 21, size = 350;

    public Voronoi() {
        
        super("Diagrama de Voronoi");
        setBounds(0, 0, size, size);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
                
        imagen = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
        px = new int[zonas];
        py = new int[zonas];
        color = new int[zonas];
        Random rand = new Random();
        for (int i = 0; i < zonas; i++) {
            px[i] = rand.nextInt(size);
            py[i] = rand.nextInt(size);
            color[i] = rand.nextInt(16777215);
        }
        int n;
        for (int x = 0; x < size; x++) {
            for (int y = 0; y < size; y++) {
                n = 0;
                for (int i = 0; i < zonas; i++) {
                    if (distance(px[i], x, py[i], y) < distance(px[n], x, py[n], y)) {
                        n = i;
                    }
                }
                imagen.setRGB(x, y, color[n]);
            }
        }
    }    
    
    @Override
    public void paint(Graphics g) {
        g.drawImage(imagen, 0, 0, this);
    }

    double distance(int x1, int x2, int y1, int y2) {
        double d;
        d = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
        return d;
    }

    public static void main(String[] args) {
        new Voronoi().setVisible(true);
    }

}


Resultado:





domingo, 25 de octubre de 2020

Gráficos en 2D. Diseño 2

Código Java (Design2.java):

package design;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import javax.swing.Timer;

public class Design2 extends javax.swing.JFrame {

    Trazador t;

    public Design2() {
        initComponents();
        this.setLocationRelativeTo(null);

        t = new Trazador(
                jPanel1.getGraphics(),
                jPanel1.getWidth(),
                jPanel1.getHeight(),
                0);

        Timer timer = new Timer(100, (ActionEvent e) -> {
            int a = 0;
            int b = 0;
            t.salta(245, 300);
            while (true) {
                for (int i = 0; i < 4; i++) {
                    t.avanza(80);
                    t.gira(90);
                }
                t.gira(15);
                a++;
                if (a >= 390 / 15) {
                    t.avanza(50);
                    a = 0;
                    b++;
                    if (b >= 12) {
                        break;
                    }
                }
            }
        });
        timer.start();
        timer.setRepeats(false);
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
                          
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Design 2 - 2020");
        setMinimumSize(new java.awt.Dimension(450, 450));
        setPreferredSize(new java.awt.Dimension(300, 300));
        setResizable(false);
        getContentPane().setLayout(new java.awt.GridLayout(1, 0));

        jPanel1.setBackground(new java.awt.Color(0, 0, 0));
        jPanel1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jPanel1MouseClicked(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 643, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 488, Short.MAX_VALUE)
        );

        getContentPane().add(jPanel1);

        getAccessibleContext().setAccessibleName("");

        pack();
    }// </editor-fold>                        

    private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {                                     

    }                                    

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Design2().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JPanel jPanel1;
    // End of variables declaration                   

    private static class Trazador {

        double x, y, angulo;
        Graphics g;

        private Trazador(Graphics g, float x, float y, float angulo) {

            this.x = x;
            this.y = y;
            this.angulo = angulo * Math.PI / 180;
            this.g = g;

            Graphics2D g2 = (Graphics2D) g;
            g2.setStroke(new BasicStroke(0.3f));
            g2.setColor(Color.YELLOW);
            g2.setRenderingHint(
                    RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);

        }

        public void gira(double angulo) {
            this.angulo += angulo * Math.PI / 180;
        }

        public void avanza(double distancia) {
            double x2 = x + distancia * Math.cos(angulo);
            double y2 = y - distancia * Math.sin(angulo);
            g.drawLine((int) x2, (int) y2, (int) x, (int) y);
            salta(x2, y2);
        }

        public void salta(double x, double y) {
            this.x = x;
            this.y = y;
        }
    }
}

Resultado:



Gráficos en 2D. Diseño 1

Código Java (Design1.java):

package design;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import javax.swing.Timer;

public class Design1 extends javax.swing.JFrame {

    Trazador t;

    public Design1() {
        initComponents();
        this.setLocationRelativeTo(null);

        t = new Trazador(
                jPanel1.getGraphics(),
                jPanel1.getWidth() / 2,
                jPanel1.getHeight() / 2,
                0);

        Timer timer = new Timer(100, (ActionEvent e) -> {
            int cont = 0;
            while (true) {
                for (int i = 0; i < 4; i++) {
                    t.avanza(90);
                    t.gira(90);
                }
                t.gira(5);
                cont++;
                if (cont >= 360 / 5) {
                    break;
                }
            }
        });
        timer.start();
        timer.setRepeats(false);
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
                          
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Design 1 - 2020");
        setMinimumSize(new java.awt.Dimension(300, 300));
        setPreferredSize(new java.awt.Dimension(300, 300));
        setResizable(false);
        getContentPane().setLayout(new java.awt.GridLayout(1, 0));

        jPanel1.setBackground(new java.awt.Color(0, 0, 0));
        jPanel1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jPanel1MouseClicked(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 643, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 488, Short.MAX_VALUE)
        );

        getContentPane().add(jPanel1);

        getAccessibleContext().setAccessibleName("");

        pack();
    }// </editor-fold>                        

    private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {                                     

    }                                    

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Design1().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JPanel jPanel1;
    // End of variables declaration                   

    private static class Trazador {

        double x, y, angulo;
        Graphics g;

        private Trazador(Graphics g, float x, float y, float angulo) {

            this.x = x;
            this.y = y;
            this.angulo = angulo * Math.PI / 180;
            this.g = g;

            Graphics2D g2 = (Graphics2D) g;
            g2.setStroke(new BasicStroke(1));
            g2.setColor(Color.YELLOW);
            g2.setRenderingHint(
                    RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);

        }

        public void gira(double angulo) {
            this.angulo += angulo * Math.PI / 180;
        }

        public void avanza(double distancia) {
            double x2 = x + distancia * Math.cos(angulo);
            double y2 = y - distancia * Math.sin(angulo);
            g.drawLine((int) x2, (int) y2, (int) x, (int) y);
            salta(x2, y2);
        }

        public void salta(double x, double y) {
            this.x = x;
            this.y = y;
        }
    }
}

Resultado:



Gráficos en 2D. Diseño 0

Código Java (Principal.java):

package octagono;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import javax.swing.Timer;

public class Principal extends javax.swing.JFrame {

   
Trazador t;

    public Principal() {
        initComponents();
        this.setLocationRelativeTo(null);

        t = new
Trazador(
                jPanel1.getGraphics(),
                jPanel1.getWidth() / 2,
                jPanel1.getHeight() / 2,
                0);

        Timer timer = new Timer(100, (ActionEvent e) -> {
            for (int i = 0; i < 8; i++) {
                t.gira(-45);
                for (int j = 0; j < 8; j++) {
                    t.avanza(45);
                    t.gira(45);
                }
            }
        });
        timer.start();
        timer.setRepeats(false);
    }

    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Octogonal Shape");
        setMinimumSize(new java.awt.Dimension(300, 300));
        setPreferredSize(new java.awt.Dimension(300, 300));
        setResizable(false);
        getContentPane().setLayout(new java.awt.GridLayout());

        jPanel1.setBackground(new java.awt.Color(0, 0, 0));

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 643, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 488, Short.MAX_VALUE)
        );

        getContentPane().add(jPanel1);

        pack();

    }                       


    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Principal().setVisible(true);
            }
        });
    }
               
    private javax.swing.JPanel jPanel1;         

    private static class
Trazador {

        double x, y, angulo;
        Graphics g;

        private Trazador(Graphics g, float x, float y, float angulo) {

            this.x = x;
            this.y = y;
            this.angulo = angulo * Math.PI / 180;
            this.g = g;

            Graphics2D g2 = (Graphics2D) g;
            g2.setStroke(new BasicStroke(2)); //Grosor pincel
            g2.setColor(Color.YELLOW); //Color
            g2.setRenderingHint(
                    RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);//Filtro de suavizado

        }

        public void gira(double angulo) {
            this.angulo += angulo * Math.PI / 180;
        }

        public void avanza(double distancia) {
            double x2 = x + distancia * Math.cos(angulo);
            double y2 = y - distancia * Math.sin(angulo);
            g.drawLine((int) x2, (int) y2, (int) x, (int) y);
            salta(x2, y2);
        }

        public void salta(double x, double y) {
            this.x = x;
            this.y = y;
        }
    }
}

 

Resultado:



 



sábado, 26 de septiembre de 2020

Sucesión de Fibonacci

La sucesión de Fibonacci comienza con los números 0 y 1 y a partir de estos cada número que les precede es la suma de los dos anteriores.

 

Código Java (Fibonacci.java):


package fibonacci;

public class Fibonacci {

    public static void main(String[] args) {
        int f0 = 0, f1 = 1, tmp;
        do {
            System.out.println(f0);
            tmp = f0 + f1;
            f0 = f1;
            f1 = tmp;
        } while (f0 < 1000);
    }

}


Resultado:

run:
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
BUILD SUCCESSFUL (total time: 0 seconds)


viernes, 12 de junio de 2020

Patrón III: Triángulo.

Código Java (Triangulos.java):

package triangulos;

import java.util.Scanner;

class Triangulos {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.print("Entra tamaño del triángulo: ");
        int n = in.nextInt();
        for (int i = n; i > 0; i--) {
            for (int j = 1; j < i; j++) {
                System.out.print(" ");
            }
            for (int j = i; j <= n; j++) {
                System.out.print("* ");
            }
            System.out.println("");
        }
    }
   
}


Resultado:

run:
Entra tamaño del triangulo: 10
         *
        * *
       * * *
      * * * *
     * * * * *
    * * * * * *
   * * * * * * *
  * * * * * * * *
 * * * * * * * * *
* * * * * * * * * *
BUILD SUCCESSFUL (total time: 3 seconds)


sábado, 16 de mayo de 2020

Cuadro binario aleatorio 16x16

Código Java (CuadroBinario.java):

package cuadrobinario;

public class CuadroBinario {

    public static void main(String[] args) {
        int n = 0;
        for (int i = 0; i < 16; i++) {
            for (int j = 0; j < 16; j++) {
                n = (int) (Math.random() * 2);
                System.out.print(String.format("%1$2s", n));
            }
            System.out.println("");
        }
    }

}



Resultado:

run:
 1 0 0 1 0 1 1 1 0 1 1 1 1 0 0 0
 1 0 0 0 0 1 1 1 0 0 1 1 0 1 1 1
 0 0 0 0 0 1 1 0 0 1 1 1 1 0 0 0
 0 1 1 0 0 1 1 1 0 0 1 0 0 0 0 1
 0 1 1 0 0 0 0 1 0 0 0 0 0 1 1 1
 1 1 0 0 0 1 0 1 1 0 1 1 0 0 0 1
 1 0 0 1 0 1 0 0 1 1 1 0 0 0 0 0
 1 1 0 1 0 0 0 1 0 0 0 0 0 1 1 1
 1 1 1 1 0 0 1 0 1 0 0 0 1 1 1 0
 1 0 1 1 1 1 1 1 1 1 1 0 1 0 0 1
 0 0 0 0 0 1 1 0 1 1 1 0 0 1 0 0
 0 1 1 1 0 1 0 0 0 1 1 0 0 1 1 0
 1 0 1 0 1 0 0 0 0 0 0 0 1 0 0 1
 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0
 1 1 0 1 1 1 1 0 0 0 0 0 1 0 1 0
 0 0 0 1 1 0 0 1 1 1 1 0 0 0 1 0
BUILD SUCCESSFUL (total time: 0 seconds)



viernes, 10 de abril de 2020

Patrón II: Cuadrado.

Código Java (Cuadros.java)

package cuadros;

import java.util.Scanner;

public class Cuadros {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.print("Entra tamaño del cuadro: ");
        int n = in.nextInt();       
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print("* ");
            }
            System.out.println("");
        }
    }

}



Resultado:

run:
Entra tamaño del cuadro: 10
* * * * *
* * * * *
* * * * * * * * * *
* * * * *
* * * * *
* * * * * * * * * *  
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * * 
* * * * * * * * * * 
* * * * * * * * * *
BUILD SUCCESSFUL (total time: 2 seconds)

domingo, 5 de abril de 2020

JavaFX. Inecuación de Gott. Calcular fechas del pasado.

Continuando con un post anterior relacionado con la inecuación de Gott, se procede a realizar la misma aplicación pero esta vez utilizando las librerías de JavaFX en las que aparecen nuevos componentes como por ejemplo los "DataPicker" que son utilizados para facilitar selección de fechas.

Se comentó en el post anterior que la "Inecuación de Gott" intentaba calcular el tiempo "de vida" de un evento histórico elegido al azar partiendo de un solo dato que era la fecha del inicio del evento.
En resumidas cuentas la fórmula predice la fecha del fin de un suceso que aún sigue en activo y que finalizará en un futuro aparentemente indeterminado.


Inecuación de Gott:



Ahora la idea NO es calcular cosas que van a suceder en el futuro, sino fechas del pasado, que por otra parte son fáciles de comprobar si los resultados obtenidos corresponden con la realidad consultando en la Wikipedia del hecho histórico en cuestión. Ejemplo:

Un ejemplo claro de un hecho histórico son las caídas de las Torres Gemelas de Nueva York. Todo el mundo se acuerda del año y día de la desaparición de las torres (11S de 2001), pero seguramente la mayoría no sabe la fecha de su inauguración. Imaginemos que no tenemos acceso a internet ni a hemerotecas para consultar año de su inauguración. Sólo disponemos de la fecha actual (04/04/2020) y fecha del fin de las Torres (11/09/2001).

Aplicando la fórmula con una fiabilidad del 50%:
Resultado obtenido: Fecha de inauguración de las Torres Gemelas entre 1946 y 1992
Realidad (consultando Wikipedia): "...Torres Gemelas, inauguradas el 4 de abril de 1973..."
Conclusión: Resultado satisfactorio ya que se encuentra dentro del rango fechas obtenido.

 

Inecuación de Gott aplicada al cálculo de fecha inauguración de las Torres Gemelas:





Ejemplo 2 -> Muro de Berlin (f = 50%):

Hecho histórico: Muro de Berlin
fecha actual: 04/04/2020
fecha caída del muro: 09/11/1989
fecha inauguración: ? (no lo sabemos)

Aplicando la fórmula con una fiabilidad del 50%:
Resultado obtenido: Fecha de inauguración entre 1898 y 1979
Realidad (consultando Wikipedia): "...formó parte de la frontera interalemana desde el 13 de agosto de 1961..."
Conclusión: Resultado satisfactorio ya que se encuentra dentro del rango de fechas obtenido.



Inecuación de Gott aplicada al cálculo de fecha inauguración del Muro de Berlín:

 


Cabe destacar que la "fiabilidad" es inversamente proporcional al grado de precisión. Es decir si queremos ganar en precisión (reducir el rango de fechas en el resultado) debemos bajar la fiabilidad.
Es algo parecido al principio de incertidumbre de Heisenberg que establece que a mayor certeza de la posición de una partícula, menor conocimiento de su momento o cantidad de movimiento y viceversa.


Ejemplo 3 -> Muro de Berlín (f = 1%):

Ahora aplicando a la fórmula una fiabilidad de sólo un 1% (más exactitud pero menos probabilidad):
Resultado obtenido: Fecha de comienzo entre 1958 y 1960
Realidad: Inaugurado en 1961
Conclusión: Como vemos da un resultado casi exacto pero esta fuera del rango obtenido (+exacto -fiable)


Notas varias:
 

Se recomienda dejar una fiabilidad del 50% para que haya un equilibrio entre grado de fiabilidad y grado de precisión.
Se observa que para obtener las fechas del pasado hay que poner en "Fecha_actual" la fecha de finalización. Y en "Fecha de inicio" la fecha actual (inversión de datos de entrada para pasar del futuro al pasado).



Código Java 1 (NewFXMain.java):

package inecuaciongottfx;

import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class NewFXMain extends Application {

    @Override
    public void start(Stage primaryStage) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("FXML.fxml"));
        Scene scene = new Scene(root);
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.setResizable(false);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}


Código Java 2 (FXMLController.java):

package inecuaciongottfx;

import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.input.MouseEvent;

public class FXMLController implements Initializable {

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    double f, fa, tmin, tmax;

    @FXML
    private DatePicker Fecha_Actual;
    @FXML
    private DatePicker Fecha_Inicio;
    @FXML
    private Label Tiempo_Transcurrido;
    @FXML
    private Label Fiabilidad;
    @FXML
    private Slider Slider_Fiabilidad;
    @FXML
    private Label Fecha_Minima;
    @FXML
    private Label Fecha_Maxima;
    @FXML
    private Label lb_fechas;
    @FXML
    private Button Calcular;
    @FXML
    private Button Limpiar;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        limpiar();
        Calcular.setOnMouseClicked((MouseEvent me) -> {
            calcular();
        });
        Limpiar.setOnMouseClicked((MouseEvent me) -> {
            limpiar();
        });
        // control arrastrar -clicar Slider
        Slider_Fiabilidad.setOnMouseClicked((MouseEvent me) -> {
            Fiabilidad.setText(Math.round(Slider_Fiabilidad.getValue()) + " %");
            calcular();
        });
        Slider_Fiabilidad.setOnMouseDragged((MouseEvent me) -> {
            Fiabilidad.setText(Math.round(Slider_Fiabilidad.getValue()) + " %");
            calcular();
        });
    }

    private void limpiar() {
        Fecha_Inicio.setValue(LocalDate.now());
        Fecha_Actual.setValue(LocalDate.now());
        Tiempo_Transcurrido.setText("0");
        Slider_Fiabilidad.setValue(50d);
        Fiabilidad.setText(Slider_Fiabilidad.getValue() + " %");
        Fecha_Minima.setText("00/00/0000");
        Fecha_Maxima.setText("00/00/0000");
        lb_fechas.setText("Resultado:");
    }

    private void calcular() {

        try {
            fa = ((dateFormat.parse(Fecha_Actual.getValue().toString()).getTime() - dateFormat.parse(Fecha_Inicio.getValue().toString()).getTime()) / 86400000);
        } catch (ParseException ex) {
        }

        f = Slider_Fiabilidad.getValue() / 100d;

        Tiempo_Transcurrido.setText("" + (int) Math.round(fa));

        tmin = fa * (Math.abs((f - 1) / (f + 1)));
        tmax = fa * (Math.abs((f + 1) / (f - 1)));

        Fecha_Minima.setText(sumarRestarDiasFecha(Fecha_Actual.getValue(), (int) Math.round(tmin)));
        Fecha_Maxima.setText(sumarRestarDiasFecha(Fecha_Actual.getValue(), (int) Math.round(tmax)));

        lb_fechas.setText("Resultado: Duración entre " + Math.round(tmin) + " y " + Math.round(tmax) + " días.");

    }

    public String sumarRestarDiasFecha(LocalDate ld, int dias) {

        // convertir Localdate a Date
        Instant instant = Instant.from(ld.atStartOfDay(ZoneId.systemDefault()));
        Date date = Date.from(instant);

        // sumar dias a la fecha
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, dias);

        // convertir Date a Localdate
        instant = calendar.getTime().toInstant();
        ld = instant.atZone(ZoneId.systemDefault()).toLocalDate();

        // formato dd-mm-yyy
        String[] aux = ld.toString().split("-");
        return aux[2] + "/" + aux[1] + "/" + aux[0];

    }

}


Código FMXL.fxml (generado con Scene Builder):

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.effect.Glow?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>

<AnchorPane id="AnchorPane" prefHeight="580.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="inecuaciongottfx.FXMLController">
   <children>
      <Label alignment="CENTER" contentDisplay="TEXT_ONLY" layoutX="70.0" layoutY="14.0" text="Inecuación de Gott. ¿cuánto tiempo dura algo?" textAlignment="CENTER" textFill="#077034" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="16.0">
         <font>
            <Font name="Tw Cen MT Condensed Bold" size="29.0" />
         </font>
         <opaqueInsets>
            <Insets />
         </opaqueInsets>
         <padding>
            <Insets bottom="10.0" />
         </padding>
         <effect>
            <Glow />
         </effect>
      </Label>
      <Pane layoutX="56.0" layoutY="92.0" prefHeight="364.0" prefWidth="494.0" translateY="5.0" AnchorPane.leftAnchor="50.0" AnchorPane.rightAnchor="50.0">
         <children>
            <Label alignment="CENTER" contentDisplay="TEXT_ONLY" text="Entrada de datos:" textAlignment="CENTER" textFill="#067235" underline="true">
               <font>
                  <Font name="Verdana Bold" size="14.0" />
               </font>
               <opaqueInsets>
                  <Insets />
               </opaqueInsets>
            </Label>
            <GridPane layoutY="29.0" prefHeight="122.0" prefWidth="493.0">
              <columnConstraints>
                <ColumnConstraints hgrow="SOMETIMES" maxWidth="195.4000244140625" minWidth="10.0" prefWidth="186.60003662109375" />
                <ColumnConstraints hgrow="SOMETIMES" maxWidth="160.199951171875" minWidth="10.0" prefWidth="143.39996337890625" />
                  <ColumnConstraints hgrow="SOMETIMES" minWidth="75.0" prefWidth="75.0" />
              </columnConstraints>
              <rowConstraints>
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
              </rowConstraints>
               <children>
                  <Label depthTest="ENABLE" text="Fecha inicio:">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Label text="Fecha actual:" GridPane.rowIndex="1">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Label text="Tiempo transcurrido:" GridPane.rowIndex="2">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Label text="Fiabilidad (%):" GridPane.rowIndex="3">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <DatePicker fx:id="Fecha_Inicio" promptText="1/1/2000" GridPane.columnIndex="1" />
                  <DatePicker fx:id="Fecha_Actual" promptText="1/1/2000" GridPane.columnIndex="1" GridPane.rowIndex="1" />
                  <Label fx:id="Tiempo_Transcurrido" alignment="CENTER" contentDisplay="CENTER" prefHeight="18.0" prefWidth="163.0" text="0" GridPane.columnIndex="1" GridPane.rowIndex="2">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                  </Label>
                  <Slider fx:id="Slider_Fiabilidad" blockIncrement="1.0" snapToTicks="true" value="50.0" GridPane.columnIndex="1" GridPane.rowIndex="3" />
                  <Label fx:id="Fiabilidad" text="50 %" GridPane.columnIndex="2" GridPane.rowIndex="3">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Label contentDisplay="CENTER" text="días" textAlignment="CENTER" GridPane.columnIndex="2" GridPane.rowIndex="2">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets left="10.0" right="10.0" />
                     </padding>
                  </Label>
               </children>
               <opaqueInsets>
                  <Insets />
               </opaqueInsets>
            </GridPane>
            <Label alignment="CENTER" contentDisplay="TEXT_ONLY" layoutY="191.0" text="Intervalo de duración del evento:" textAlignment="CENTER" textFill="#067235" translateY="-20.0" underline="true">
               <font>
                  <Font name="Verdana Bold" size="14.0" />
               </font>
               <opaqueInsets>
                  <Insets />
               </opaqueInsets>
            </Label>
            <GridPane layoutY="219.0" prefHeight="143.0" prefWidth="493.0" translateY="-15.0">
               <columnConstraints>
                  <ColumnConstraints hgrow="SOMETIMES" maxWidth="195.4000244140625" minWidth="10.0" prefWidth="186.60003662109375" />
                  <ColumnConstraints hgrow="SOMETIMES" maxWidth="160.199951171875" minWidth="10.0" prefWidth="143.39996337890625" />
                  <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
               </columnConstraints>
               <rowConstraints>
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
               </rowConstraints>
               <children>
                  <Label text="Fecha mínima:" GridPane.rowIndex="1">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Label text="Fecha máxima:" GridPane.rowIndex="2">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="10.0" />
                     </padding>
                     <GridPane.margin>
                        <Insets left="10.0" right="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Label fx:id="Fecha_Minima" alignment="CENTER" prefWidth="163.0" text="00/00/0000" GridPane.columnIndex="1" GridPane.rowIndex="1">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                  </Label>
                  <Label fx:id="Fecha_Maxima" alignment="CENTER" prefWidth="163.0" text="00/00/0000" GridPane.columnIndex="1" GridPane.rowIndex="2">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                  </Label>
                  <Label fx:id="lb_fechas" prefHeight="18.0" prefWidth="501.0" text="Resultado: " GridPane.columnSpan="3" GridPane.rowIndex="4">
                     <font>
                        <Font name="Verdana" size="14.0" />
                     </font>
                     <GridPane.margin>
                        <Insets left="10.0" />
                     </GridPane.margin>
                  </Label>
                  <Separator prefWidth="200.0" GridPane.columnSpan="3" GridPane.rowIndex="3" />
                  <Separator prefWidth="200.0" GridPane.columnSpan="3" />
               </children>
               <opaqueInsets>
                  <Insets />
               </opaqueInsets>
            </GridPane>
         </children>
      </Pane>
      <HBox layoutX="389.0" layoutY="383.0" prefHeight="28.0" prefWidth="161.0" translateX="-10.0" translateY="100.0" AnchorPane.bottomAnchor="150.0">
         <children>
            <Button fx:id="Calcular" mnemonicParsing="false" text="Calcular" textAlignment="CENTER">
               <font>
                  <Font name="Verdana" size="14.0" />
               </font>
            </Button>
            <Button fx:id="Limpiar" alignment="CENTER_RIGHT" contentDisplay="RIGHT" mnemonicParsing="false" text="Limpiar" textAlignment="CENTER">
               <font>
                  <Font name="Verdana" size="14.0" />
               </font>
               <opaqueInsets>
                  <Insets />
               </opaqueInsets>
               <HBox.margin>
                  <Insets left="10.0" />
               </HBox.margin>
            </Button>
         </children>
      </HBox>
   </children>
</AnchorPane>


Con la tecnología de Blogger.