JTable Print

Posted by 小权 @ 技术生活 No Comments »

这几天在做关于JTable的打印工作,项目中客户需要直接将JTable打印出来,之前这方面工作做的比较少,经过这几天的研究,稍微有些积累,现在分享一下。

JTable打印目前用的比较多的还是JasperReport来实现的,JasperReport开源免费,但是不是特别好用,这也是为什么JasperReport免费用,但是培训是收费的。

不过常用的一些JTable的打印实现起来也还好了,只是复杂的稍微有些麻烦,可以看看我之前介绍的一篇入门文章:JasperReport 个人使用的一些经验

这里主要分享的是通过Swing 打印的积累,JasperReport常用的简单的打印没问题,但是遇上比较复杂的表单,比如合成表头等,就稍微有点麻烦,当然也有可能是自己没有找到JasperReport的处理方法,要是有朋友知道欢迎分享下。

通过Swing来绘制,应该是无奈的一步,不过通过这无奈的一步,和同事的帮助下,却学习到了不少这方面的知识,尤其是Swing绘制方面的。

下面的代码是我抽出来的一个比较通用的,基于TableModel的表格打印,普通表头,不带合成表头的,如果Table Model不一样,那么自己就需要改改了。

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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.math.BigDecimal;
import java.text.NumberFormat;
import javax.swing.JTable;
import javax.swing.table.TableModel;
 
/**
 *
 * @author xiaoquan
 */
public class SwingCommonPrinitTools implements Printable {
 
    private TableModel model = null;
    private String info;
    private int totalRow = 0;
    private static final int LEFT = 0;
    private static final int RIGHT = 1;
    private static final int CENTER = 2;
    private static final int AUTO = 3;
 
