Inicio > java, javafx, kodegeek, oracle > Aventuras con JavaFX 1.3 y NetBean 6.9

Aventuras con JavaFX 1.3 y NetBean 6.9

Sábado, 1 de mayo de 2010

Bueno, después de una larga espera Oracle nos trae JavaFX 1.3. El entorno de ejecución promete muchas mejoras, lo único es que el entorno de desarrollo es NetBeans 6.9 BETA.

Si, beta. Tiene una lista de problemas (entre esos la depuración de programas). Sin embargo, si escribo mis ‘unit tests’ debería estar más o menos bien, ¿no es así?

Lo primero que intenté hacer es convertir el método ‘main’ de una de mis clases en Java (no JavaFX) a Junit:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
 * Helper class used to parse and process CVS data comming from an InputStream
 * License: GPL
 * @author josevnz at kodegeek dot com
 */
 
package com.kodegeek.blog.javafx.workout.app;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
 
 
/**
 *
 * @author josevnz
 */
final public class CsvDataParser {
 
private List <list <Object>>data;
private static final Pattern splitPattern = Pattern.compile(",\\s*");
private SimpleDateFormat format;
private Pattern skipNonNumberPatter = Pattern.compile("^\\D+");
 
/**
 * Expected default number of data observations
 */
public static final int DEFAULT_DAY_COUNT = 365;
 
/**
 * Expected default number of series to display on the same chart
 */
public static final int DEFAULT_SERIES = 50;
 
    /**
     * Constructor
     * @param numSeries expected number of series on the stream
     */
    public CsvDataParser(int numSeries) {
 
        /*
         * Ddata is a list of lists where:
         * data(0): List of dates
         * data(n): Values of each series.
         * data is a rectangular array, every value matches a date
         */
        data = new ArrayList</list><list <Object>>();
        List<object> dates = new ArrayList</object><object>();
        data.add(0, dates);
        for (int i = 1; i < numSeries; i++) {
            List<Object> values =
                    new ArrayList</object><object>();
            data.add(i, values);
        }
 
        format = new SimpleDateFormat("MM/dd/yy");
    }
 
    /**
     * Parse a given input stream for data. Not thread safe. It is assumed than
     * the number of tokens on the stream is constant and there
     * are no data holes. The caller is responsible from closing the stream
     * @param io The data source
     * @throws Exception If there is a problem reading the stream
     */
    public void parse(InputStream io) throws Exception {
        BufferedReader lineRdr = new BufferedReader(new InputStreamReader(io));
        String line = null;
 
        try {
 
            while ((line = lineRdr.readLine()) != null) {
 
                if (skipNonNumberPatter.matcher(line).find()) {
                    continue;
                }
 
                String[] tokens = splitPattern.split(line, -1);
                int numSeries = tokens.length;
                if (numSeries ==0 || tokens[0] == null) {
                    return;
                }
 
                if (numSeries != data.size()) {
                    String error = String.format(
                            "Number of expected tokens is %s, got %s",
                            data.size(),
                            numSeries);
                    throw new Exception(error);
                }
 
                // Store dates as numbers, let the caller do any conversions
                List</object><object> dates = (List</object><object>) data.get(0);
                dates.add(format.parse(tokens[0]).getTime());
 
                // Get the values for each series now (rest of the tokens)
                for (int i = 1; i < numSeries; i++) {
                    List<Object> values = (List</object><object>) data.get(i);
                    values.add(Float.parseFloat(tokens[i]));
                }
 
            }
        } catch (Exception exp) {
            throw exp;
        }
 
    }
 
    /**
     * Get the collected data as a List of Lists. First element of the returned
     * list contains the dates as Epoch long dates, after that the series
     * @return Array of dates as epoch long
     */
    public Long [] getDates() {
        return data.get(0).toArray(new Long[0]);
    }
 
    /**
     * Get the values as a list of
     * @param index Valid ranges go from 1 to n
     * @return Array of float series values
     */
    public Float [] getSeriesValues(int index) {
        if (index < 1 || index > data.size()) {
            throw new IllegalArgumentException(
                    String.format("Invalid series index %d", index));
        }
        return data.get(index).toArray(new Float[0]);
    }
 
 
    /**
     * Unit test, show how the parser works on a CSV file. THIS SHOULD BE A
     * JUNIT TEST INSTEAD!!!
     * Program expects the property.
     * @param args List of files to parse. Each one like: numTokens:fullpathFile
     * @throws Exception If there are any problems
     */
    public static void main(final String [] tokens) throws Exception {
        for (String token: tokens) {
            String [] parts = token.split(":", -1);
            InputStream in = null;
            try {
                int nTokens = Integer.parseInt(parts[0]);
                File f = new File(parts[1]);
                if (f.canRead() && f.isFile()) {
                    in = new FileInputStream(f);
                    CsvDataParser instance = new CsvDataParser(nTokens);
                    instance.parse(in);
                    in.close();
                    Long [] dates = instance.getDates();
                    Float [] values = instance.getSeriesValues(1);
                    for (int i = 0; i < dates.length; i++) {
                        System.out.println(
                                String.format("%s -> %s",
                                new Date(dates[i]), values[i]));
                    }
                }
            } catch (NumberFormatException nfe) {
                System.err.println(
                        String.format(
                        "Invalid expected token value: '%s'", parts[0]));
            } catch (Exception exp) {
                throw exp;
            } finally {
                if (in != null) {
                    in.close();
                }
            }
        }
    }
 
}
</object></list>

Sin embargo la interfaz gráfica me abofetea con este error: No tests root folder was found

Que fastidio. No soy un experto en NetBeans (me defiendo mucho más con Eclipse), así que en vez de estar echando código ando resolviendo estos problemas. ¡Que perdida de tiempo!

Me pregunto si Oracle piensa competir en serio con Adobe Flash si su editor principal aún tiene este tipo de problemas.

Amanecerá y veremos, por los momentos ando tratando de resolver el asunto yo mismo, al mismo tiempo pedí ayuda en los foros oficiales. Una vez resuelto, podré correr Junit para JavaFX como lo indica este excelente blog.

java, javafx, kodegeek, oracle

  1. Lunes, 3 de mayo de 2010 a las 15:09 | #1

    Debo decir que no estoy sólo con mi frustración con el nivel de limpieza de JavaFX:

    http://www.theregister.co.uk/2010/02/18/javafx_under_oracle/

    El autor tiene puntos bien validos, entre ellos que Swing (http://java.sun.com/docs/books/tutorial/uiswing/index.html) sufre de una muerte lenta y JavaFX aún no alcanza su pleno potencial.

  1. Sábado, 1 de mayo de 2010 a las 21:33 | #1
  2. Domingo, 6 de junio de 2010 a las 05:01 | #2