Un viaje sobre lenguajes, APIs y otras cosas raras en el mundo del desarrollo de sistemas.

After a very heavy workload here we are to finish (or start) what we begun.

If you remember we made a user interface that had a VBox named as  “vbScores” in that VBox  we’ll put our baseball results. but what we will show?

well let’s make our FXML first:

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

<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<AnchorPane id="AnchorPane" prefHeight="45.0" prefWidth="169.0" styleClass="mainFxmlClass, rootPane" xmlns:fx="http://javafx.com/fxml" fx:controller="com.beisbolicos.scoreboard.GameResultController">
  <children>
    <GridPane AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
      <children>
        <Label fx:id="eVisitante" text="Label" textFill="#e0ff66" GridPane.columnIndex="0" GridPane.rowIndex="0">
          <font>
            <Font name="Verdana Bold" size="12.0" fx:id="x1" />
          </font>
        </Label>
        <Label fx:id="eLocal" font="$x1" text="Label" textFill="#52ff00" GridPane.columnIndex="0" GridPane.rowIndex="2" />
        <Label fx:id="cVisitante" text="Label" textFill="WHITE" GridPane.columnIndex="1" GridPane.rowIndex="0" />
        <Label fx:id="cLocal" text="Label" textFill="WHITE" GridPane.columnIndex="1" GridPane.rowIndex="2" />
        <Label id="lInning" fx:id="lInning" text="Label" textFill="#ff3d00" GridPane.columnIndex="2" GridPane.rowIndex="0">
          <font>
            <Font name="System Bold" size="12.0" fx:id="x2" />
          </font>
        </Label>
        <Label fx:id="lStatus" font="$x2" graphicTextGap="0.0" text="Label" textFill="#33ffe7" GridPane.columnIndex="0" GridPane.rowIndex="3">
          <GridPane.margin>
            <Insets fx:id="x3" />
          </GridPane.margin>
        </Label>
        <ImageView fitHeight="30.0" fitWidth="50.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="2" GridPane.halignment="LEFT" GridPane.hgrow="NEVER" GridPane.margin="$x3" GridPane.rowIndex="1" GridPane.rowSpan="2" GridPane.valignment="TOP" GridPane.vgrow="NEVER" />
      </children>
      <columnConstraints>
        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        <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>
    </GridPane>
  </children>
  <stylesheets>
    <URL value="@scoreboard.css" />
  </stylesheets>
</AnchorPane>


As you can see we will put the game’s local team name and runs, visitor’s name and run and one state and one graphic for the on bases runners.

Now it’s time to connect to the WebService that will provide the data, we will make this from out initial FXML controller, that is the ScoreboardController class and we will read something like:

package com.beisbolicos.scoreboard;
import com.delunasaenz.scoreboardWS.Game;
import com.delunasaenz.scoreboardWS.ScoreboardWS;
import com.delunasaenz.scoreboardWS.ScoreboardWSService;
import java.io.IOException;import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javax.annotation.Resource;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class ScoreBoardController implements Initializable {
    public ScoreboardWSService service;
    @FXML
    private ChoiceBox leagueSelection;
    @FXML
    private VBox vbScores;
    @FXML
    private void handleButtonAction(ActionEvent event) {
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        URL wsdlLocation = null;
        try {
            wsdlLocation = new URL("http://localhost:8080/"
                    + "ScoreboardApp/ScoreboardWSService?wsdl");
        } catch (MalformedURLException ex) {
            Logger.getLogger(ScoreBoardController.class.getName()).log(Level.SEVERE, null, ex);
        }
        service = new ScoreboardWSService(wsdlLocation,
                new QName("http://scoreboard.delunasaenz.com/", "ScoreboardWSService"));
        leagueSelection.getSelectionModel().select(0);
        leagueSelection.getSelectionModel().selectedIndexProperty()
                .addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> ov,
                    Number t, Number t1) {
                actualizaLista(t1);
            }
        });
        actualizaLista(new Integer(0));
    }
    private void actualizaLista(Number t1) {
        ScoreboardWS port = service.getScoreboardWSPort();
        String liga;
        switch (t1.intValue()) { 
           case 0:
                liga = "MEX";
                break;
            case 1:
                liga = "LMP";
                break;
            case 2:
                liga = "MLB";
                break;
            case 3:
                liga = "SC";
                break;
            default:
                liga = "MEX";
                break;
        }
        List<Game> result = port.league(liga);
        vbScores.getChildren().clear();
        for (Game item : result) {
            FXMLLoader fxml = new FXMLLoader(getClass()
                        .getResource("/com/beisbolicos/scoreboard/GameResult.fxml"));
            try {
                fxml.load();
                GameResultController grc = fxml.getController();
                vbScores.getChildren().add((Node) fxml.getRoot());
                grc.setGame(item);
            } catch (IOException ex) {
                Logger.getLogger(ScoreBoardController.class.getName()).
                        log(Level.SEVERE, null, ex);
            }
        }
    }
}