    public void printTable(TableModel model,
            String info) {
        this.model = model;
        this.info = info;
        totalRow = model.getRowCount();
        PrinterJob printJob = PrinterJob.getPrinterJob();
        printJob.setPrintable(this);
        if (printJob.printDialog()) {
            try {
                printJob.print();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
    private static final double paper_offset_x = 20;
    private static final double paper_offset_y = 20;
    private static final double title_time_margin = 10;
    private static final double time_body_margin = 2;
    private static final double cell_padding_y = 3;
    private static final double cell_padding_x = 2;
    private static final double body_btm_margin = 20;
    private static final double body_cell_height = 20;
    private static final Font title_font = new Font("黑体", Font.PLAIN, 18);
    private static final Font time_font = new Font("Dialog", Font.PLAIN, 10);
    private static final Font body_font = new Font("Dialog", Font.PLAIN, 10);
 
    @Override
    public int print(Graphics g, PageFormat pf, int pageIndex) throws
            PrinterException {
        //纸张宽
        double pageWidth = pf.getImageableWidth();
        //纸张高
        double pageHeight = pf.getImageableHeight();
        //打印的内容起始X
        double pageStartX = pf.getImageableX();
        //打印的内容起始Y
        double pageStartY = pf.getImageableY();
 
        //表头高
        double tableHeadH = 0;
        //Cell高
        double cellH = 0;
 
        //计算表头高度和单元格高度
        g.setFont(body_font);
        FontMetrics cellFm = g.getFontMetrics();
        cellH = cellFm.getHeight() + cell_padding_y * 2 + 1;
        tableHeadH = cellH * 2;
 
        //计算Title以及其位置
        String title = info;
        g.setFont(title_font);
        FontMetrics titleFm = g.getFontMetrics();
        int titleW = titleFm.stringWidth(title);
 
        //表底和表头文字属性
        g.setFont(time_font);
        FontMetrics btmFm = g.getFontMetrics();
        FontMetrics timeFm = g.getFontMetrics();
 
        //表格以上的Margin
        double tableTopMargin = paper_offset_y + titleFm.getHeight() +
                title_time_margin + timeFm.getHeight() + time_body_margin;
 
        //表格每列的最大宽度
        double[] cellColMaxWidths = caculateTableCellWidth(model, cellFm);
 
        //当前Page的数据容量高度-不包括表头和表尾
        double currentPageDataCapacityHeight = pageHeight - tableTopMargin -
                tableHeadH - btmFm.getHeight() - body_btm_margin - 1;
 
        //当前Page的数据容量
        int currentPageBodyCapacityRows = (int) (currentPageDataCapacityHeight /
                cellH);
 
        //Y方向的分页数量
        int pagesY = 0;
        if (model.getRowCount() % currentPageBodyCapacityRows == 0) {
            pagesY = (int) (model.getRowCount() /
                    currentPageBodyCapacityRows);
        } else {
            pagesY = (int) (model.getRowCount() /
                    currentPageBodyCapacityRows) +
                    1;
        }
 
        //当前页数大于总页数时不打印
        if (pageIndex + 1 > pagesY) {
            return NO_SUCH_PAGE;
        }
 
        //绘制Title
        g.setFont(title_font);
        g.drawString(title, (int) (pageStartX +
                (pageWidth - titleW) / 2), (int) (pageStartY +
                paper_offset_y +
                titleFm.getAscent()));
 
        //绘制区域移动到新的(0,0)点
        g.translate((int) (paper_offset_x + pageStartX), (int) (tableTopMargin +
                pageStartY));
        int currentX = 0, currentY = 0;
 
        //绘制第一张表
 
        //绘制表头
        g.setFont(time_font);
        String time = "表头: " + info;
        g.drawString(time, currentX, currentY);
        currentY += 5;
        //绘制单一表头
        for (int i = 0; i 
                totalRow
                ? totalRow
                : (currentPageBodyCapacityRows * (yIndex + 1));
        for (int row = startRow; row < endRow; row++) {
            //绘制单项表头下面的数据
            for (int i = 0; i < model.getColumnCount(); i++) {
                double width = cellColMaxWidths[i];
                double height = body_cell_height;
                Object value = model.getValueAt(row, i);
                drawCell(g, value, currentX, currentY, (int) width,
                        (int) height, AUTO);
                currentX += width;
                rightCellX = currentX;
            }
            currentX = 0;
            currentY += cellH;
        }
 
        //绘制闭合线,下面和右侧两条
        g.drawLine(currentX, currentY, rightCellX, currentY);
        g.drawLine(rightCellX, 5, rightCellX, currentY);
 
        drawBottomInfo(pageIndex, pagesY, currentY, g, (int) pageWidth);
        return PAGE_EXISTS;
    }
 
    private void drawBottomInfo(int pageIndex, int pagesY,
            int currentY, Graphics g, int pageWidth) {
        if (pageIndex + 1 == pagesY) {
            //绘制底部信息
            int btmX = 0;
            int btmY = currentY + 20;
            g.drawString("负责人:", btmX, btmY);
            g.drawString("制表:", pageWidth / 3, btmY);
            FontMetrics fm = g.getFontMetrics();
            int dataWidth = fm.stringWidth("日期: 2009/10/26");
            g.drawString("日期:", pageWidth - dataWidth, btmY);
        }
    }
 
    /**
     * 计算最大列宽
     * @param cellFm
     * @return
     */
    private double[] caculateTableCellWidth(
            TableModel model,
            FontMetrics cellFm) {
        //表格每列的最大宽度
        double[] cellColMaxWidths = new double[model.getColumnCount()];
 
        //计算表头每列最大宽度
        double[] headerColMaxWidths = new double[model.getColumnCount()];
 
        for (int i = 0; i < model.getColumnCount(); i++) {
            String name = model.getColumnName(i);
            headerColMaxWidths[i] = cellFm.stringWidth(name) + cell_padding_x *
                    2 + 1;
        }
        //没有数据时,表头每列的最大宽度就是表格每列的最大宽度
        cellColMaxWidths = headerColMaxWidths;
 
        //算数据每列的最大宽度和表头每列最大宽度对比
        for (int j = 0; j < model.getRowCount(); j++) {
            for (int i = 0; i < model.getColumnCount(); i++) {
                //做些数据类型的判断
                Object value = model.getValueAt(j, i);
                if (value instanceof BigDecimal) {
                    value = ((BigDecimal) value).doubleValue();
                }
                String text = "";
                if (value != null) {
                    text = value.toString();
                }
                double temp = cellFm.stringWidth(text) + cell_padding_x * 2 + 1;
                if (cellColMaxWidths[i] < temp) {
                    cellColMaxWidths[i] = temp;
                }
            }
        }
        return cellColMaxWidths;
    }
 
    /**
     * 绘制单元格及里面的文字
     * @param g
     * @param value
     * @param x
     * @param y
     * @param width
     * @param height
     */
    private static void drawCell(Graphics g, Object value, int x, int y,
            int width,
            int height, int locate) {
 
        g.drawLine(x, y, x + width - 1, y);
        g.drawLine(x, y, x, y + height - 1);
        FontMetrics fm = g.getFontMetrics();
        if (value == null) {
            value = "";
        }
        switch (locate) {
            case 0:
                //居左
                g.drawString(value.toString(), (int) (x + cell_padding_x), y +
                        (height - fm.getHeight()) / 2 + fm.getAscent());
            case 1:
                //居右
                g.drawString(value.toString(),
                        (int) (x +
                        (width - fm.stringWidth(value.toString()) + width -
                        fm.stringWidth(value.toString()) - cell_padding_x) /
                        2), y +
                        (height - fm.getHeight()) / 2 + fm.getAscent());
            case 2:
                //居中
                g.drawString(value.toString(), x + (width - fm.stringWidth(
                        value.toString())) / 2, y + (height -
                        fm.getHeight()) / 2 + fm.getAscent());
            case 3:
                //自动判断
                NumberFormat formatter = NumberFormat.getNumberInstance();
                formatter.setMinimumFractionDigits(2);
                formatter.setMaximumFractionDigits(2);
                //根据数据类型左对齐还是右对齐绘制还是居中对齐
                if (value instanceof BigDecimal) {
                    //居右
                    value = ((BigDecimal) value).doubleValue();
                    value = formatter.format(value);
                    g.drawString(value.toString(),
                            (int) (x +
                            (width - fm.stringWidth(value.toString()) + width -
                            fm.stringWidth(value.toString()) - cell_padding_x) /
                            2), y +
                            (height - fm.getHeight()) / 2 + fm.getAscent());
                } else if (value instanceof Integer || value instanceof Long ||
                        value instanceof Double) {
                    //居右
                    g.drawString(value.toString(),
                            (int) (x +
                            (width - fm.stringWidth(value.toString()) + width -
                            fm.stringWidth(value.toString()) - cell_padding_x) /
                            2), y +
                            (height - fm.getHeight()) / 2 + fm.getAscent());
                } else {
                    //居中
                    g.drawString(value.toString(), x + (width - fm.stringWidth(
                            value.toString())) / 2, y + (height -
                            fm.getHeight()) / 2 + fm.getAscent());
                }
        }
    }
 
    public static void main(String[] args) {
        new SwingCommonPrinitTools().printTable(testData(), "测试");
    }
 
    private static TableModel testData() {
        final Object rows[][] = {
            {"one", "ichi - \u4E00", "Test1", "Test2", "Test3"},
            {"two", "ni - \u4E8C", "Test1", "Test2", "Test3"},
            {"three", "san - \u4E09", "Test1", "Test2", "Test3"},
            {"four", "shi - \u56DB", "Test1", "Test2", "Test3"},
            {"five", "go - \u4E94", "Test1", "Test2", "Test3"},
            {"six", "roku - \u516D", "Test1", "Test2", "Test3"},
            {"seven", "shichi - \u4E03", "Test1", "Test2", "Test3"},
            {"eight", "hachi - \u516B", "Test1", "Test2", "Test3"},
            {"nine", "kyu - \u4E5D", "Test1", "Test2", "Test3"},
            {"ten", "ju - \u5341", "Test1", "Test2", "Test3"},
            {"one", "ichi - \u4E00", "Test1", "Test2", "Test3"},
            {"two", "ni - \u4E8C", "Test1", "Test2", "Test3"},
            {"three", "san - \u4E09", "Test1", "Test2", "Test3"},
            {"four", "shi - \u56DB", "Test1", "Test2", "Test3"},
            {"five", "go - \u4E94", "Test1", "Test2", "Test3"},
            {"six", "roku - \u516D", "Test1", "Test2", "Test3"},
            {"seven", "shichi - \u4E03", "Test1", "Test2", "Test3"},
            {"eight", "hachi - \u516B", "Test1", "Test2", "Test3"},
            {"nine", "kyu - \u4E5D", "Test1", "Test2", "Test3"},
            {"ten", "ju - \u5341", "Test1", "Test2", "Test3"},
            {"one", "ichi - \u4E00", "Test1", "Test2", "Test3"},
            {"two", "ni - \u4E8C", "Test1", "Test2", "Test3"},
            {"three", "san - \u4E09", "Test1", "Test2", "Test3"},
            {"four", "shi - \u56DB", "Test1", "Test2", "Test3"},
            {"five", "go - \u4E94", "Test1", "Test2", "Test3"},
            {"six", "roku - \u516D", "Test1", "Test2", "Test3"},
            {"seven", "shichi - \u4E03", "Test1", "Test2", "Test3"},
            {"eight", "hachi - \u516B", "Test1", "Test2", "Test3"},
            {"nine", "kyu - \u4E5D", "Test1", "Test2", "Test3"},
            {"ten", "ju - \u5341", "Test1", "Test2", "Test3"},
            {"one", "ichi - \u4E00", "Test1", "Test2", "Test3"},
            {"two", "ni - \u4E8C", "Test1", "Test2", "Test3"},
            {"three", "san - \u4E09", "Test1", "Test2", "Test3"},
            {"four", "shi - \u56DB", "Test1", "Test2", "Test3"},
            {"five", "go - \u4E94", "Test1", "Test2", "Test3"},
            {"six", "roku - \u516D", "Test1", "Test2", "Test3"},
            {"seven", "shichi - \u4E03", "Test1", "Test2", "Test3"},
            {"eight", "hachi - \u516B", "Test1", "Tes12121t2", "Test3"},
            {"nine", "kyu - \u4E5D", "Test1", "Test2", "Test3"},
            {"ten", "ju - \u5341", "Test1", "Test2", "Test3"},
            {"one", "ichi - \u4E00", "Test1", "Test2", "Test3"},
            {"two", "ni - \u4E8C", "Test1", "Test2", "Test3"},
            {"three", "san - \u4E09", "Test1", "Test2", "Test3"},
            {"four", "shi - \u56DB", 12, "Test2", "Test3"},
            {"five", "go - \u4E94", 121212, "Test2", "Test3"},
            {"six", "roku - \u516D", 1212121212, "Test2", "Test3"},
            {"seven", "shichi - \u4E03", 12.01, "Test2", "Test3"},
            {"eight", "hachi - \u516B", 135.12, "Test2", "Test3"},
            {"nine", "kyu - \u4E5D", 93828.34, "Test2", "Test3"},
            {"ten", "ju - \u5341", "Test1", "Test2", "Test3"},
            {"one", "ichi - \u4E00", "Test1", "Test2", "Test3"},
            {"two", "ni - \u4E8C", "Test1", "Test2", "Test3"},
            {"three", "san - \u4E09", "Test1", "Test2", "Test3"},
            {"four", "shi - \u56DB", "Test1", "Test2", "Test3"},
            {"five", "go - \u4E94", "Test1", "Test2", "Test3"},
            {"six", "roku - \u516D", "Test1", "Test2", "Test3"},
            {"seven", "shichi - \u4E03", "Test1", "Test2", "Test3"},
            {"eight", "hachi - \u516B", "Test1", "Test2", "T1212121212est3"},
            {"nine", "kyu - \u4E5D", "Test1", "Test2", "Test3"},
            {"ten", "ju - \u5341", "Test1", "Test2", "Test3"},};
        final Object headers[] = {"English", "Japanese", "Column1", "Column2",
            "Column3"};
        JTable table = new JTable(rows, headers);
        return table.getModel();
    }
}

Popularity: 15% [?]

10 things all JAVA developers should know [zz]

Posted by ijay @ 技术生活 No Comments »

原文在这里

Since JAVA (I know it’s not an acronym, but it stands out like that) was officially introduced in 1995, it has changed the way most of us look at the Operating System. Bill Gate (how ironic) once said that it was not about the hardware but the software which will be the future. A decade or more later, the fifth employee of SUN, John Gage said “The Network is the Computer”. Fast-forwarding to the 21st century and John seemed to be right. Anyway, JAVA was built not to depend on an Operating System and deployed through the network. JAVA through its applet technology gave birth to Rich Network Application aka Rich Internet Application (RIA). JAVA is not perfect; or we would not have various releases and more on the way, but JAVA has given birth to a wide range of programming language (just Google it to find out more).

Without further ado, I am going to get back to subject. This is a brief article on what I believe that every Java developers should know regardless of their experience. I do not personally believe that someone with 5 years experience is not as good as someone with 10 years experience. We all develop our own methods of working but as a developer you need to stay abreast of your technology. So, here are my top 10 not in order of importance (or?):

  1. Remember the basic of JAVA language and OOP paradigm.
    Most experience developers seem to forget the theory behind the language. I am not saying that they are not good at their job but can they explain to junior developers why they have used interfaces instead of abstract classes or why implement a pattern over another one? As a programmer, you become very arrogant as you believe that you write the best code but in the real world, people work in teams with different skill set and experiences. It is important that you can backup your actions/ codes. A very simple question such as; when should I use a String object instead of a StringBuilder/ StringBuffer? You might take this question lightly but can you actually tell someone else the difference?
  2. Know your technology stack
    All developers have to know their technology stack. What does it mean? JAVA is not like other languages; JAVA has subsets such J2ME and superset such as Java EE. We have our own area of expertise but it is important to know the differences between the various sets of JAVA. Some basic questions such as the differences between SWING, Applet, Servlets, EJBs and JAVAFX will boost your confidence. Most developers do not know how to tweak the JVM and the differences between the JRE and the SDK environment. Do you know why you need the SDK to be installed to run Tomcat but you only need the JRE to run an application?
  3. Experiment with various Java EE framework
    I am not asking you to be an expert in every single Java EE framework but it will make the difference if you are familiar with Spring and EJB. That should actually be the de facto framework that should be on every developers CV. Developers should know the difference between Java EE 5 (soon 6) and Spring. Hibernate is also brilliant and it’s used for data access but all developers should have moved to JPA by now. Hibernate also comply with JPA therefore there is no more excuses.
  4. Know a scripting language
    JAVA can be heavyweight for some simple tasks which can be implemented using a simple dynamic language such as Python, Perl(?) and others. I would also recommend to developers to learn shell scripting on their target OS.
  5. Know how to develop web services
    The network is the computer, therefore it is important to know the different web services framework available. Data are integrated through web services and opening your services to the “cloud”. SWING developers will probably not develop web services but I am sure that they will be connecting to data through web services clients. Understanding the difference between the standardised SOAP and non-standardised ReST will help you choose which is best to implement your services.
  6. Know how and when to multithread your application
    I have to put that in there. Developers should know when and why to multithread an application, thread inter-communication and monitoring. All developers, junior or not, should know how to write a multi-threaded application.
  7. Database development using JDBC and JPA
    This should be a development law. All developers should know how to write SQL queries and how to create databases. All enterprise applications store data in some sort of relational database systems and it is therefore imperative that this knowledge should be of second nature. Java EE 5 introduced JPA (JDO was there before) but it is not applicable to all situation. Hence, knowing the difference and when to implement one instead of the other is important.
  8. Know a client side scripting language and what is AJAX
    The network is the computer and Internet is the deployment platform. Java EE and its various framework are server side executiong which can put extra “load” on the server. If you are looking to move a cloud based system where the providers charges you per resources used, it might be wise to move some of the execution to the client side. AJAX has been buzzing the scene for the last 3 years and more. This is not a technology but a new way of doing something that already existed. There are numerous JAVA AJAX framework such as GWT and DWR which makes it easy to develop AJAX based application which are compiled to JavaScript. Developers should also know what is the AJAX theories.
  9. Know your competitors and do not take part on “what is the best IDE” discussion
    JAVA is not the only language that can do what it does. I think that JAVA is more mature and complete as opposed to other languages. Knowing the difference between JAVA and .NET or JAVA and Ruby is a good asset to have. You also need to know when and why to use one instead of the other. Please please please, do not get into “my IDE is better than x because…” discussion as it is good for the JAVA community to have multiple IDEs and framework available to use. Every tools have their place as for example JDeveloper is better than x if you are going to solely develop on an Oracle stack and etc…
  10. Know ANT (MAVEN?), TOMCAT and any other mainstrean application server
    ANT is the de facto build script for JAVA and its IDE-based development. Maven is becoming popular and soon can be as popular as ANT (not sure of its popularity in the financial sector). TOMCAT  should be immortalised as the based servlet container that all developers should be familiar with.

There are alot more to add but this is just some of the basics that I think all developers should have in their repertoire. Feel free to add to this list in the comments box. If I could had another one to this, would be; all developers not just JAVA, should know how to search the web and Google is your best friends (now support my advertisers by clicking on the links on the right ;) ). I hope you enjoyed the entry and feel free to comments good or bad!!! are welcome.

Popularity: 17% [?]

BlockingQueue与InterruptedException

Posted by ijay @ 技术生活 No Comments »

感谢Blader同学的抛砖

首先,这段代码会编译成功吗,运行起来会有异常吗,他会打印什么?

1
2
3
4
5
6
7
8
9
10
11
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
 
public class Foo {
   public static void main(String[] args) throws InterruptedException {
       BlockingQueue q = new LinkedBlockingQueue();
       q.put(1);
       Thread.currentThread().interrupt();
       System.out.println(q.take());
   }
}

运行后结果如下:

Exception in thread "main" java.lang.InterruptedException
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1135)
	at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:312)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:354)
	at Foo.main(Foo.java:9)

