{"id":2402,"date":"2016-10-04T15:00:00","date_gmt":"2016-10-04T15:00:00","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2402"},"modified":"2025-06-13T19:56:30","modified_gmt":"2025-06-14T02:56:30","slug":"using-couchbase-lite-in-a-java-gluon-application","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-lite-in-a-java-gluon-application\/","title":{"rendered":"Uso de Couchbase Lite en una aplicaci\u00f3n Java Gluon"},"content":{"rendered":"<p>Hace poco escrib\u00ed sobre la creaci\u00f3n de aplicaciones de escritorio con <a href=\"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-in-a-javafx-desktop-application\/\">Couchbase Lite y JavaFX<\/a>. Como se ha demostrado Couchbase es una excelente soluci\u00f3n para el almacenamiento de datos y sincronizaci\u00f3n en una aplicaci\u00f3n de escritorio debido a la Java SDK disponible. Sin embargo, soy consciente de que JavaFX no es para todo el mundo.<\/p>\n<p>Existe otro framework similar para crear aplicaciones de escritorio en Java. Se llama Gluon, y tambi\u00e9n ofrece soporte para aplicaciones Android e iOS. Sin embargo, en este ejemplo nos centraremos estrictamente en el escritorio.<\/p>\n<p>Vamos a ver c\u00f3mo crear una aplicaci\u00f3n de escritorio Gluon utilizando casi el mismo c\u00f3digo que se encuentra en nuestro anterior ejemplo JavaFX.<\/p>\n<h2>Requisitos<\/h2>\n<p>Hay algunos requisitos para construir una aplicaci\u00f3n Gluon que utilice Couchbase.<\/p>\n<ul>\n<li>JDK 1.7+<\/li>\n<li>IntelliJ IDEA<\/li>\n<li>Pasarela de sincronizaci\u00f3n Couchbase<\/li>\n<\/ul>\n<p>Normalmente no hago de esto un requisito, pero es mucho m\u00e1s f\u00e1cil crear una aplicaci\u00f3n Gluon con un IDE como IntelliJ, por eso est\u00e1 en la lista. Hay un plugin para IntelliJ que construir\u00e1 un proyecto Gluon con Gradle y todo lo que necesitas.<\/p>\n<p>Aunque Couchbase Sync Gateway no es realmente un requisito, es necesario si quieres a\u00f1adir soporte de sincronizaci\u00f3n entre tu aplicaci\u00f3n y Couchbase Server \/ otras plataformas y dispositivos.<\/p>\n<h2>Creaci\u00f3n de un nuevo proyecto Gluon<\/h2>\n<p>Si decide utilizar IntelliJ para compilar su proyecto, aseg\u00farese de haber descargado el plugin Gluon tal y como se describe a continuaci\u00f3n <a href=\"https:\/\/gluonhq.com\/the-new-gluon-plugin-for-intellij-idea\/\">aqu\u00ed<\/a>.<\/p>\n<p>Utilizando IntelliJ, cree un nuevo proyecto, pero elija crear un proyecto <strong>Gluon Desktop - Proyecto de vistas m\u00faltiples con FXML<\/strong> como se ve a continuaci\u00f3n.<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2016\/october\/using-couchbase-lite-in-a-java-gluon-application\/cb-gluon-desktop-1.png\" \/><\/p>\n<p>En \u00faltima instancia, depende de usted hacia d\u00f3nde ir a partir de aqu\u00ed, pero para mantenerse lo m\u00e1s cerca posible de esta gu\u00eda, d\u00e9 a su proyecto un <strong>com.couchbaselabs<\/strong> nombre del paquete y <strong>glu\u00f3n<\/strong> clase principal.<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2016\/october\/using-couchbase-lite-in-a-java-gluon-application\/cb-gluon-desktop-2.png\" \/><\/p>\n<p>Todo lo que sigue puede dejarse por defecto ya que s\u00f3lo vamos a hacer una aplicaci\u00f3n de dos p\u00e1ginas con Gluon. Cuando hayamos terminado, es de esperar que nos quedemos con una estructura de archivos y directorios parecida a la siguiente:<\/p>\n<pre><code>\r\ngradle\r\n    wrapper\r\nsrc\r\n    main\r\n        java\r\n            com\r\n                couchbaselabs\r\n                    views\r\n                        PrimaryPresenter.java\r\n                        PrimaryView.java\r\n                        SecondaryPresenter.java\r\n                        SecondaryView.java\r\n                    CouchbaseSingleton.java\r\n                    Todo.java\r\n                    gluon.java\r\n    resources\r\n        couchbaselabs\r\n            views\r\n                primary.fxml\r\n                primary.css\r\n                secondary.fxml\r\n                secondary.css\r\n            style.css\r\n        icon.png\r\nbuild.gradle\r\ngradlew\r\ngradlew.bat\r\n<\/code><\/pre>\n<p>Te dar\u00e1s cuenta de que he creado algunos archivos adicionales, tales como <strong>CouchbaseSingleton.java<\/strong> y <strong>Todo.java<\/strong>.<\/p>\n<p>Esencialmente tenemos vistas XML y controladores que van con esas vistas. Esto es muy similar a lo que vimos en un <a href=\"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-in-a-javafx-desktop-application\/\">Aplicaci\u00f3n JavaFX<\/a>. A la hora de dise\u00f1ar esas vistas, tenemos varias opciones. Podemos usar XML sin procesar, o podemos usar <a href=\"https:\/\/gluonhq.com\/labs\/scene-builder\/\">SceneBuilder<\/a>. Ahora bien, no hay que confundir este SceneBuilder con el JavaFX SceneBuilder. Comet\u00ed este error y estuve d\u00e1ndome cabezazos durante bastante tiempo. La versi\u00f3n que queremos soportar\u00e1 aplicaciones Gluon.<\/p>\n<p>Antes de empezar a a\u00f1adir c\u00f3digo de aplicaci\u00f3n, debemos a\u00f1adir nuestras dependencias al archivo Gradle del proyecto. Si no est\u00e1s familiarizado con Gradle, hace el mismo trabajo que Maven o Ant. La sintaxis es diferente, pero yo personalmente lo encuentro un poco m\u00e1s limpio. Abra el proyecto de <strong>build.gradle<\/strong> e incluya el siguiente c\u00f3digo:<\/p>\n<pre><code>\r\nbuildscript {\r\n    repositories {\r\n        jcenter()\r\n    }\r\n    dependencies {\r\n        classpath 'org.javafxports:jfxmobile-plugin:1.0.8'\r\n    }\r\n}\r\n\r\napply plugin: 'org.javafxports.jfxmobile'\r\n\r\nrepositories {\r\n    jcenter()\r\n    maven {\r\n        url 'https:\/\/nexus.gluonhq.com\/nexus\/content\/repositories\/releases'\r\n    }\r\n}\r\n\r\nmainClassName = 'com.couchbaselabs.gluon'\r\n\r\ndependencies {\r\n    compile 'com.gluonhq:charm:3.0.0'\r\n    compile 'com.couchbase.lite:couchbase-lite-java:1.3.0'\r\n    desktopRuntime 'com.gluonhq:charm-desktop:3.0.0'\r\n}\r\n<\/code><\/pre>\n<p>Lo m\u00e1s importante aqu\u00ed son las dependencias:<\/p>\n<pre><code>\r\ndependencies {\r\n    compile 'com.gluonhq:charm:3.0.0'\r\n    compile 'com.couchbase.lite:couchbase-lite-java:1.3.0'\r\n    desktopRuntime 'com.gluonhq:charm-desktop:3.0.0'\r\n}\r\n<\/code><\/pre>\n<p>Esto incluir\u00e1 la biblioteca Couchbase Lite, as\u00ed como el tiempo de ejecuci\u00f3n de la aplicaci\u00f3n de escritorio para Gluon.<\/p>\n<p>Con el proyecto listo, podemos empezar a desarrollar la aplicaci\u00f3n.<\/p>\n<h2>Dise\u00f1o de la capa de datos de Couchbase<\/h2>\n<p>Cuando trabajamos con Couchbase es una buena idea crear una instancia singleton del mismo. Esto significa que vamos a utilizar la misma instancia abierta durante toda la aplicaci\u00f3n, hasta que decidamos cerrarla.<\/p>\n<p>Abra el archivo <strong>src\/main\/java\/com\/couchbaselabs\/CouchbaseSingleton.java<\/strong> e incluya el siguiente c\u00f3digo:<\/p>\n<pre><code>\r\npackage com.couchbaselabs;\r\n\r\nimport com.couchbase.lite.*;\r\nimport com.couchbase.lite.replicator.Replication;\r\n\r\nimport java.net.URL;\r\nimport java.util.ArrayList;\r\nimport java.util.HashMap;\r\nimport java.util.Iterator;\r\nimport java.util.Map;\r\n\r\npublic class CouchbaseSingleton {\r\n\r\n    private Manager manager;\r\n    private Database database;\r\n    private Replication pushReplication;\r\n    private Replication pullReplication;\r\n\r\n    private static CouchbaseSingleton instance = null;\r\n\r\n    private CouchbaseSingleton() {\r\n        try {\r\n            this.manager = new Manager(new JavaContext(\"data\"), Manager.DEFAULT_OPTIONS);\r\n            this.database = this.manager.getDatabase(\"fx-project\");\r\n            View todoView = database.getView(\"todos\");\r\n            todoView.setMap(new Mapper() {\r\n                @Override\r\n                public void map(Map&lt;String, Object&gt; document, Emitter emitter) {\r\n                    emitter.emit(document.get(\"_id\"), document);\r\n                }\r\n            }, \"1\");\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n\r\n    public static CouchbaseSingleton getInstance() {\r\n        if(instance == null) {\r\n            instance = new CouchbaseSingleton();\r\n        }\r\n        return instance;\r\n    }\r\n\r\n    public Database getDatabase() {\r\n        return this.database;\r\n    }\r\n\r\n    public void startReplication(URL gateway, boolean continuous) {\r\n        this.pushReplication = this.database.createPushReplication(gateway);\r\n        this.pullReplication = this.database.createPullReplication(gateway);\r\n        this.pushReplication.setContinuous(continuous);\r\n        this.pullReplication.setContinuous(continuous);\r\n        this.pushReplication.start();\r\n        this.pullReplication.start();\r\n    }\r\n\r\n    public void stopReplication() {\r\n        this.pushReplication.stop();\r\n        this.pullReplication.stop();\r\n    }\r\n\r\n    public Todo save(Todo todo) {\r\n        Map&lt;String, Object&gt; properties = new HashMap&lt;String, Object&gt;();\r\n        Document document = this.database.createDocument();\r\n        properties.put(\"type\", \"todo\");\r\n        properties.put(\"title\", todo.getTitle());\r\n        properties.put(\"description\", todo.getDescription());\r\n        try {\r\n            todo.setDocumentId(document.putProperties(properties).getDocument().getId());\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n        return todo;\r\n    }\r\n\r\n    public ArrayList query() {\r\n        ArrayList results = new ArrayList();\r\n        try {\r\n            View todoView = this.database.getView(\"todos\");\r\n            Query query = todoView.createQuery();\r\n            QueryEnumerator result = query.run();\r\n            Document document = null;\r\n            for (Iterator it = result; it.hasNext(); ) {\r\n                QueryRow row = it.next();\r\n                document = row.getDocument();\r\n                results.add(new Todo(document.getId(), (String) document.getProperty(\"title\"), (String) document.getProperty(\"description\")));\r\n            }\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n        return results;\r\n    }\r\n\r\n}\r\n<\/code><\/pre>\n<p>Si viste la aplicaci\u00f3n JavaFX que constru\u00ed anteriormente, notar\u00e1s que este singleton es el mismo entre los dos proyectos. Incluso puedes usar una versi\u00f3n similar para Android.<\/p>\n<p>En el <code>CouchbaseSingleton<\/code> estamos creando y abriendo una base de datos local llamada <strong>proyecto fx<\/strong>. Esta base de datos se utilizar\u00e1 en toda la aplicaci\u00f3n. Tambi\u00e9n estamos creando nuestra vista Couchbase Lite para realizar consultas. Este <code>todos<\/code> emitir\u00e1 un par clave-valor de id de documento y documento para cada documento de la base de datos local.<\/p>\n<p>El m\u00e9todo constructor es privado, lo que significa que no queremos que el usuario pueda instanciar un objeto desde \u00e9l. En su lugar, queremos utilizar un m\u00e9todo est\u00e1tico <code>getInstance<\/code> para hacer el trabajo.<\/p>\n<p>Aunque no nos ocuparemos de la replicaci\u00f3n hasta m\u00e1s adelante en la gu\u00eda, queremos sentar las bases. El sitio <code>startReplication<\/code> nos permitir\u00e1 definir una sincronizaci\u00f3n bidireccional con una pasarela de sincronizaci\u00f3n y el m\u00e9todo <code>stopReplication<\/code> nos permitir\u00e1 detener la replicaci\u00f3n, quiz\u00e1s cuando se cierre la aplicaci\u00f3n.<\/p>\n<p>Ahora tenemos nuestras funciones para guardar y cargar datos.<\/p>\n<pre><code>\r\npublic Todo save(Todo todo) {\r\n    Map&lt;String, Object&gt; properties = new HashMap&lt;String, Object&gt;();\r\n    Document document = this.database.createDocument();\r\n    properties.put(\"type\", \"todo\");\r\n    properties.put(\"title\", todo.getTitle());\r\n    properties.put(\"description\", todo.getDescription());\r\n    try {\r\n        todo.setDocumentId(document.putProperties(properties).getDocument().getId());\r\n    } catch (Exception e) {\r\n        e.printStackTrace();\r\n    }\r\n    return todo;\r\n}\r\n<\/code><\/pre>\n<p>En el <code>guardar<\/code> aceptamos un m\u00e9todo personalizado <code>Todo<\/code> objeto. Este objeto s\u00f3lo contiene un id, un t\u00edtulo y una descripci\u00f3n. La clase se parece a esto:<\/p>\n<pre><code>\r\npackage com.couchbaselabs;\r\n\r\nimport java.util.*;\r\n\r\npublic class Todo {\r\n\r\n    private String documentId;\r\n    private String title;\r\n    private String description;\r\n\r\n    public Todo(String documentId, String title, String description) {\r\n        this.documentId = documentId;\r\n        this.title = title;\r\n        this.description = description;\r\n    }\r\n\r\n    public Todo(String title, String description) {\r\n        this.documentId = UUID.randomUUID().toString();\r\n        this.title = title;\r\n        this.description = description;\r\n    }\r\n\r\n    public void setDocumentId(String documentId) {\r\n        this.documentId = documentId;\r\n    }\r\n\r\n    public String getDocumentId() {\r\n        return this.documentId;\r\n    }\r\n\r\n    public String getTitle() {\r\n        return this.title;\r\n    }\r\n\r\n    public String getDescription() {\r\n        return this.description;\r\n    }\r\n\r\n}\r\n<\/code><\/pre>\n<p>Esta clase se encuentra en la secci\u00f3n <strong>src\/main\/java\/com\/couchbaselabs\/Todo.java<\/strong> archivo. Lo que estamos haciendo en realidad es tomar el objeto y a\u00f1adirlo como propiedades a un documento NoSQL de Couchbase. Despu\u00e9s de guardar el documento y obtener un id, devolvemos el mismo documento con el id incluido.<\/p>\n<p>La funci\u00f3n de consulta ejecutar\u00e1 la vista que hemos creado anteriormente y a\u00f1adir\u00e1 cada uno de los elementos resultantes a un array de <code>Todo<\/code> poniendo fin a nuestro singleton de base de datos.<\/p>\n<h2>Creaci\u00f3n de una vista para listar datos<\/h2>\n<p>Vamos a crear una aplicaci\u00f3n que utiliza m\u00faltiples vistas Gluon en lugar de tratar de meter todo en la misma vista. Esto no debe confundirse con Couchbase Lite Views que est\u00e1n en el tema de los datos, no UI.<\/p>\n<p>La vista por defecto ser\u00e1 la primera vista que aparezca cuando iniciemos la aplicaci\u00f3n. Esta vista mostrar\u00e1 una lista de todos nuestros elementos de tareas. Si no se utiliza SceneBuilder, el marcado XML que se encuentra en <strong>src\/main\/resources\/com\/couchbaselabs\/views\/primary.fxml<\/strong> tendr\u00eda el siguiente aspecto:<\/p>\n<pre><code>\r\n<!--?xml version=\"1.0\" encoding=\"UTF-8\"?-->\r\n\r\n<!--?import com.gluonhq.charm.glisten.mvc.View?-->\r\n<!--?import javafx.scene.control.ListView?-->\r\n<!--?import javafx.scene.layout.BorderPane?--><\/code><\/pre>\n<p>&nbsp;<\/p>\n<pre><code>\r\n\r\n<\/code><\/pre>\n<p>La vista resultante tendr\u00e1 el siguiente aspecto:<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2016\/october\/using-couchbase-lite-in-a-java-gluon-application\/cb-gluon-desktop-3.png\" \/><\/p>\n<p>Ver\u00e1 en la imagen que hay una barra de navegaci\u00f3n con un bot\u00f3n, pero no aparece en el dise\u00f1o XML. En su lugar, el dise\u00f1o s\u00f3lo contiene la vista de lista. Sin embargo, el XML hace referencia a nuestro <strong>src\/main\/java\/com\/couchbaselabs\/views\/PrimaryPresenter.java<\/strong> archivo. Este es el archivo donde no s\u00f3lo definimos la barra de navegaci\u00f3n, sino cualquier l\u00f3gica que alimente la vista en particular.<\/p>\n<p>En <strong>src\/main\/java\/com\/couchbaselabs\/views\/PrimaryPresenter.java<\/strong> se parecer\u00e1 mucho a nuestro proyecto JavaFX, con las diferencias en el componente de navegaci\u00f3n.<\/p>\n<pre><code>\r\npackage com.couchbaselabs.views;\r\n\r\nimport com.couchbaselabs.CouchbaseSingleton;\r\nimport com.couchbaselabs.Todo;\r\nimport com.couchbase.lite.Database;\r\nimport com.couchbase.lite.Document;\r\nimport com.couchbaselabs.gluon;\r\nimport com.gluonhq.charm.glisten.application.MobileApplication;\r\nimport com.gluonhq.charm.glisten.control.AppBar;\r\nimport com.gluonhq.charm.glisten.mvc.View;\r\nimport com.gluonhq.charm.glisten.visual.MaterialDesignIcon;\r\nimport javafx.application.Platform;\r\nimport javafx.collections.ObservableList;\r\nimport javafx.fxml.FXML;\r\nimport javafx.scene.control.ListCell;\r\nimport javafx.scene.control.ListView;\r\nimport javafx.util.Callback;\r\n\r\npublic class PrimaryPresenter {\r\n\r\n    private CouchbaseSingleton couchbase;\r\n\r\n    @FXML\r\n    private View primary;\r\n\r\n    @FXML\r\n    private ListView fxListView;\r\n\r\n    public void initialize() {\r\n        try {\r\n            this.couchbase = CouchbaseSingleton.getInstance();\r\n            fxListView.getItems().addAll(this.couchbase.query());\r\n            this.couchbase.getDatabase().addChangeListener(new Database.ChangeListener() {\r\n                @Override\r\n                public void changed(Database.ChangeEvent event) {\r\n                    for(int i = 0; i &lt; event.getChanges().size(); i++) {\r\n                        final Document retrievedDocument = couchbase.getDatabase().getDocument(event.getChanges().get(i).getDocumentId());\r\n                        Platform.runLater(new Runnable() {\r\n                            @Override\r\n                            public void run() {\r\n                                int documentIndex = indexOfByDocumentId(retrievedDocument.getId(), fxListView.getItems());\r\n                                for (int j = 0; j &lt; fxListView.getItems().size(); j++) { if (((Todo) fxListView.getItems().get(j)).getDocumentId().equals(retrievedDocument.getId())) { documentIndex = j; break; } } if (retrievedDocument.isDeleted()) { if (documentIndex &gt; -1) {\r\n                                        fxListView.getItems().remove(documentIndex);\r\n                                    }\r\n                                } else {\r\n                                    if (documentIndex == -1) {\r\n                                        fxListView.getItems().add(new Todo(retrievedDocument.getId(), (String) retrievedDocument.getProperty(\"title\"), (String) retrievedDocument.getProperty(\"description\")));\r\n                                    } else {\r\n                                        fxListView.getItems().remove(documentIndex);\r\n                                        fxListView.getItems().add(new Todo(retrievedDocument.getId(), (String) retrievedDocument.getProperty(\"title\"), (String) retrievedDocument.getProperty(\"description\")));\r\n                                    }\r\n                                }\r\n                            }\r\n                        });\r\n                    }\r\n                }\r\n            });\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n        fxListView.setCellFactory(new Callback&lt;ListView, ListCell&gt;() {\r\n            @Override\r\n            public ListCell call(ListView p) {\r\n                ListCell cell = new ListCell() {\r\n                    @Override\r\n                    protected void updateItem(Todo t, boolean bln) {\r\n                        super.updateItem(t, bln);\r\n                        if (t != null) {\r\n                            setText(t.getTitle());\r\n                        }\r\n                    }\r\n                };\r\n                return cell;\r\n            }\r\n        });\r\n        primary.showingProperty().addListener((obs, oldValue, newValue) -&gt; {\r\n            if (newValue) {\r\n                AppBar appBar = MobileApplication.getInstance().getAppBar();\r\n                appBar.setTitleText(\"Couchbase Todo - List\");\r\n                appBar.getActionItems().add(MaterialDesignIcon.ADD.button(e -&gt;\r\n                        MobileApplication.getInstance().switchView(gluon.SECONDARY_VIEW)\r\n                ));\r\n            }\r\n        });\r\n    }\r\n\r\n    private int indexOfByDocumentId(String needle, ObservableList haystack) {\r\n        int result = -1;\r\n        for(int i = 0; i &lt; haystack.size(); i++) {\r\n            if(haystack.get(i).getDocumentId().equals(needle)) {\r\n                result = i;\r\n                break;\r\n            }\r\n        }\r\n        return result;\r\n    }\r\n\r\n}\r\n<\/code><\/pre>\n<p>En el archivo anterior tenemos la propiedad de vista de lista vinculada a la vista de lista real en el XML. Sin embargo, el c\u00f3digo que realmente importa es el que se encuentra en el archivo <code>inicializar<\/code> m\u00e9todo. En \u00e9l hacemos tres cosas fundamentales.<\/p>\n<pre><code>\r\nfxListView.setCellFactory(new Callback&lt;ListView, ListCell&gt;() {\r\n    @Override\r\n    public ListCell call(ListView p) {\r\n        ListCell cell = new ListCell() {\r\n            @Override\r\n            protected void updateItem(Todo t, boolean bln) {\r\n                super.updateItem(t, bln);\r\n                if (t != null) {\r\n                    setText(t.getTitle());\r\n                }\r\n            }\r\n        };\r\n        return cell;\r\n    }\r\n});\r\n<\/code><\/pre>\n<p>En el c\u00f3digo anterior definimos c\u00f3mo aparecer\u00e1n los datos en la lista. Por defecto s\u00f3lo acepta datos de cadena, as\u00ed que lo anulamos para que tome el t\u00edtulo de nuestro <code>Todo<\/code> objetos.<\/p>\n<pre><code>\r\nprimary.showingProperty().addListener((obs, oldValue, newValue) -&gt; {\r\n    if (newValue) {\r\n        AppBar appBar = MobileApplication.getInstance().getAppBar();\r\n        appBar.setTitleText(\"Couchbase Todo - List\");\r\n        appBar.getActionItems().add(MaterialDesignIcon.ADD.button(e -&gt;\r\n                MobileApplication.getInstance().switchView(gluon.SECONDARY_VIEW)\r\n        ));\r\n    }\r\n});\r\n<\/code><\/pre>\n<p>En el listener anterior establecemos el t\u00edtulo de nuestra barra de navegaci\u00f3n as\u00ed como el bot\u00f3n. Cuando se pulse el bot\u00f3n, la vista cambiar\u00e1 a nuestra vista secundaria.<\/p>\n<p>Por \u00faltimo, nos queda ejecutar la consulta inicial de datos y rellenar la lista, as\u00ed como estar atentos a los nuevos datos que vayan llegando. Si llegan cambios, se iterar\u00e1 sobre ellos y se revisar\u00e1n los indicadores en cada documento modificado. Si se ha eliminado un indicador, los datos se borrar\u00e1n de la lista. Si se ha producido un cambio, los datos de la vista de lista se eliminar\u00e1n y, a continuaci\u00f3n, se sustituir\u00e1n. En caso contrario, s\u00f3lo se a\u00f1adir\u00e1n los datos. Dado que el listener opera en un subproceso en segundo plano, los cambios en la interfaz de usuario deben realizarse dentro del subproceso <code>Plataforma.runLater<\/code>.<\/p>\n<p>Esto nos lleva al segundo y \u00faltimo punto de vista.<\/p>\n<h2>Creaci\u00f3n de una vista para guardar datos<\/h2>\n<p>La segunda vista tendr\u00e1 un formulario y ser\u00e1 responsable de que las entradas del usuario se a\u00f1adan a la base de datos y se muestren en la vista anterior. El marcado XML que alimenta esta vista tendr\u00e1 el siguiente aspecto:<\/p>\n<pre><code>\r\n&lt;!--?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?--&gt;\r\n\r\n&lt;!--?import com.gluonhq.charm.glisten.mvc.View?--&gt;\r\n&lt;!--?import javafx.geometry.Insets?--&gt;\r\n&lt;!--?import javafx.scene.control.TextArea?--&gt;\r\n&lt;!--?import javafx.scene.control.TextField?--&gt;\r\n&lt;!--?import javafx.scene.layout.BorderPane?--&gt;\r\n&lt;!--?import javafx.scene.layout.VBox?--&gt;\r\n\r\n\r\n   \r\n      \r\n         \r\n            \r\n            &lt;textarea&gt;         &lt;\/children&gt;\r\n      &lt;\/VBox&gt;\r\n   &lt;\/top&gt;\r\n   &lt;padding&gt;\r\n      &lt;insets bottom=&quot;10.0&quot; left=&quot;10.0&quot; right=&quot;10.0&quot; top=&quot;10.0&quot; \/&gt;\r\n   &lt;\/padding&gt;\r\n&lt;\/View&gt;\r\n&lt;\/code&gt;\r\n&lt;\/pre&gt;\r\n&lt;p&gt;The XML above is found in the &lt;strong&gt;src\/main\/resources\/com\/couchbaselabs\/views\/secondary.fxml&lt;\/strong&gt; file and the view itself looks like the following:&lt;\/p&gt;\r\n&lt;p&gt;&lt;img src=&quot;\/wp-content\/original-assets\/2016\/october\/using-couchbase-lite-in-a-java-gluon-application\/cb-gluon-desktop-4.png&quot; \/&gt;&lt;\/p&gt;\r\n&lt;p&gt;Notice that there are two &lt;code&gt;Campo de texto&lt;\/code&gt; inputs. They will be important in the &lt;strong&gt;src\/main\/java\/com\/couchbaselabs\/views\/SecondaryPresenter.java&lt;\/strong&gt; file referenced in the XML. This file contains the following code:&lt;\/p&gt;\r\n&lt;pre&gt;\r\n&lt;code&gt;\r\npackage com.couchbaselabs.views;\r\n\r\nimport com.couchbaselabs.CouchbaseSingleton;\r\nimport com.couchbaselabs.Todo;\r\nimport com.gluonhq.charm.glisten.animation.BounceInRightTransition;\r\nimport com.gluonhq.charm.glisten.application.MobileApplication;\r\nimport com.gluonhq.charm.glisten.control.AppBar;\r\nimport com.gluonhq.charm.glisten.layout.layer.FloatingActionButton;\r\nimport com.gluonhq.charm.glisten.mvc.View;\r\nimport com.gluonhq.charm.glisten.visual.MaterialDesignIcon;\r\nimport javafx.fxml.FXML;\r\nimport javafx.scene.control.Alert;\r\nimport javafx.scene.control.TextArea;\r\nimport javafx.scene.control.TextField;\r\n\r\npublic class SecondaryPresenter {\r\n\r\n    private CouchbaseSingleton couchbase;\r\n\r\n    @FXML\r\n    private View secondary;\r\n\r\n    @FXML\r\n    private TextField fxTitle;\r\n\r\n    @FXML\r\n    private TextArea fxDescription;\r\n\r\n    public void initialize() {\r\n        this.couchbase = CouchbaseSingleton.getInstance();\r\n        secondary.setShowTransitionFactory(BounceInRightTransition::new);\r\n\r\n        secondary.getLayers().add(new FloatingActionButton(MaterialDesignIcon.SAVE.text,\r\n            e -&gt; save()\r\n        ));\r\n\r\n        secondary.showingProperty().addListener((obs, oldValue, newValue) -&gt; {\r\n            if (newValue) {\r\n                AppBar appBar = MobileApplication.getInstance().getAppBar();\r\n                appBar.setTitleText(&quot;Couchbase Todo - Create&quot;);\r\n            }\r\n        });\r\n    }\r\n\r\n    private void save() {\r\n        if(!fxTitle.getText().equals(&quot;&quot;) &amp;&amp; !fxDescription.getText().equals(&quot;&quot;)) {\r\n            couchbase.save(new Todo(fxTitle.getText(), fxDescription.getText()));\r\n            fxTitle.setText(&quot;&quot;);\r\n            fxDescription.setText(&quot;&quot;);\r\n            MobileApplication.getInstance().switchToPreviousView();\r\n        } else {\r\n            Alert alert = new Alert(Alert.AlertType.INFORMATION);\r\n            alert.setTitle(&quot;Missing Information&quot;);\r\n            alert.setHeaderText(null);\r\n            alert.setContentText(&quot;Both a title and description are required for this example.&quot;);\r\n            alert.showAndWait();\r\n        }\r\n    }\r\n\r\n}\r\n&lt;\/code&gt;\r\n&lt;\/pre&gt;\r\n&lt;p&gt;The input fields are mapped to this controller, but what really matters here is the code for adding the floating action button and setting the navigation bar title.&lt;\/p&gt;\r\n&lt;pre&gt;\r\n&lt;code&gt;\r\nsecondary.getLayers().add(new FloatingActionButton(MaterialDesignIcon.SAVE.text,\r\n    e -&gt; save()\r\n));\r\n\r\nsecondary.showingProperty().addListener((obs, oldValue, newValue) -&gt; {\r\n    if (newValue) {\r\n        AppBar appBar = MobileApplication.getInstance().getAppBar();\r\n        appBar.setTitleText(&quot;Couchbase Todo - Create&quot;);\r\n    }\r\n});\r\n&lt;\/code&gt;\r\n&lt;\/pre&gt;\r\n&lt;p&gt;When the floating action button is clicked, the &lt;code&gt;guardar&lt;\/code&gt; method is called. In the &lt;code&gt;guardar&lt;\/code&gt; method we check to make sure the input fields are not blank and if they aren&#039;t, save the data and navigate backwards in the stack to the previous view.&lt;\/p&gt;\r\n&lt;h2&gt;Syncing Data with Couchbase Sync Gateway&lt;\/h2&gt;\r\n&lt;p&gt;Up until now, every part of our Gluon application was built for offline local use. However, including synchronization support into the mix is not only useful, but incredibly easy.&lt;\/p&gt;\r\n&lt;p&gt;At this point I&#039;m going to assume you&#039;ve downloaded and installed Couchbase Sync Gateway. Before we run it, we need to create a configuration file. Create a JSON file with the following:&lt;\/p&gt;\r\n&lt;pre&gt;\r\n&lt;code&gt;\r\n{\r\n    &quot;log&quot;:[&quot;CRUD+&quot;, &quot;REST+&quot;, &quot;Changes+&quot;, &quot;Attach+&quot;],\r\n    &quot;databases&quot;: {\r\n        &quot;fx-example&quot;: {\r\n            &quot;server&quot;:&quot;walrus:&quot;,\r\n            &quot;sync&quot;:`\r\n                function (doc) {\r\n                    channel (doc.channels);\r\n                }\r\n            `,\r\n            &quot;users&quot;: {\r\n                &quot;GUEST&quot;: {\r\n                    &quot;disabled&quot;: false,\r\n                    &quot;admin_channels&quot;: [&quot;*&quot;]\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n&lt;\/code&gt;\r\n&lt;\/pre&gt;\r\n&lt;p&gt;The above configuration file is one of the most simplest you can make for Sync Gateway. You&#039;re creating a partition called &lt;strong&gt;fx-example&lt;\/strong&gt; within the in-memory database &lt;strong&gt;morsa&lt;\/strong&gt; and you&#039;re accepting all documents from everyone with no read or write permissions.&lt;\/p&gt;\r\n&lt;p&gt;Running this configuration with Sync Gateway won&#039;t get us very far yet because we haven&#039;t activated sync support in our application. Open the project&#039;s &lt;strong&gt;src\/main\/java\/com\/couchbaselabs\/gluon.java&lt;\/strong&gt; e incluya lo siguiente:&lt;\/p&gt;\r\n&lt;pre&gt;\r\n&lt;code&gt;\r\npackage com.couchbaselabs;\r\n\r\nimport com.couchbaselabs.views.PrimaryView;\r\nimport com.couchbaselabs.views.SecondaryView;\r\nimport com.gluonhq.charm.glisten.application.MobileApplication;\r\nimport com.gluonhq.charm.glisten.visual.Swatch;\r\nimport javafx.scene.Scene;\r\n\r\n\r\npublic class gluon extends MobileApplication {\r\n\r\n    public static final String PRIMARY_VIEW = HOME_VIEW;\r\n    public static final String SECONDARY_VIEW = &quot;Secondary View&quot;;\r\n    public CouchbaseSingleton couchbase;\r\n\r\n    @Override\r\n    public void init() {\r\n        addViewFactory(PRIMARY_VIEW, () -&gt; new PrimaryView(PRIMARY_VIEW).getView());\r\n        addViewFactory(SECONDARY_VIEW, () -&gt; new SecondaryView(SECONDARY_VIEW).getView());\r\n    }\r\n\r\n    @Override\r\n    public void postInit(Scene scene) {\r\n        Swatch.BLUE.assignTo(scene);\r\n\r\n        scene.getStylesheets().add(gluon.class.getResource(&quot;style.css&quot;).toExternalForm());\r\n        try {\r\n            this.couchbase = CouchbaseSingleton.getInstance();\r\n            this.couchbase.startReplication(new URL(&quot;https:\/\/localhost:4984\/fx-example\/&quot;), true);\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n\r\n    }\r\n}\r\n&lt;\/code&gt;\r\n&lt;\/pre&gt;\r\n&lt;p&gt;Really we only care about the &lt;code&gt;startReplication&lt;\/code&gt; line in the &lt;code&gt;postInit&lt;\/code&gt; method. Once we call it, replication will happen in both directions, continuously.&lt;\/p&gt;\r\n&lt;h2&gt;Conclusi&oacute;n&lt;\/h2&gt;\r\n&lt;p&gt;You just saw how to create a Java desktop application with Gluon and Couchbase. Using Gradle you can build and run the application and with a few revisions it can be converted to Android as well.&lt;\/p&gt;\r\n&lt;p&gt;The full source code to this project can be found on GitHub &lt;a href=&quot;https:\/\/github.com\/couchbaselabs\/couchbase-lite-gluon-example&quot;&gt;aqu&iacute;&lt;\/a&gt;.&lt;\/p&gt;\r\n&lt;\/textarea&gt;<\/code><\/pre>","protected":false},"excerpt":{"rendered":"<p>I recently wrote about building desktop applications with Couchbase Lite and JavaFX. As demonstrated Couchbase makes an excellent solution for data storage and sync in a desktop application because of the Java SDK available. However, I realize JavaFX is not [&hellip;]<\/p>","protected":false},"author":63,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1810,1818,2366],"tags":[1577],"ppma_author":[9032],"class_list":["post-2402","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-mobile","category-java","category-sync-gateway","tag-cross-platform"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using Couchbase Lite in a Java Gluon Application - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-lite-in-a-java-gluon-application\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using Couchbase Lite in a Java Gluon Application\" \/>\n<meta property=\"og:description\" content=\"I recently wrote about building desktop applications with Couchbase Lite and JavaFX. As demonstrated Couchbase makes an excellent solution for data storage and sync in a desktop application because of the Java SDK available. However, I realize JavaFX is not [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-lite-in-a-java-gluon-application\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/thepolyglotdeveloper\" \/>\n<meta property=\"article:published_time\" content=\"2016-10-04T15:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T02:56:30+00:00\" \/>\n<meta name=\"author\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@nraboy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Using Couchbase Lite in a Java Gluon Application\",\"datePublished\":\"2016-10-04T15:00:00+00:00\",\"dateModified\":\"2025-06-14T02:56:30+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/\"},\"wordCount\":1320,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"cross platform\"],\"articleSection\":[\"Couchbase Mobile\",\"Java\",\"Sync Gateway\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/\",\"name\":\"Using Couchbase Lite in a Java Gluon Application - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2016-10-04T15:00:00+00:00\",\"dateModified\":\"2025-06-14T02:56:30+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using Couchbase Lite in a Java Gluon Application\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\",\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"caption\":\"Nic Raboy, Developer Advocate, Couchbase\"},\"description\":\"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.\",\"sameAs\":[\"https:\/\/www.thepolyglotdeveloper.com\",\"https:\/\/www.facebook.com\/thepolyglotdeveloper\",\"https:\/\/x.com\/nraboy\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/es\/author\/nic-raboy-2\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Using Couchbase Lite in a Java Gluon Application - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-lite-in-a-java-gluon-application\/","og_locale":"es_MX","og_type":"article","og_title":"Using Couchbase Lite in a Java Gluon Application","og_description":"I recently wrote about building desktop applications with Couchbase Lite and JavaFX. As demonstrated Couchbase makes an excellent solution for data storage and sync in a desktop application because of the Java SDK available. However, I realize JavaFX is not [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-lite-in-a-java-gluon-application\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2016-10-04T15:00:00+00:00","article_modified_time":"2025-06-14T02:56:30+00:00","author":"Nic Raboy, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@nraboy","twitter_misc":{"Written by":"Nic Raboy, Developer Advocate, Couchbase","Est. reading time":"16 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Using Couchbase Lite in a Java Gluon Application","datePublished":"2016-10-04T15:00:00+00:00","dateModified":"2025-06-14T02:56:30+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/"},"wordCount":1320,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["cross platform"],"articleSection":["Couchbase Mobile","Java","Sync Gateway"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/","url":"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/","name":"Using Couchbase Lite in a Java Gluon Application - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2016-10-04T15:00:00+00:00","dateModified":"2025-06-14T02:56:30+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-lite-in-a-java-gluon-application\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Using Couchbase Lite in a Java Gluon Application"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"El blog de Couchbase","description":"Couchbase, la base de datos NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1","name":"Nic Raboy, Defensor del Desarrollador, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354","url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","caption":"Nic Raboy, Developer Advocate, Couchbase"},"description":"Nic Raboy es un defensor de las tecnolog\u00edas modernas de desarrollo web y m\u00f3vil. Tiene experiencia en Java, JavaScript, Golang y una variedad de frameworks como Angular, NativeScript y Apache Cordova. Nic escribe sobre sus experiencias de desarrollo relacionadas con hacer el desarrollo web y m\u00f3vil m\u00e1s f\u00e1cil de entender.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/es\/author\/nic-raboy-2\/"}]}},"authors":[{"term_id":9032,"user_id":63,"is_guest":0,"slug":"nic-raboy-2","display_name":"Nic Raboy, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","author_category":"","last_name":"Raboy","first_name":"Nic","job_title":"","user_url":"https:\/\/www.thepolyglotdeveloper.com","description":"Nic Raboy es un defensor de las tecnolog\u00edas modernas de desarrollo web y m\u00f3vil. Tiene experiencia en Java, JavaScript, Golang y una variedad de frameworks como Angular, NativeScript y Apache Cordova. Nic escribe sobre sus experiencias de desarrollo relacionadas con hacer el desarrollo web y m\u00f3vil m\u00e1s f\u00e1cil de entender."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2402","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=2402"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2402\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=2402"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=2402"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=2402"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=2402"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}