And now the explanation.

if you have used Web Services from servlets or JSP you will find that  @WebServiceRef(wsdlLocation = “http://localhost:8080/ScoreboardApp/ScoreboardWSService?wsdl&#8221;) is missing, that is because the Service reference for our webservice client (service variable), that is because that annotation only works inside a Webserver container and a JavaFX is not running on the server side, but the client side, then we need to start our WS client using the constructor of the client using the wsdlLocation, new QName(“http://scoreboard.delunasaenz.com/&#8221;, “ScoreboardWSService”) as the parameters to start it.

On the initialize method we add a listener to the leagueSelection ChoiceBox making the VBox to be filled with the current games on the league selected, the leagues are obtained thanks to web service we defined.

I hope this can get you a good brief explanation on how to start and use a WebService from a FXML/JavaFX application.

Stop the press… xD

I’ve been working hard with a project that uses a lot of text data in a TableView, usually the tableviews uses about 8 columns for each row and can be more than 100000 rows on a “bad user search”…

the problem with this is that TableView use to “paint” (outside the screen) all the cells involved (above) the line that has to be presented when you use the scroolTo(int) function, so with tables like the one i described the response can became veeeery slooow…

after making a research i wrote a “work around” for those tables with the same height on all the rows:

package my.good.stuff.package.utils;

import com.sun.javafx.scene.control.skin.TableViewSkin;
import com.sun.javafx.scene.control.skin.VirtualContainerBase;
import com.sun.javafx.scene.control.skin.VirtualFlow;
import javafx.scene.Node;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.TableView;

/**
* @author charly
*/
public class MyVeryGoodTableView extends TableView
{
protected double rowHeight;
@Override
public void scrollTo(int registro){
TableViewSkin skin = (TableViewSkin)getSkin();
VirtualFlow vf = null;
for(Node node : skin.getChildren()){
if(node instanceof VirtualFlow){
vf = (VirtualFlow)node;
}
}
ScrollBar bar=null;
for(Node node : vf.getChildrenUnmodifiable()){
if(node instanceof ScrollBar){
bar=(ScrollBar)node;
if(Orientation.VERTICAL== bar.getOrientation()){
bar.valueProperty().set((double)(
((double)registro/(double)(getItems().size()-1))
*bar.getMax()));
}
}
}
}

public double getRowHeight() {
return rowHeight;
}

public void setRowHeight(double rowHeight) {
this.rowHeight = rowHeight;
}

}

Hope this works for you… after this we will continue with the JavaFX tutorial…  xD

La reusabilidad viene en varios sabores, el peor de ellos es el copy/paste o el mueve_este_archivo_y_vuelvelo_a_usar, y el mejor de los sabores es el usa_este_modulo. Para obtener este último sabor se debe considerar cuantos proyectos (módulos) debe tener uno. Yo recomiendo por lo menos 2 (aún cuando uno programa algo tan sencillo como un “casi Hola Mundo”), uno para la capa de presentación (Vista y controladores con un “cliente del modelo”) y otro con el Modelo, que incluye la Lógia  de Megocios y los DAOs

Normalmente se necesitará una Façade -Una Façade (o Fachada) es un objeto que recibe peticiones (en este caso para CUALQUIERA de los “métodos” de la Lógica de Negocios) y los redirige al objeto correcto que puede resolver dicha petición (En este caso un Objeto de Lógica de Negocios) y puede ser publicada despues como un Web Service o usado por cualquier otra capa de presentación como JSP/JSF-. Asi pues, si uno quiere “aislar” la Façade en un proyecto nuevo para poder ser reutilizado por otro proyecto similar definitivamente tendría que ser otro módulo o proyecto (piensen en un banco que tiene diferentes políticas de impuestos dependiente del sistema y el país donde se acceda al sistema; cada sistema y país tendrían sus propios objetos de negocio de acuerdo a las especificaciones de la Fachada).

Generalmente cuando uno habla de modularidad encontramos buenas razones para hacer más y más módulos cada vez, les recomiendo leer el refcard   http://refcardz.dzone.com/refcardz/patterns-modular-architecture.

La siguiente entrada será sobre un diseño de UI basado en un escenario complejo de manera que podamos utilizar FXML y sus controlers, debo disculparme por estas dos partes de introducción “teóricas”  que habla principalmente de patrones.

Saludos y hasta la siguiente.

¿Do you like baseball? Well, may be not as much as i do…  I have a site that is all about baseball, news, results, world baseball classic, mexican baseball, major leagues, etc… inside that site there is a plugin made in Adobe Flash…

Recently i talked with a group of designers and they made me a new design for the complete site… but one of the things to change is that applet.. and guess what!!! even when i have not the code to that applet i will made a JavaFX app to change it, what about doing it togheter?

To start i discovered that the applet reads a XML file with the information of several leagues (winter leagues, for today’s results), so in order to have more than just the “Mexican Pacific league” and have more audience for that applet let’s make a “multi-league” scoreboard.

To start let’s supposed that the part to read the file with the “live” results is done and that we have a class (let’s called that class ResultsFacade) that does all that., so our main goal is to design the front end in a very little space.

To do that we will make our “applet/application” for about 300pix width and 400 pix height.

Before begin let’s understand a little bit of JavaFX, FXML and how do they make great apps.

First af all, JavaFX is an API, used to create User Interfaces that will run on a JVM, usually you will want to write those UIs in Java or any other language compatible wih Java 7. You can think in JavaFX as the sucesor of swing, a good API reborned and rewritten inorder to help you to have more tools to create and develop great applications and to let the graphical designers to do their job without having to learn Java or any programming language (maybe HTML and JavaScript can be a usefull reference).

FXML is a language based on XML to design the UI and conect it to a controller Java class, that is you can develop an XML file to “draw” your UI and a .java to make it work.

Once you have this in mind try to imagine our scoreboard.

Imagen

well… if you look at it everything is “anchored” in a “Pane”, so the main UIControl will be a “AnchorPane”, after that we will be “adding” more controls one below the others until we reach our logo, so we will have a “Vertical Box” inside our Anchor pane and so on… what about something like this:

<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200.0" prefWidth="320.0" xmlns:fx="http://javafx.com/fxml" fx:controller="com.beisbolicos.scoreboard.ScoreBoardController">
  <children>
    <VBox AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
      <children>
        <ChoiceBox>
          <items>
            <FXCollections fx:factory="observableArrayList">
              <String fx:value="Item 1" />
              <String fx:value="Item 2" />
              <String fx:value="Item 3" />
            </FXCollections>
          </items>
        </ChoiceBox>
        <ScrollPane prefHeight="200.0" prefWidth="200.0">
          <content>
            <VBox prefHeight="150.0" prefWidth="200.0" />
          </content>
        </ScrollPane>
        <ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
      </children>
    </VBox>
  </children>
</AnchorPane>

If we check line per line we will have:

<?xml version=”1.0″ encoding=”UTF-8″?>
Just to say that is an XML file
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>

All of them to import the needed objects to make our UI:

<AnchorPane id="AnchorPane" prefHeight="200.0" prefWidth="320.0"
            xmlns:fx="http://javafx.com/fxml"
            fx:controller="com.beisbolicos.scoreboard.ScoreBoardController">
  <children>

This will put an Achor pane (a pane that will grow or shrink within the space the parent (our Stage -applet or window-) will left for it. it will have an id (used for CSS) called “AnchorPane” and the controller will be our Java class, as part of the attributes are the children that will populate the UI inside the AnchorPane:

    <VBox AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">

The VBox is a pane that will be populated adding any new child on the bottom of the already existing children

<ChoiceBox>
          <items>
            <FXCollections fx:factory="observableArrayList">
              <String fx:value="Item 1" />
              <String fx:value="Item 2" />
              <String fx:value="Item 3" />
            </FXCollections>
          </items>
        </ChoiceBox>

A ChoiceBox is like a “closed” Combo box (that is you will not be able to “write” a new value being the user, and the Items are inside a Collections (yes, a new kind of List that we have been using in Java Generics), the values are given (in this case) by Strings.

After it we will put a scroll bar to have all the live results that will be aded via programming, and they will be added vertically inside a VBox.

After that there will be our logo.

If you want to “manipullate any of the controls you will need to name them with the fx:id attribute, so… since you will need to know what league is choosed and you will want to add scores to the scoreboard space inside the applet you must name them and the final FXML will look like:

<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane"
            prefHeight="200.0"
            prefWidth="320.0"
            xmlns:fx="http://javafx.com/fxml"
            fx:controller="com.beisbolicos.scoreboard.ScoreBoardController">
  <children>
    <VBox AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0"
          AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
      <children>
        <ChoiceBox fx:id="cbxLeague">
          <items>
            <FXCollections fx:factory="observableArrayList">
              <String fx:value="Item 1" />
              <String fx:value="Item 2" />
              <String fx:value="Item 3" />
            </FXCollections>
          </items>
        </ChoiceBox>
        <ScrollPane prefHeight="200.0" prefWidth="200.0">
          <content>
            <VBox  fx:id="vbScores" prefHeight="150.0" prefWidth="200.0" />
          </content>
        </ScrollPane>
        <ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
      </children>
    </VBox>
  </children>
</AnchorPane>


In the next entry (later this week) we will customize the colors using CSS and we will populate the data inside our applet.
Hope you enjoy this first look on the actual JavaFX front-end code.

Re usability comes in too many flavors, the worst flavor is the copy/paste or move_that_file_and_use_it_again, and the best flavor is the use_this_already_made_module. To achieve the last flavor we must consider how many projects (or modules) our program will have. I recommend at least 2 (even if your program is “almost a Hello World”), one for the presentation layer (Views and Controllers with one “model client”) and other with my Model that will include the Business Logic objects and the DAOs.

I usually made a Façade -A Façade is an object that receives requests (in this case for ANY Business Logic “method”) and redirects it to the right object to resolve it (in this case a Business Logic Object)- that can be published later as a Web Service or used for any other kind of presentation layer (such JSP).

So, if you want to “isolate” the Façade in a new project in order to reuse it with any other similar project, that would be another module or project (think in a bank with different taxing politics according to the country and the system, you could make a single Façade that can be used on those different countries that will have to implement their own Business Logic objects according to the Façade specs).

Usually when talking about modularity we will find some good reasons to make more and more modules at the time, i recommend you to read the “Patterns of Modularity Architecture” refcard.

The next post will talk on our UI Design based on a real complex scenario in order to start using FXML files and controllers, for now i must apologize for all this “teorical” 2 parts introduction that talks mainly on patterns.

Greetings and see u next week.

I have some time using JavaFX already and i love it.

The best configuration (at this point) for you to use JavaFX  is simple to install and use. Here you will  find tips on how to make a complex (or simple) JavaFX program and how to generate the needed packages to have a clean and easy to maintain and understand project.

To start you must install NetBeans 7.2 -with glassfish- (or later if you are seeing this view after a new version is released), Java 7 (necessarily because there are a lot of improvements on the language and JavaFX is part of it now) and Scene Builder (last version).

You must think on your Jar modules to be grouped with the needed granularity based on your business logic and also as a MVC solution (Model – View – Controller).

On JavaFX the model will be our “Domain Model” (that is the model that represents our reality on the world translated to java objects, usually known as business logic and DAO) and it will bring the necessarily data to our controller to make the view  right interaction with the user. That is, for practical purposes, we should see three different “strong” layers on our program: the one that “paints” the object on the screen (View), the one that fills them with information (controller) and the one that process the data and obtains the information (Model).

If you are used to use Java (or simple Design) Patterns you will want to generate TO (or DTOs) to transfer the data between layers. A TO is, finally by definition, a plain object (POJO – plain object Java Object) that has only the attributes and the getters /setters – NOTHING ELSE -.

The Models will search for the data using DAOs (Data Access Objects) that will be done JUST TO access the databases or information containers, the must be the only objects with the capacity to reach the data repositories and the MUST NO to manipulate the content of the data, the just obtain the data and put it on the TO to be used by the business logic objects that will transform them and will take the right decisions.

Our View in JavaFX is, as a suggestion, given by FXML files that are a variety of XML files defining the User Interface and that will delegate the controllers the required actions to interact with the user when he uses any component.

The controller will decide how the view will behave and how it will be communicate with our business Model according with the needs of this model, for example:

FXML  file:

<Button fx:id=”myButton” onAction=”#doSomething” text=”do something”/>

Controller.java file:

private void doSomething(ActionEvent evt){
   // Code to execute when the users clicks the button....

}

That’s the way our controller will use (inside the “Code to execute when the users clicks the button….”) the business model that we have done.

Once we have understand this we will just mention that for the examples to come we will use Spring Framework version 3.0 in the DAOs interfaces and that this is not intended to be a JavaFX tutorial but a general terms vision with tips on how to reach an agile application that will integrate the benefits of the framework (JavaFX)

Greetings and wait for the next post, next week.

Tengo ya un tiempo usando JavaFx y estoy fascinado.

La configuración (en este momento) ideal para que usen JavaFx es sencilla de instalar y de usar, aquí mostraremos poco a poco como es que se establece un programa de JavaFX y como es que debemos generar los paquetes necesarios para llevar un proyecto limpio y fácil de entender.

En principio debemos instalar NetBeans 7.2 -con Glassfish- (o posterior en el caso de que la entrada ya sea muy vieja o haya salido una nueva actualización por parte de oracle), Java 7 (imprescindible por una serie de mejoras del lenguaje, además de que JavaFX ya forma parte integral de esta versión) y Scene Builder (la última versión existente.

Se sugiere hagan módulos de los Jars que contendrán su programa de una manera tan dispersa como se requiera, sobre todo en la parte de la lógica de negocio y también que se preparen para estar pensando todo en una solución basada en un MVC (Modelo-Vista-Controlador).

En el caso de JavaFX el Modelo seguirá siendo nuestro Modelo de dominio, abastecido principalmente por nuestras clases de negocio y que abastecerá idealmente a nuestro controlador, el cual hará que la vista interactúe correctamente con nuestro usuario.  Es decir para fines prácticos debemos ver como tres capas “fuertes” nuestro programa: el que pinta los objetos que el usuario va a utilizar, la que los llena y la que consigue los datos.

Si ustedes son apegados al uso de patrones de Java seguramente querran generar TO (o DTOs) para transferir los datos entre las diferentes capas. Un TO es, a  final de cuentas por definición, un objeto plano de Java (POJO) que sólo contiene atributos con sus getters y sus setters -NADA MÁS-.

Los Modelos de dominio buscarán los datos seguramente mediante DAOs (Data Access Objets) que serán objetos hechos únicamente para el acceso a las Bases de Datoso contenedores de información, estos objetos deben ser los únicos capaces de tener acceso a estos repositorios y NO deben manipular el contenido de estos datos, simplemente obtienen los datos necesarios y los “depositan” en TOs para que los objetos de negocio los transformen y tomen las decisiones que sean necesarias.

Nuestra vista en JavaFX es, sugerentemente, dada por archivos FXML que son archivos de XML que definen la interfaz gráfica y que delegan a los Controladores las acciones a realizar cuando el usuario haga uso de cada uno de los componentes de nuestra Interfaz de Usuario (UI).

El controlador pues decide como se comportará la vista y se comunicará con nuestro Modelo de Negocio de acuerdo a las necesidades de este, por ejemplo:

archivo en FXML:

<Button fx:id="miBoton" onAction="#hazAlgo" text="haz algo"/>

en el archivo Controller.java

private void hazAlgo(ActionEvent evt){
   // Código que se ejecutará al dar click al botón
   ....

}

Así pues nuestro controlador hará uso del modelaje de negocio que hayamos hecho.

Una vez entendido esto sólo agregaremos que para los ejemplos que empezaremos a postear haremos uso de Spring 3.0 en la parte de los DAOs y que esto más que ser un tutorial sobre JavaFX será una visión a su utilización en términos generales con tips sobre como lograr una aplicación ágil y que integre las ventajas del framework.

Saludos y esperen la siguiente parte esta misma semana.

Después de escribir todo esto resulta que Microsoft ha empezado a definir un poco mejor su política, aunque Silverlight en escencia es un WPF recortad/ampliado/modificado (por lo cual muchas de las cosas explicadas en este BLOG siguen siendo válidas para SL) la decisión es, aparentemente ir matando lentamente a WPF para dejar a Silverlight, que "algún dia" tendra presencia en Mac y linux con sus "últimas" versiones.
Alguno de los contras con que SL se maneja tienen que ver con su interacción hacia WCFque no permite la generación de comunicación síncrina, toda la comunicación hacia el servidor debe ser asíncrona y en algunos casos eso implica que el desarrollador debe cambiar una gran parte de su código a la basura. Esto, dice MS, no es por que no quieran dar menos flexibilidad… es para proteger la interfaz de usuario de un probable congelamiento en el uso de las comunicaciones cuando este sea inadecuado.
Por su parte Java ha sacado lo que yo he llamado "Swing 2.0 para web" que en el argot de sistemas es "Java FX", sin embargo no creo que en el mediano plazo SL o JavaFX puedan sobrevivir si no empiezan a cuestionarse ampliamente el soporte que deben dar a dispositivos moviles. SL ya lo hace hacia los que tengan Windows Mobile y JavaFX seguramente podrá hacerlo con quienes tengan Java ME, pero el desafio real proviene de 2 actores que están entrando al mercado con mucha más fuerza de la que quisieran muchos: Google y Apple con la gran batalla de las tabletas, cada uno con sus sistemas operativos Android e iOS.
Así pues a partir de hoy trataremos de dar un giro a este blog para tratar de establecer como es la mejor manera de cubrir este mercado aplicativo que seguramente traerá muchos cambios en la industria ya que nos presenta un cambio de paradigma apenas equivalente al que se dio en la transición de los mainframes a las PC, mercado que por lo menos tendrá unos 10 o 15 años más de vida, pero que si buscamos una carrera más larga en este circuito tendremos que empezar a establecer como cambiaran tantolos clientes como los servidores en este plazo.
Saludos y prometo actividad en este blog informático.

ahora
que ya sabemos que usandlo la etiqueta local haremos referencia a nuestro
namespace (paquete en Java) tenemos que definir la etiqueta referente a nuestro
control de usuario:

           
<Canvas Grid.Column="0" Grid.Row="0">

                   
<local:MensajesGenerales x:Name="ventanaEmergente"

                                       
 
Visibility="Hidden" Canvas.Left="83" Canvas.Top="0" Height="180" Width="437"/>

               
</Canvas>

Observese que nuestro control lo estamos poniendo dentro de un canvas, esto es
por que si lo hacemos dentro de un Grid este no dejará que el código funcione
correctamente, esto lo notaremos en el siguiente paso, generar el código de
nuestro control para poder darle la funcionalidad de movimiento y de que el
botón "cierre" nuestra ventana emergente, para utilizar nuestra
ventana basta con poner un botón y cambiarle el valor de la propiedad
Visibility a "Visible" (En SilverLight Visibility solo puede tener
los valores de Collapsed y Visible, Hidden no existe).

Regresando a nuestro control el código debe verse algo como:

using System;

using System.Collections.Generic;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using
System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

 

namespace
mx.gob.scjn.ius_common.gui.apoyos

{

    /// <summary>

    /// Interaction logic for MensajesGenerales.xaml

    /// </summary>

    public partial class MensajesGenerales : UserControl

    {

        private
Point inicioDrag;

        private
Point ofsetDrag;

 

        public
MensajesGenerales()

        {

           
InitializeComponent();

        }

 

        private
void salir_MouseLeftButtonUp(object sender, RoutedEventArgs
e)

        {

            this.Visibility = Visibility.Hidden;

        }

 

        private
void BarraMovimiento_MouseLeftButtonDown(object sender, MouseButtonEventArgs
e)

        {

           
ofsetDrag = e.GetPosition(this);

            if ((inicioDrag.X == -1) && (inicioDrag.Y ==
-1))

            {

               
inicioDrag = e.GetPosition(Parent as Canvas);

               
this.BarraMovimiento.CaptureMouse();

            }

 

        }

 

        private
void BarraMovimiento_MouseLeftButtonUp(object sender, MouseButtonEventArgs
e)

        {

           
inicioDrag.X = -1;

           
inicioDrag.Y = -1;

           
BarraMovimiento.ReleaseMouseCapture();

 

       
}

 

        private
void BarraMovimiento_MouseMove(object sender, MouseEventArgs
e)

        {

            if ((e.LeftButton == MouseButtonState.Pressed)
&& (BarraMovimiento.IsMouseCaptured))

            {

               
Point puntoActual = e.GetPosition(Parent as Canvas);

               
puntoActual.X -= ofsetDrag.X;

               
puntoActual.Y -= ofsetDrag.Y;

               
Canvas.SetTop(this,
puntoActual.Y);

               
Canvas.SetLeft(this,
puntoActual.X);

            }

           
else

           
{

               
inicioDrag.X = -1;

               
inicioDrag.Y = -1;

           
}

 

       
}

    }

}

 

Como
se puede ver el botón lo único que hará en realidad es esconder nuestro
control, mientras que las funciones definidas en nuestro rectángulo permitirán
la simulación de arrastrar y soltar de nuestra ventana alterando los valores de
Canvas.Top y Canvas.Left, es precisamente por eso que el control no funcionará
en un Grid y por lo que debe ponerse en un Canvas (que sí puede esar dentro de
un Grid).

Espero que esto les sea de mucha utilidad para su applet…. perdon.. XBAP

 

Ahora revisemos parte por parte:
<UserControl.Resources>

       
<ResourceDictionary>

           
<ResourceDictionary.MergedDictionaries>

               
<ResourceDictionary Source="/General;component/Resources.xaml"/>

           
</ResourceDictionary.MergedDictionaries>

        </ResourceDictionary>

    </UserControl.Resources>

       
<Border Name="degradado"  Style="{StaticResource BorderStyle}">

En esta parte definimos que se va a utilizar un archivo de
recursos dentro del assembly (jar en Java) General y que se llama
Resources.xaml (este funciona un poco como hoja de estilos…
En el objeto Border estamos definiéndole un nombre y le decimos que use un
estilo llamado BorderStyle, este está definido en Resources.XAML y es el
siguiente:

<Style TargetType="{x:Type Border}" x:Key="BorderStyle">

       
<Setter Property="Background">

           
<Setter.Value>

               
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

                   
<GradientStop Color="#E4F1C9" Offset="0"/>

                   
<GradientStop Color="#F0F7E1" Offset="1"/>

               
</LinearGradientBrush>

           
</Setter.Value>

        </Setter>       

    </Style>

En esto andamos definiendo que nuestro fondo tendrá un degradado de dos tonos
de verde.

Siguiendo con nuestro control de usuario tenemos que pusimos una etiqueta de
título y un campo de texto rico para dar un mensaje grande y posiblemente con
fotos o cambios de colores de texto.
Lo que nos interesa para la parte de ventana emergente es lo siguiente:

<Button Height="40"

                  
 
HorizontalAlignment="Right"

                  
 Margin="0,0,0,0"

                  
 Name="salir"

          
         ToolTip="Cerrar"

                  
 VerticalAlignment="Top"

                  
 Width="40"

                  
 Template="{StaticResource
RegresarBoton
}"

                  
 Click="salir_MouseLeftButtonUp"/>

           
<Rectangle Height="11" Cursor="ScrollAll"

                
      Margin="-1,-1,38,0" Name="BarraMovimiento"

                     
 Stroke="Black" VerticalAlignment="Top"

                     
 MouseLeftButtonDown="BarraMovimiento_MouseLeftButtonDown"

                     
 MouseLeftButtonUp="BarraMovimiento_MouseLeftButtonUp"

                     
 MouseMove="BarraMovimiento_MouseMove">

               
<Rectangle.Fill>

                   
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

                       
<GradientStop Color="LightGray" Offset="0"/>

  
                     
<GradientStop Color="SeaGreen" Offset="0.5"/>

                       
<GradientStop Color="LightGray" Offset="1.0"/>

                   
</LinearGradientBrush>

               
</Rectangle.Fill>

           
</Rectangle>

El botón tiene otro elemento definido como estático y que se encuentra definido
en el archivo de recursos:

<ControlTemplate x:Key="RegresarBoton" TargetType="Button">

       
<Image x:Name="ImagenRegresar" Source="/General;component/images/REGRESAR1.png"/>

       
<ControlTemplate.Triggers>

       
<Trigger Property="IsMouseOver" Value="True">

           
<Setter TargetName="ImagenRegresar" Property="Source" Value="/General;component/images/REGRESAR2.png"/>

       
</Trigger>

           
</ControlTemplate.Triggers>

    </ControlTemplate>

Lo que se entá definiendo en este template es que cuando uno pase el mouse
sobre el botón para cerrar nuestra ventana emergente este debe cambiar de
imagen.
El rectángulo es el que hace las veces de barra de título de una ventana, en
este caso lo llenamos con un degradado para dar la impresión de que
efectivamente es un elemento para cambiar la ventana de posición, al decir que
el cursor es de tipo "ScrollAll" definimos que estará en una cruz de
flechas, lo que indicará el objetivo del rectángulo.
Una vez definido lo gráfico veamos como debemos hacer para utilizar nuestra
ventana emergente y como funciona internamente:
Para insertarla dentro de nuestro "Page" debemos hacer lo siguiente:
Definir que vamos a usar el namespace dentro de la página:

<Page x:Class="IUS.Tesis" Loaded="Page_Loaded"

      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;

      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;

      xmlns:local="clr-namespace:mx.gob.scjn.ius_common.gui.apoyos"

      xmlns:utilities="clr-namespace:mx.gob.scjn.ius_common.gui.gui.utilities;assembly=General"

      MinWidth="770">

Adivinaron, no puedo poner mucho texto en la entrada del BLOG!!! seguiremos en la parte 3.

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.