看了一下源代码,阻塞队列的访问方法(take、put、poll、offer)会在执行之前检查Lock对象的中断标记,而Lock对象则是检查当前线程的中断标记

Popularity: 19% [?]

JDK 7 Features [zz]

Posted by ijay @ 技术生活 No Comments »

原文地址:http://openjdk.java.net/projects/jdk7/features/

This is the list of features being developed by Sun, and others, for JDK 7.

When the Java SE 7 Platform JSR is submitted then these features will be proposed therein, except for those listed as either VM-level or implementation-specific.

Per the current draft of the development process we will shortly publish a Feature Proposal template. That will be the vehicle for proposing additional features for inclusion in the release.

Comments to: jdk7-dev at openjdk.java.net

Summary

Features are listed in order, more or less, from lowest to highest in the overall JDK  software stack.

Features that were planned but later dropped are listed at the bottom of this page.

VM
Compressed 64-bit object pointers
A technique for compressing 64-bit pointers to fit into 32 bits, which decreases memory and memory-bandwidth consumption and thereby improves performance (VM-level feature)
Lead: Coleen Phillimore
Links: wiki page
Milestone target: M1
Garbage-First GC (G1)
A new garbage collector that promises to achieve lower pause times and better predictability than the current CMS collector (VM-level feature)
Milestone target: M1
JSR 292: VM support for non-Java languages (InvokeDynamic)
VM extensions to support the implementation of non-Java languages at performance levels near to that of the Java language itself
Lead: John Rose
Milestone target: M3
Language
JSR 308: Annotations on Java types
An extension to the Java annotation syntax to permit annotations on any occurrence of a type
Milestone target: M4
JSR TBD: Small language enhancements (Project Coin)
A set of small language changes intended to simplify common, day-to-day programming tasks
Lead: Joe Darcy
Milestone target: M5
JSR 294: Language and VM support for modular programming
Enhancements to the Java language and virtual-machine specifications to support modular programming, at both compile time and run time
Core
Modularization (Project Jigsaw)
An implementation-specific, simple, low-level module system focused upon the goal of modularizing the JDK, and the application of that system to the JDK itself
Upgrade class-loader architecture
Modifications to the ClassLoader API and implementation to avoid deadlocks in non-hierarchical class-loader topologies
Lead: Karen Kinnear
Links: summary
Milestone target: M3
Method to close a URLClassLoader
A method that frees the underlying resources, such as open files, held by a URLClassLoader
Links: summary; api
Milestone target: M2
Unicode 5.1
Upgrade the supported version of Unicode to 5.1
Lead: Yuka Kamiya
Milestone target: M3
Concurrency and collections updates (jsr166y)
A lightweight fork/join framework, generalized barriers and queues, a concurrent-reference HashMap, and fences to control fine-grained read/write ordering
Lead: Doug Lea
Milestone target: M5
JSR 203: More new I/O APIs for the Java platform (NIO.2)
New APIs for filesystem access, scalable asynchronous I/O operations, socket-channel binding and configuration, and multicast datagrams
Milestone target: M2
SCTP (Stream Control Transmission Protocol)
An implementation-specific API for the Stream Control Transmission Protocol on Solaris
Milestone target: M3
SDP (Sockets Direct Protocol)
Implementation-specific support for reliable, high-performance network streams over Infiniband connections on Solaris
Milestone target: M3
Elliptic-curve cryptography (ECC)
A portable implementation of the standard Elliptic Curve Cryptographic (ECC) algorithms, so that all Java applications can use ECC out-of-the-box
Lead: Vincent Ryan
Milestone target: M5
Client
XRender pipeline for Java 2D
A new Java2D graphics pipeline based upon the X11 XRender extension, which provides access to much of the functionality of modern GPUs
Forward-port 6u10 deployment features
Forward-port implementation-specific deployment features from the 6u10 release: The new Java Plug-In, Java Kernel, Quickstarter, and related installer features
Lead: Andy Herrick
Milestone target: M4
Create new platform APIs for 6u10 graphics features
Create new platform APIs for features originally implemented in the 6u10 release: Translucent and shaped windows, heavyweight/lightweight mixing, and the improved AWT security warning
Lead: Anthony Petrov
Milestone target: M3
Nimbus look-and-feel for Swing
A next-generation cross-platform look-and-feel for Swing
Lead: Jasper Potts; team: Richard Bair, Peter Zhelezniakov
Milestone target: M3
Swing updates
Small additions to the Swing API including the JXLayer component decorator, JXDatePicker, and possibly CSS-based styling
Milestone target: M5
Web
Update the XML stack
Upgrade the JAXP, JAXB, and JAX-WS APIs to the most recent stable versions
Milestone target: M5
Dropped
JSR 296: Swing application framework
An API to define the basic structure of a typical Swing application, thereby eliminating lots of boilerplate code and providing a much-improved initial developer experience
Links: JSR 296

Popularity: 21% [?]

如何在Snow Leopard下安装JDK 1.5

Posted by zn_cn_2 @ 未分类 No Comments »
万恶的Snow Leopard将JDK 1.5去除了,这直接导致安装不了GlassFish 2.1,非常烦人。
不过将JDK 1.5找回来其实也很简单,就是把leopard的jdk 1.5拷过来就OK了

首先下载leopard版的jdk 1.5,可以在文件服务器上找到,也可以点击下面这个地址直接下载
http://www.cs.washington.edu/homes/isdal/snow_leopard_workaround/java.1.5.0-leopard.tar.gz
然后将其解压到/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0-leopard下,并将其所有者修改为root:wheel
chown -R root:wheel 1.5.0-leopard
然后将原1.5和1.5.0的link删除,并将其指向新的1.5.0-leopard(注意切换为root用户)
sudo -s
rm 1.5
ln -s 1.5.0-leopard/ 1.5
rm 1.5.0
ln -s 1.5.0-leopard/ 1.5.0
OK,这下可以装GlassFish 2.1啦

Popularity: 20% [?]

解决openfire在使用MySQL数据库后的中文乱码问题

Posted by zn_cn_2 @ 未分类 No Comments »

openfire是一个非常不错的IM服务器,而且是纯Java实现,具有多个平台的版本,他的数据存储可以采用多种数据库,如MySQL,Oracle等。

在实际使用时大家遇到最多的就是采用MySQL数据库后的中文乱码问题,这个问题十分有趣,而且从现象上可以看出openfire内部的一些机制。

实际问题是这样的:首先启动openfire服务器,然后利用客户端或直接登录到后台新建一个帐户,为该帐户指定一些中文的属性,如姓名等。如果不重启服务器,你永远不会觉得有什么不对的地方,因为所有的中文显示都是正常的。接下来重启一下openfire,再用建立的帐号登录客户端或进入后台管理端查看,会发现所有的中文全都变成了问号。登录到数据库中进行查看,发现所有的中文字符也均为问号,这说明了两个问题:

  1. openfire具有应用层缓存
  2. 数据库编码存在问题

解决办法其实也很简单,首先要保证你为openfire创建的数据库编码是utf8的,建表语句如下:

create database openfire default character set utf8 default collate utf8_general_ci

其次,在初始化openfire数据库时,必须在连接里增加UTF8的编码要求,连接字符串设置如下:

jdbc:mysql://127.0.0.1:3306/openfire?useUnicode=true&characterEncoding=utf8

如果已经安装完成,这个配置也是可以改动的,直接到openfire的安装目录下,找到conf/openfire.xml这样一个文件,打开找到如下的XML节,修改其中的serverURL即可

<database>
<defaultProvider>
<driver>com.mysql.jdbc.Driver</driver>
<serverURL>jdbc:mysql://127.0.0.1:3306/openfire?useUnicode=true&amp;characterEncoding=utf8</serverURL>

注意:由于&具有特殊含义,因此原&符号必须被转义为&amp;

Popularity: 25% [?]

Which GlassFish version is right for me? [zz]

Posted by ijay @ 技术生活 No Comments »

GlassFish has several versions that you may have heard of. Each one attempts to address different needs. I’ve had several people in the last couple of weeks ask me which one they should use, so here’s a quick list of features and reasons to use one more than the other.

GlassFish v2.1: current JavaEE 5-certified and supported product. Offers centralized admin, clustering. v2.0 was released in September 2007 and v2.1 in March 2009 with the Enterprise Manager value add. All major IDE’s (NetBeans, Eclipse, IntelliJ) have plugins to deploy to this version. GlassFish v2.1 update 3 is the latest version available for supported customers.

GlassFish v3 Prelude: interesting if you want a lightweight Java EE 5 web container (no EJB, JMS, etc…) with admin tools. This is the first release using the modular OSGi architecture, IPS packaging format, and developer features such as preserve session across redeployments. This was released in November 2008 and is a supported product (although not a long-lived as traditional software at Sun). It also offers native deployment of Grails and Rails applications. Some people use this version in development and deploy to v2.1.

GlassFish v3 Preview: while not yet a supported product, this is a more recent version building on the same foundation as the above “Prelude” version, only it now offers both a Web distribution and a full Java EE 6 (Preview) distribution. It has a number of improvements over the “Prelude” version (IPS and updatetool for instance) and certainly much closer to a fully-featured application server. The final version should ship in September 2009 and offer a JavaEE 6, single-instance architecture. At that point this will become a supported product. The centralized administration will come in the v3.1 release which will mean feature parity with v2.1. If you like bleeding edge stuff, promoted builds for v3 are here.

For more details on the releases, including sustaining (restricted) releases, please visit http://blogs.sun.com/GlassFishForBusiness/ Which GlassFish version is right for me? [zz]

Popularity: 29% [?]

遍历Map<K, Collection<V>>的正确方法

Posted by ijay @ 技术生活 No Comments »

对于value为集合的map,一般直觉上我们可能会选用下面的方式遍历map中所有collection的所有对象:

for(K key:map.keySet()){
    for(V value:map.get(key)){
        // do sth.
    }
}

实际上,这种方式在第二行上会因为对哈希表的查询浪费效率,正确的做法应该这样:

for(List&lt;V&gt; list:map.values()){
    for(V o:list){
        // do sth.
    }
}

或者

for(Map.Entry&lt;K,List&lt;V&gt;&gt; entry:map.entrySet()){
    for(V o:entry.getValue()){
        // do sth.
    }
}

Popularity: 38% [?]

远程访问Tomcat的JMX

Posted by 小权 @ 技术生活 No Comments »

Tomcat的JMX支持默认应该是关闭的,首先我们得打开Tomcat的JMX支持,同时指定远程访问的IP地址、接口、是否支持SSl,是否验证访问等信息。
在Tomcat启动的VM arguments中加入下面的参数:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8060
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=172.16.100.114

然后,打开JDK/bin目录下的jconsole.exe,在远程进程中输入:service:jmx:rmi:///jndi/rmi://172.16.100.114:8060/jmxrmi,就可以远程访问 172.16.100.114:8060 下面的jmx服务

Popularity: 41% [?]

到底要不要用Mercurial?

Posted by zn_cn_2 @ nazca生活 No Comments »

今天在solidot上读到了一条新闻,说GNOME已经决定采用Git版本控制系统,正式迁移将在4月16日的GNOME2.26.1发布之后开始。于是上网搜了一下Git,不搜不知道,一搜还真是吓了一跳,许多开源项目都已转向了Git:

  • Linux kernel
  • Samba
  • Wine
  • X.org Server
  • Ruby on Rails

本打算研究一下,但是Git对跨平台和中文支持不足的问题让我不得不暂时停手了。可是又不甘心,因为觉得分布式SCM似乎是大势所趋,于是我的目光又开始转向另一个分布式SCM:Mercurial。
早在08年初,Netbeans就已经宣布把代码版本管理系统从cvs迁移到Mercurial,在那之后发布的所有Netbeans版本中都出现了名为Mercurial的插件。我一直就没太在意这个东西,每次装完Netbeans之后的第一件事就是把CVS和Mercurial插件禁掉(因为团队只使用subversion进行代码同步)。但是近期的大家频繁提交导致repository容量和代码版本号暴涨让我不得不开始考虑解决办法。也许是与个人习惯有关,但我始终认为频繁提交代码不是一件很值得提倡的事。
短暂了研究了一下,结论是现阶段的Mercurial仍不是很适合我们团队的开发,原因如下:

  1. 尽管Mercurial支持离线工作,具有临时提交功能,但这此临时提交没有办法合并,在合并到主支时,所有的版本号全一并合并到主支,依然存在版本号暴涨的问题
  2. Mercurial不支持子目录或子项目提交,这点相对于多项目管理来说非常不方便
  3. Mercurial对权限管理很弱,不能很容易的实现用户身份认证
  4. Mercurial与apache的结合并不是很好

不过不排除以后版本的Mercurial解决上述问题后会对团队的项目进行版本库迁移。另外,如果只是一个人开发项目的话,还是很推荐使用一下Mercurial,毕竟它比VSS要好很多,呵呵。
找到一篇介绍Mercurial的文章,感兴趣的人可以参考一下。

Popularity: 43% [?]

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS 登录
北京英智兴达信息技术有限公司 京ICP备08011463号
Beijing YingZhi XingDa Technology Co., LTD. © 2008-2009
联系我们: