DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

The Latest Coding Topics

article thumbnail
Tips and Tricks for Debugging in Eclipse
In this article I will describe some tips and tricks for debugging your applications in Eclipse.
April 4, 2008
by chander prakash
· 145,779 Views · 4 Likes
article thumbnail
John Wilson: Groovy and XML
John Wilson is mainly known to the Groovy community because of his work on XmlSlurper, one of the easiest ways to work with XML in the JVM. Continue reading to learn what inspired John to get into Groovy. Enjoy! [img_assist|nid=2119|title=|desc=|link=none|align=right|width=220|height=188]Q. John, you are the creator of XmlSlurper, what motivated you to make it ? A. I had a problem with processing very large XML documents. XmlParser uses a simple and robust way of implementing GPath expressions which involves building an array to hold the result of each term on the expression. Unfortunately this means that you can consume large amounts of memory if the original document is large. I was getting out of memory errors quite a bit so I wrote the original version of XmlSlurper to use Iterarors rather than arrays which cut down the memory footprint quite a bit. It had the happy side effect of being faster too. I have rewritten XmlSlurper a couple of times since then and it now plays very well with StreamingMarkupBuilder, handles namespaces nicely and has an interesting way of doing edits on the fly as the slurped document is written out. Q. XmlSluper and XmlParser are so similar, is there a reason to have both ? A. On the one hand it's a disadvantage because users are unsure which one to use (The answer is - for most things it doesn't matter). However they have differences which are significant and, in my view, valuable. The most significant difference is their approach to editing the document. XmlParser is very straightforward, you just change the in memory tree structure which represents the document. XmlSlurper does not let you have direct access to the in memory data structure. It forces you to put you editing code in closures and specify where in the document the closures should be applied. It then does the editing on the fly as the document is written out. The first mechanism is simple but limited the second is more complicated but very powerful. Most of us only want to do relatively simple operations on small XML documents and XmlParser is excellent for that. For those people who want to do rather complex operations on XMl documents which can be quite large then XmlSlurper is a better choice. Fortunately they support an almost identical GPath syntax so switching from one to the other is no big deal. This was not always so - the community owes a big debt of gratitude to Paul King for doing a large amount of work on documenting these implementations and aligning them. My long term aim is to be able to do away altogether with the need to hold the whole document in memory but to stream the document through memory whist executing the GPath expressions. Q. You are also the creator of the xmlrpc module, what can you tell us about it ? A. It's a module I'm very fond of. It's an excellent example of how Groovy can make something that is quite complex in Java completely trivial. I can build an XML-RPC server in 4 lines of Groovy and a client in 1 line. Performance is excellent and it interoperates well. It is based on code I wrote a few years ago to implement XML-RPC on the Dallas Semiconductor TINI. The TINI is an amazing device the size of a memory SIMM which runs Java on a 8051 (the processor which controlled the keyboard in the original IBM PC) with 1Mb of battery backed up RAM and an Ethernet port. One of my favourite TINI apps was a weather forecasting toaster! [it's true! check it out for yourselves here] Q. Have you participated in other Open Source projects ? A. Yes, mostly in the embedded Java arena. I wrote tiny XML parsers (MinML and MinML2) and a tiny XML-RPC server (MinMl-RPC) i have also contributed to VNC and the Snort intrusion detections system. In the background I'm working on Ng which is an attempt to build a runtime system for dynamic languages on the JVM which is both simple and fast. Q. Ng, can you share more about it? A. Ng is a solo (at the moment) project which tries to answer the question: How can we implement a fully dynamic language on the current JVM which runs no more than ten times slower than Java? This is looking for an improvement of one to two orders of magnitude over current implementations (Groovy, JRuby, Jython, etc.). The idea is to design a programming language "backwards". I start with a highly optimised runtime system and then derive a language which can be optimally compiled for that runtime system. I'm hoping that some of the insights I get whist doing this can be fed back into the Groovy 2.0 MOP redesign. I'm making good but slow progress. I have arithmetic operations executing at less than twice as slow as Java in some benchmarks and method calls are coming below ten times as slow. I have started to document some of the techniques I have developed http://docs.google.com/View?docid=ah76zbd6xsx2_9ck33c8dp Q. How did you get involved with Groovy ? A. I was looking for an Open Source project to get involved in. I have a long term interest in programming languages (my first paid job was as a compiler writer in 1971). I looked at Ruby and JRuby but it was too Perlish for my tastes and the JRuby project looked moribund. Google found me Groovy and I liked the feel of the language and the community was very lively so I stuck around. Q. Do you use Groovy at work ? A. Yes. If I have to mung XML I will always do it in Groovy. I also spend quite a bit of time building DSLs in Groovy. I think the return on investment in DSLs is huge if they are done properly. Q. Do you have a preferred technique for building DSLs (builders, metaprogramming, ... ) ? A. I like builders a lot. I think that the Builder concept is one of James Strachan's best ideas. I built a little DSL to allow people to specify arbitrary graphs - it took about an hour to develop and it's saved days in allowing us to specify complex graphs simply, clearly and reliably. I tend to override invokeMethod, etc. or use Categories rather than ExpandoMetaClass to do MetaPrograming magic. That's probably because to got into the habit before Graeme wrote ExpandoMetaClass. However I do like the fact that Categories allow me to limit the extent of the change to a single thread - they need to have less impact on performance, though. Q. Is there a specific feature you would like to see in a future version of Groovy ? A. I think Inner Classes need to be added. Other than that I don't see much urgent need for language extensions. Quite a lot of work has been done on making the run time system cleaner and that work needs to continue. The speed of the implementation has been improved in the last few months but there is more work needed there (especially with Categories). the big thing I'd like to see is the ability to not compile to class files but to execute the AST (Abstract Syntax Tree) directly. JRuby does this and it can be very useful in cases where you are generating code dynamically and executing it once or twice before discarding it (which is quite a common use). It would also help with the Groovy console. Thanks John! John's bio John Wilson has been a programmer, project manager, teacher, CTO and CEO. He's now CTO of an English engineering company and is enjoying working with a great crowd in the Groovy/Grails community.
April 1, 2008
by Andres Almiray
· 17,262 Views · 1 Like
article thumbnail
Convert Java Date To GMT
This function converts a local date to GMT. This version corrects the bug common to this type of conversion where the date is incorrectly converted when the time is close to the DST crossover. WARNING: This code is for printing/string-representation only, the millis value of the returned date is NOT in GMT. private static Date cvtToGmt( Date date ) { TimeZone tz = TimeZone.getDefault(); Date ret = new Date( date.getTime() - tz.getRawOffset() ); // if we are now in DST, back off by the delta. Note that we are checking the GMT date, this is the KEY. if ( tz.inDaylightTime( ret )) { Date dstDate = new Date( ret.getTime() - tz.getDSTSavings() ); // check to make sure we have not crossed back into standard time // this happens when we are on the cusp of DST (7pm the day before the change for PDT) if ( tz.inDaylightTime( dstDate )) { ret = dstDate; } } return ret; }
March 28, 2008
by Douglas Wyatt
· 9,792 Views
article thumbnail
Ant Build File Changes for Java Web Projects in NetBeans IDE 6.1
While working with a Java Web Application in NetBeans, I noticed some slight changes in the Ant build file for my project between NetBeans 6.0 and 6.1. This article explores some of the problems these changes caused to help out anyone with similar issues. I started with a Java Web Application that was created in NetBeans 6.0.1. After adding some JSP files and several Java source files, I committed everything in the project to my CVS repository. For some of my projects, I utilize the Hudson continuous integration build server. Using a standard deployment of Hudson, I configured the project to poll the SCM every 60 minutes, check out the code from CVS (if changes had been committed), and trigger the NetBeans project’s Ant build file (calling several specific targets like compile, dist, and so on. My builds have been functioning correctly for several weeks using this standard setup. I recently opened one of those projects in NetBeans 6.1 Beta and have been thoroughly enjoying the new features (faster startup, better JSP parsing in the Source Editor). After adding some JAR files as libraries and making several configuration changes, I committed the entire project (particularly the build-related files in the nbproject directory). Suddenly, my build for that project started failing. The console output reported by Hudson was : -init-check: BUILD FAILED D:/projects/hudson-server/data/jobs/MyWebProjectl/workspace/nbproject/build-impl.xml:149: The Java EE server classpath is not correctly set up. Your active server type is Tomcat55. Either open the project in the IDE and assign the server or setup the server classpath manually. For example like this: ant -Duser.properties.file= (where you put the property “j2ee.platform.classpath” in a .properties file) or ant -Dj2ee.platform.classpath= (where no properties file is used) Total time: 2 seconds finished: FAILURE I undid the configuration changes one by one, but the build failed regardless of what I reset. Apparently the property j2ee.platform.classpath is now required. I did a DIFF on the nbproject/build-impl.xml file and discovered several changes. The -init-check target includes property checks including this new one : The Java EE server classpath is not correctly set up. Your active server type is ${j2ee.server.type}.Either open the project in the IDE and assign the server or setup the server classpath manually.For example like this: ant -Duser.properties.file= (where you put the property “j2ee.platform.classpath” in a .properties file) or ant -Dj2ee.platform.classpath= (where no properties file is used) I hadn’t really taken notice of this property in the build file before, but it is referenced in a number of other targets such as: -init-macrodef-javac, -init-macrodef-junit, -init-macrodef-java, -init-macrodef-nbjpda, -init-macrodef-debug, compile-jsps, -do-compile-single-jsp, connect-debugger, javadoc-build, -do-compile-test, -do-compile-test-single Not being able to find a definition of the property anywhere in the build file, I looked through the project’s project.properties file among the list of defined properties. The property j2ee.platform.classpath was not defined. Thus, I’m assuming this is passed into the build file dynamically by NetBeans? In general I wouldn’t care, but when running the build file via Ant inside Hudson, the property j2ee.platform.classpath is never passed in. Hudson DOES allow you to pass properties and values to the build file, so I suppose I can specify the value manually, but I would like to keep the number of per project customizations to a minimum to maintain a low level of maintenance. Unless this causes some problem with the project properties in the build system, I would suggest the following fix for anyone who is experiencing a similar issue. Open your project’s project.properties file. Navigate to the section that contains these properties: j2ee.platform=1.4 j2ee.server.type=Tomcat55 Add a new line that specifies a blank j2ee.platform.classpath property such as this: j2ee.platform=1.4 j2ee.platform.classpath= j2ee.server.type=Tomcat55 Now, if the project.properties file is committed to CVS, a Hudson build can be triggered, and the FAIL check in the build-impl.xml file will pass. I ran some quick tests with the project, and everything with the project inside NetBeans still seems to work fine. I would propose to the NetBeans team to have the j2ee.platform.classpath property automatically added to the project.properties file.
March 26, 2008
by Adam Myatt
· 15,658 Views
article thumbnail
Quick Tip: Granting Access to Meta-Data on MySQL
If you have root access to your MySQL database then you can simply run a query on the database to resolve the problem.
March 22, 2008
by Schalk Neethling
· 45,403 Views
article thumbnail
Java Bean Code Generation In Eclipse
Where would we be without JavaBeans? We use them in all our basic Java applications. We have Struts Form Beans, Hibernate and Spring POJO's and the list goes on. We are all used to writing setters and getters in for our Java Bean's manually. With thanks to Eclipse and other plugins, this effort is now very very easy. This tip is for the beginners (seniors, this is my first quick tip post) to generate setters and getters in a Java Bean class. First declare all the variables you need in the class. Next, right click any where on the source file. Select Source and then Generate Getters and Setters. This can be done alternatively by pressing Alt+Shift+S. Now select the variables for which you want to generate the getters and setters and you're done. As you can see there are multiple options in the window. Finally, the source code is.. Happy Coding! Until Next Time... RD
March 20, 2008
by Ratna Dinakar Tumuluri
· 56,983 Views
article thumbnail
Applying Python To Modify Java Code
Python script intended to open each Java's project file, add the license term on the start of the file as a Java comment and writing it to the disk. 1) You'll need a Python interpreter. Check this out in http://python.org. 2) You'll need to enter the root file directory of the Java project, like python AddLicense.py ${path} where ${path} defines user project root directory. 3) See http://fcmanager.wiki.sourceforge.net 1:# Python script to add the LGPL notices to each java file of the FileContentManager project. 2:import os, glob, sys 3:License = """\ 4:/** 5:*FileContentManager is a Java based file manager desktop application, 6:*it can show, edit and manipulate the content of the files archived inside a zip. 7:* 8:*Copyright (C) 2008 9:* 10:*Created by Camila Sanchez [http://mimix.wordpress.com/], Rafael Naufal [http://rnaufal.livejournal.com] 11:and Rodrigo [[email protected]] 12:* 13:*FileContentManager is free software; you can redistribute it and/or 14:*modify it under the terms of the GNU Lesser General Public 15:*License as published by the Free Software Foundation; either 16:*version 2.1 of the License, or (at your option) any later version. 17:* 18:*This library is distributed in the hope that it will be useful, 19:*but WITHOUT ANY WARRANTY; without even the implied warranty of 20:*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21:*Lesser General Public License for more details. 22:* 23:*You should have received a copy of the GNU Lesser General Public 24:*License along with FileContentManager; if not, write to the Free Software 25:*Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ 26: 27:size = len(sys.argv) 28:if size == 1 or size > 2: 29: print "Usage: AddLicense.py $1" 30: sys.exit(1) 31:inputPath = sys.argv[1] 32:if not os.path.exists(inputPath): 33: print inputPath, "does not exist on disk" 34: sys.exit(1) 35:if not os.path.isdir(inputPath): 36: print inputPath, "isn't a dir" 37: sys.exit(1) 38:for path, dirs, files in os.walk(inputPath): 39: fileWithLicense = '' 40: for filepath in [ os.path.join(path, f) 41: for f in files if f.endswith(".java")]: 42: content = file(filepath).read() 43: f = file(filepath, "w") 44: print >>f, License + "\n" + content 45: f.close() 46: 47:
March 17, 2008
by Rafael Naufal
· 2,822 Views
article thumbnail
How to Create a Pluggable Photo Album in Java
Here you see a simple photo album I created in Java Swing. It is, by no definition of the term, a great photo album. However, the point is that none of the photos you see are provided by the application itself. Nor do they come from the web. So... where do they come from and how did they end up in my photo album? Read on to find out... Here's a clue. All that you would need to provide in order to add photos to my photo album is a Java application that is structured as follows: The images "demo1.png" and "demo2.png" are two of the four photos you see in the first screenshot, i.e., the screenshot of my photo album. The other two photos you see there come from another Java application, which is structured in exactly the same way as the above. "Ah," you might now think. "This article is all about the Java SE 6 java.util.ServiceLoader class. I guess I'll need to be using Java SE 6 and then I'll be able to construct small applications structured like the above and then I'll be able to plug into your photo album." Wrong. You don't need Java SE 6 at all. Although, you're close. Here's the definition of the VacPhotos class that you see in the illustration above: package com.example.vacphotos; import javax.swing.Icon; import javax.swing.ImageIcon; import photoalbumapp.Photo; public class VacPhotos implements Photo { ImageIcon icon1 = new ImageIcon(getClass().getResource("/com/example/vacphotos/demo1.png")); ImageIcon icon2 = new ImageIcon(getClass().getResource("/com/example/vacphotos/demo2.png")); public VacPhotos() { } @Override public Icon[] getPhoto() { Icon[] icons = new Icon[]{icon1, icon2}; return icons; } @Override public String[] getDescription() { String[] descs = new String[]{"pic 1", "pic2"}; return descs; } } In other words, you simply need to extend the photoalbumapp.Photo class, which the photo album itself makes available, meaning you need its JAR on your plugin's classpath. The photo album is an empty application shell that exposes the Photo class, with its two methods getPhoto and getDescription. You therefore need to create a Java class that implements those two methods, returning arrays of Icons and Strings for the photos you'd like to integrate into the photo album. Finally, you need to create a file in your META-INF.services folder, with the name of the class that you are implementing, which in this case is photoalbumapp.Photo. Within that file you need nothing more than one line, which is the FQN of your implementation class: com.example.vacphotos.VacPhotos And that's all. Now, when the JAR of your app is on the classpath of the photo album, your photos and descriptions will automatically be integrated with all the photos provided by all the other implementations of the same class. The cool thing is that the photo album is an implementation of JSR-296, the Swing Application Framework, so that lifecycle management and persistance, as well as other typical application services, are dealt with by the framework itself. For example, I don't need to provide any code for the user's resizings and repositionings to be saved across restarts. The most important part, in this context, of my photo album application (i.e., this is a totally separate application to the VacationPhotos application above), is the code that defines my photo service: package photoalbumapp; import java.util.Collection; import org.openide.util.Lookup; import org.openide.util.Lookup.Result; import org.openide.util.Lookup.Template; public class PhotoService { private static PhotoService service; private Lookup photoLookup; private Collection photos; private Template photoTemplate; private Result photoResults; private PhotoService() { photoLookup = Lookup.getDefault(); photoTemplate = new Template(Photo.class); photoResults = photoLookup.lookup(photoTemplate); photos = photoResults.allInstances(); } public static synchronized PhotoService getInstance() { if (service == null) { service = new PhotoService(); } return service; } public Collection getDefinitions() { return photos; } } The template lookup method returns a Result instance that contains multiple providers, if they exist. You can retrieve the entire collection of providers by calling the Result instance's allInstances method, which is exactly what is done above. Here you see that we are not dealing with the Java SE 6 ServiceLoader class (nor its earlier incarnations, which have been in the JDK since JDK 1.3). Instead, we are dealing with the NetBeans Platform's org.openide.util.Lookup class. Above, I have provided the bridge between your VacationPhotos application and my own separate application that provides the photo album. The bridge is accessed by the photo album to retrieve photos and descriptions. The bridge, in its role as a "service", will, in turn, access all the classes that implement the Photo implementers, as defined in the small Java applications that exist for no other reason than to provide photos, such as the VacPhotos application shown earlier. And how is the service used? The main JFrame constructor in the photo album is as follows, really simplistic as you can see: ... ... ... private PhotoService photo; public PhotoAlbum() { photo = PhotoService.getInstance(); initComponents(); JPanel content = new JPanel(); content.setLayout(new FlowLayout()); Collection coll = photo.getDefinitions(); Iterator it = coll.iterator(); while (it.hasNext()) { Photo photo = it.next(); Icon[] icons = photo.getPhoto(); String[] strings = photo.getDescription(); for (int i = 0; i < icons.length; i++) { JLabel imageLabel = new JLabel(); imageLabel.setBorder(BorderFactory.createLineBorder(Color.red)); Icon icon = icons[i]; String desc = strings[i]; imageLabel.setIcon(icon); imageLabel.setText(desc); content.add(imageLabel); } } setContentPane(content); } ... ... ... And that's really all. Now, what are the benefits of using the NetBeans Platform's org.openide.util.Lookup class instead of the JDK's ServiceLoader class? Lookup is available in versions for older JDKs and thus you can use it as a replacement of ServiceLoader when running on JDKs older than 1.6. Lookup is ready to work inside of the NetBeans runtime container, so makes even more sense when you're working with NetBeans modules. It knows how to discover all the modules in the system, how to effectively read its defined services, and similar activities. Lookup supports listeners. Client code can attach a listener and observe changes in lookup content. This is a necessary improvement to adapt to the dynamic environment created by the NetBeans runtime container, where modules can be enabled or disabled at runtime, which in turn can affect the set of registered service providers. Lookup is extensible and replaceable. While the ServiceLoader class in JDK 1.6 is a final class with hard-coded behavior, the NetBeans Lookup class is an extensible class that allows various implementations. This can be useful while writing unit tests. Or you can write an enhanced version of lookup that not only reads META-INF/services but, for example, finds the requested service providers around the Internet. Lookup is a general purpose abstraction. While the JDK's ServiceLoader can de-facto have just one instance per classloader, there can be thousands of independent Lookup instances, each representing a single place to query services and interfaces. In fact this is exactly the way Lookup is used in NetBeans IDE—it represents the context of each dialog, window element, node in a tree, etc. And now you know all that's needed for treating Java applications as plugins. (For further information, see John O'Conner's Creating Extensible Applications With the Java Platform.) In summary, by means of registration and discovery of classes and interfaces, loosely coupled photo albums, and similar applications, are clearly very easy to achieve.
March 16, 2008
by Geertjan Wielenga
· 47,137 Views
article thumbnail
Understanding Loose Typing in JavaScript
for many front end developers, javascript was their first taste of a scripting and/or interpretive language. to these developers, the concept and implications of loosely typed variables may be second nature. however, the explosive growth in the demand for web 2.0-ish applications has resulted in a growing number of back end developers that have had to dip their feet into pool of client side technologies. many of these developers are coming from a background in strongly typed languages, such as c# and java, and are unfamiliar with both the freedom and the potential pitfalls involved in working with loosely typed variables. since the concept of loose typing is so fundamental to scripting in javascript, an understanding of it is essential. this article is a top level discussion of loose typing in javascript. since there may be subtle differences in loose typing from language to language, let me constrain this discussion to the context of javascript. ok, let's dig in... what is loose typing? well, this seems like a good place to start. it is important to understand both what loose typing is , and what loose typing is not . loose typing means that variables are declared without a type. this is in contrast to strongly typed languages that require typed declarations. consider the following examples: /* javascript example (loose typing) */ var a = 13; // number declaration var b = "thirteen"; // string declaration /* java example (strong typing) */ int a = 13; // int declaration string b = "thirteen"; // string declaration notice that in the javascript example, both a and b are declared as type var. please note, however, that this does not mean that they do not have a type, or even that they are of type "var". variables in javascript are typed, but that type is determined internally. in the above example, var a will be type number and var b will be type string. these are two out of the three primitives in javascript, the third being boolean. javascript also has other types beyond primitives. the type diagram for javascript is as follows (as per mozilla ): ya really - null and undefined too. note, however, that this distinction between primitives and objects will be dismissed in javascript 2.0. you can read more about that here . type coercion type coercion is a topic that is closely associated with loose typing. since data types are managed internally, types are often converted internally as well. understanding the rules of type coercion is extremely important. consider the following expressions, and make sure you understand them: 7 + 7 + 7; // = 21 7 + 7 + "7"; // = 147 "7" + 7 + 7; // = 777 in the examples above, arithmetic is carried out as normal (left to right) until a string is encountered. from that point forward, all entities are converted to a string and then concatenated. type coercion also occurs when doing comparisons. you can, however, forbid type coercion by using the === operator. consider these examples: 1 == true; // = true 1 === true; // = false 7 == "7"; // = true 7 === "7"; // = false; there are methods to explicitly convert a variable's type as well, such as parseint and parsefloat (both of which convert a string to a number). double negation (!!) can also be used to cast a number or string to a boolean. consider the following example: true == !"0"; // = false true == !!"0"; // = true conclusion this obviously is not a definitive reference to loose typing in javascript (or type coercion for that matter). i do hope, however, that this will be a useful resource to those who are not familiar with these topics, and a good refresher for those who already are. i have tried to insure that the above is accurate, but if you notice anything incorrect, please let me know! and as always, thanks for reading!
March 14, 2008
by Jeremy Martin
· 15,444 Views
article thumbnail
DJ NativeSwing - reloaded: JWebBrowser, JFlashPlayer, JVLCPlayer, JHTMLEditor.
Today's release of DJ Native Swing 0.9.4 greatly improves stability and brings new components: in addition to the JWebBrowser and JFlashPlayer, there is now the JVLCPlayer and the JHTMLEditor. Here is a summary of what to expect when using this library. 1. Various native components DJ Native Swing was designed to handle all the complexity of native integration, mainly in the form of components with a simple Swing-like API. Here are some screenshots of several components in action (click to enlarge): JWebBrowser: JFlashPlayer: JVLCPlayer: JHTMLEditor: 2. Simple API First, we need to initialize the framework. This needs to happen before any feature is used. A common place for this call is the first line of the main(): public static void main(String[] args) { NativeInterfaceHandler.init(); // Here goes the rest of the initialization. } Now, let's see how to create a JWebBrowser, with its URL set to Google's homepage: JWebBrowser webBrowser = new JWebBrowser(); webBrowser.setURL("http://www.google.com"); myContentPane.add(webBrowser); Note that we set a URL, but we could as well set the HTML text. The JWebBrowser also allows to execute Javascript calls, and we can even propagate notifications from custom pages to our Swing application. Moving to a more practical example, we may want to be notified of URL change events or track window opening events, potentially preventing navigation to occur or open the page elsewhere. This is easily achieved by attaching a listener: webBrowser.addWebBrowserListener(new WebBrowserAdapter() { public void urlChanging(WebBrowserNavigationEvent e) { String newURL = e.getNewURL(); if(newURL.startsWith("http://www.microsoft.com/")) { // Prevent the navigation to happen. e.consume(); } else { // We can consume the event and decide to open this page in a tab. } } public void windowWillOpen(WebBrowserWindowWillOpenEvent e) { // We can prevent, add the URL to a tab, etc. } // There are of course more events that can be received. }); Let's have a look at the JFlashPlayer: JFlashPlayer flashPlayer = new JFlashPlayer(); flashPlayer.setURL(myFlashURL); The JFlashPlayer can open local or remote Flash files, and files from the classpath; the latter being a general capability of the library by proxying files using a minimalistic web server. Of course, the JFlashPlayer allows to retrieve and set Flash variables, and play/pause/stop the execution. The JVLCPlayer and the JHTMLEditor are no exceptions to this simplicity: playlist can be manipulated in the VLC player, HTML can be set and retrieved from the HTML editor, etc. There is also the possibility to integrate Ole controls on Windows, still with a simple Swing-like API. An example is provided in the library in the form of an embedded Windows Media Player. 3. Advanced capabilities The library takes care of most common integration issues. This covers modal dialog handling, Z-ordering, heavyweight/lightweight mix (to a certain extent), invisible native components with regards to focus handling and threading. Here are some more screenshots, showing a lightweight/heavyweight mix, and Z-ordering capability: The demo application that is part of the distribution shows all the features along with the source code, so check it out! 4. Project info and technical notes Webstart demo: http://djproject.sourceforge.net/ns/DJNativeSwingDemo.jnlp Screenshots: http://djproject.sourceforge.net/ns/screenshots Native Swing: http://djproject.sourceforge.net/ns The DJ Project: http://djproject.sourceforge.net The 0.9.4 version has a completely new architecture. It still uses SWT under the hood, but it does not use the SWT_AWT bridge anymore. The JWebBrowser and browser-based components require XULRunner to be installed, except on Windows when using Internet Explorer. The JVLCPlayer requires VLC to be installed. The JHTMLEditor uses the FCKeditor. 5. Conclusions This project finally brings all that is needed to make Java on the desktop a reality. A web browser, a flash player, a multimedia player, and even an HTML editor. So, what next? Yes, what next? For that one, I am waiting for your feedback. So, what do you think? What are your comments and suggestions? -Christopher
March 12, 2008
by Christopher Deckers
· 54,572 Views
article thumbnail
Easy Multi Select Transfer with jQuery
I'm sure that at some point or another you've encountered a form widget like the one below, allowing options to be traded from one multi select to another. Option 1 Option 2 Option 3 Option 4 add >> << remove I recently encountered a tutorial over at Quirks Mode on creating such a widget. While not a bad script, when all was said and done it was coming up on 40 lines of JS. I suppose that's not horrible, but we're talking about some simple functionality. This struck me as a perfect example to demonstrate the simple and compact nature of jQuery coding. The widget operating above is running off of the following code: $().ready(function() { $('#add').click(function() { return !$('#select1 option:selected').remove().appendTo('#select2'); }); $('#remove').click(function() { return !$('#select2 option:selected').remove().appendTo('#select1'); }); }); That's it... 8 lines. You can also try it out for yourself with the following test page: Option 1Option 2Option 3Option 4 add >> << remove Since the purpose of this widget is usually to collect all the elements in the second multi select, you can use the following snippet to automatically select all of the options before submitting. $('form').submit(function() { $('#select2 option').each(function(i) { $(this).attr("selected", "selected"); }); }); Just make sure you include that snippet inside the $().ready() handler. Thanks for viewing and I hope you found this helpful! Feel free to use and modify without constraint.
March 7, 2008
by Jeremy Martin
· 31,756 Views
article thumbnail
Writing Unit Tests Using Groovy
Groovy can greatly decrease the level of work involved in creating unit tests for your Java code.
March 6, 2008
by Tomas Malmsten
· 57,172 Views
article thumbnail
Log4J the Groovy Way
While developing around, now or then one wants something printed out at the console of his/her IDE.
March 4, 2008
by Gerhard Balthasar
· 61,977 Views
article thumbnail
A Domain-Specific Language for unit manipulations
Domain-Specific Languages are a hot topic, and have been popularized by languages like Groovy and Ruby thanks to their malleable syntax which make them a great fit for this purpose. In particular, Groovy allows you to create internal DSLs: business languages hosted by Groovy. In a recent research work, Tiago Antão has decided to use Groovy to model the resistance to drugs against the Malaria disease. In two blog posts, Tiago explains some of the tactics he used, and how to put them together to create a mini-language for health related studies. In this work, he needed to represent quantities of medecine, like 300 miligram of Chloroquinine, a drug used against Maralia. Groovy lets you add properties to numbers, and you can represent such quantities with just 300.mg. Inspired by this idea, the purpose of this article is to examine how to build a mini-DSL for manipulating measures and units by leveraging the JScience library. First of all, let's speak about JScience. JScience is a Java library leveraging generics to represent various measurable quantities. JScience is also the Reference Implementation for JSR-275: javax.measure.*. Whether it is for measuring mass, length, time, amperes or volts (and many more), the calculations you can do are type-safe and checked at compile-time: you cannot add a second to a kilogram, your program wouldn't compile. This is definitely one of the strength of the library. However fluent the library is, the notation used to represent an amount of some unit is still not as readable as scientist could wish. How do you represent a mass with JScience? import static javax.measure.unit.SI.*; import javax.measure.* import org.jscience.physics.amount.*; // ... Amount m3 = Amount.valueOf(3, KILO(GRAM)); Amount m2 = Amount.valueOf("2 kg"); Amount sum = m3.plus(m2); The first expression leverages static imports to represent the KILO (GRAM) unit, while the second simply parses the mass from a String. The last line does just an addition between the two masses. Still, it doesn't look like what a physicist would write. Wouldn't we want to use a mathematical notation, like 3 kg + 2 kg? We will see how you can do this in Groovy. Our first step will be to add units to numbers. We can't write 2 kg, as it's not valid Groovy, instead, we'll write 2.kg. To so, we'll add some dynamic properties to numbers, thanks to the ExpandoMetaClass mechanism. import javax.measure.unit.* import org.jscience.physics.amount.* // Allow ExpandoMetaClass to traverse class hierarchies // That way, properties added to Number will also be available for Integer or BigDecimal, etc. ExpandoMetaClass.enableGlobally() // transform number properties into an mount of a given unit represented by the property Number.metaClass.getProperty = { String symbol -> Amount.valueOf(delegate, Unit.valueOf(symbol)) } // sample units println( 2.kg ) println( 3.m ) println( 4.5.in ) See how we created kilograms, meters and inches? The "metaclass" is what represents the runtime behavior of a class. When assigning a closure to the getProperty property, all the requests for properties on Numbers will be rooted to this closure. This closure then uses the JScience classes to create a Unit and an Amout. The delegate variable that you see in this closure represents the current number on which the properties are accessed. Okay, fine, but at some point, you'll need to multiply these amounts by some factor, or you will want to add to lengths together. So we'll need to do leverage Groovy's operator overloading to do some arithmetics. Whenever you have methods like multiply(), plus(), minus(), div(), or power(), Groovy will allow you to use the operators *, +, -, /, or **. Some of the conventions for certain of these operations being a bit different from those of Groovy, we have to add some new operator methods for certain of these operations: // define opeartor overloading, as JScience doesn't use the same operation names as Groovy Amount.metaClass.multiply = { Number factor -> delegate.times(factor) } Number.metaClass.multiply = { Amount amount -> amount.times(delegate) } Number.metaClass.div = { Amount amount -> amount.inverse().times(delegate) } Amount.metaClass.div = { Number factor -> delegate.divide(factor) } Amount.metaClass.div = { Amount factor -> delegate.divide(factor) } Amount.metaClass.power = { Number factor -> delegate.pow(factor) } Amount.metaClass.negative = { -> delegate.opposite() } // arithmetics: multiply, divide, addition, substraction, power println( 18.4.kg * 2 ) println( 1800000.kg / 3 ) println( 1.kg * 2 + 3.kg / 4 ) println( 3.cm + 12.m * 3 - 1.km ) println( 1.5.h + 33.s - 12.min ) println( 30.m**2 - 100.ft**2 ) // opposite and comparison println( -3.h ) println( 3.h < 4.h ) We can also do comparisons, as shown on the last line above, since these types are comparable. Again, free of charge. Something we have covered yet is compound units, such as speed, which is a mix of a distance and a duration. So, if you wanted to use a speed limit, you would like to write 90.km/h but our DSL in its current state would only allow you to write 90.km/1.h, which doesn't really look nice. To circumvent this issue, we could create as many variables as units. We could have a h variable, a km variable, etc. But I'd prefer something more automatic, by letting the script itself provide these units. In Groovy scripts, you can have local variables (whenever you define a variable, it's a local variable), but you can also pass or access variables through a binding. This is a convenient way to pass data around when you integrate Groovy inside a Java application, for instance, to share a certain context of data. We are going to create a new Binding called UnitBinding which will override the getVariable() method, so that all non-local variables which are used withing the Groovy script are looked up in this binding. You'll notice a special treatment for the variable 'out', which is where the println() method looks for for the output stream to use. // script binding to transform free standing unit reference like 'm', 'h', etc class UnitBinding extends Binding { def getVariable(String symbol) { if (symbol == 'out') return System.out return Amount.valueOf(1, Unit.valueOf(symbol)) } } // use the script binding for retrieving unit references binding = new UnitBinding() // inverse units println( 30.km/h + 2.m/s * 2 ) println( 3 * 3.mg/L ) println( 1/2.s - 2.Hz ) The velocity now looks much more like the mathematical notation everybody would use. Now that all this magic is done, there's still one last thing we could do. Sometimes, you may want to convert different units, like feet and meters or inches and centimers. So, as the last step of our units DSL experiments, we'll add a to() method to do convertions. // define to() method for unit conversion Amount.metaClass.to = { Amount amount -> delegate.to(amount.unit) } // unit conversion println( 200.cm.to(ft) ) println( 1.in.to(cm) ) At this point, we are able to easily manipulate amounts of any unit in a very convenient and natural notation. The magic trick of adding properties to numbers makes the process of creating a unit DSL straightforward. This DSL is just a small part of the equation, as you may certainly want to represent other business related concepts, but this article will have shown you how to decorate a powerful existing library, so that the code becomes more natural to use by the end users of your DSL. In further articles, we'll discover some other tricks! Stay tuned!
March 1, 2008
by Guillaume Laforge
· 35,065 Views
article thumbnail
Who Needs EJB 3.1 (lite)?
There is an interesting statement about technologies dedicated to a given profile in the J2EE 6 spec. You may have noticed the descriptions of something called EJB 3.1 (lite). "EJB 3.1 (Lite)" refers to the idea of allowing implementations to deliver a subset of EJB 3.1. The contents of this "lite" subset are wholly undecided at this point, but as an example it might include the annotation-based programming model introduced in EJB 3.0, restricted to session beans with local interfaces (only). In other words, you could write an annotated session bean with a local interface and use it in your Web Profile-compliant product (assuming (B) is accepted, that is). But, for example, you could not write a EJB 2.1-style session bean, or an EJB 3.0 message-driven bean, or a EJB 3.0 stateful session bean with a remote interface. It seems that someone is obsessed with EJB. I don't see any advantage of EJB 3.1 (Lite) over POJO except complications that affect everyone. deployment and packaging - WAR vs EJB JAR, classloader isolation etc. need for an application server - forget about Tomcat or Jetty complexity overhead - you still need a lot of about EJB as a bean lifecycle, transaction, JNDI etc. From a developer's point of view there isn't much difference between EJB full and EJB lite. Both of them bring the same level of complexity and make development more complicated. I don't think that EJB 3.1 could be useful for developers. So, who really needs this EJB 3.1 lite?
March 1, 2008
by Roman Pichlik
· 19,915 Views
article thumbnail
Effective Eclipse: Custom Templates
The same way I try to avoid the redundancy in my code, the same way I try to avoid the redundancy in my writing. I am lazy and templates do the most writing for me. Eclipse comes bundled with predefined templates, but they are too general and not all of them are too useful. The real power is in custom templates. In this article I would like to show you how to create them and list a few useful pieces for inspiration. What are templates Exactly as the name suggests, templates are little pieces of code with defined placeholders. An example of simple template is System.out.println(${text}); Each template has a name, which serves as a shortcut to the template itself. You type the name, press CTRL + SPACE and it will be expanded. Our first template would expand to [img_assist|nid=1424|title=|desc=|link=none|align=middle|width=186|height=19] I will not explain here what it all means, I already did this in my previous post on templates. What is important now, is that the ${text} placeholder (variable) was highlighted and can be edited immediately. The true power of templates can be fully seen in more complex templates. The first power point lies in the fact, that you can have more than one variable with same name. Our second template will have more variables: int ${increment} = ${value}; y = ${increment} + ${increment}; and will expand to [img_assist|nid=1428|title=|desc=|link=none|align=middle|width=204|height=45] When you start typing now, all occurrences of increment variable will be changed. You can then switch to the next variable by pressing TAB key. In the end, you can have [img_assist|nid=1425|title=|desc=|link=none|align=middle|width=110|height=43] in just three key presses - one for i, one for TAB and one for 2. To make it even better, the template system provides predefined variables, which will be expanded depending on their context. I will not list them, you can find them under the Insert variable button. [img_assist|nid=1426|title=|desc=|link=popup|align=middle|width=640|height=274] Notice, that you are not getting only a list, you are also getting a description and an usage example. To make it clear, I will illustrate one builtin variable - ${enclosing_type}. When this one is expanded you will get a name of the class (or interface, enum) in which your template was expanded. "But how can I use it?", I hear you asking. I have prepared few templates just for inspiration, I believe that after reading this you will find thousands others and I believe that you will create them and share them with us. Custom templates Open Window -> Preferences and type Templates into the search box. [img_assist|nid=1427|title=|desc=|link=popup|align=middle|width=640|height=578] You will get a list of all editors, and their respective template settings. This is because templates are closely bound to editors - you will get different builtin variables in different editors. Also note, that your list may vary from my list, it all depends on installed plugins. Now you must decide what type of template you would like to create. If it is a Java template, which will be applicable in context of classes, interfaces and enums, then choose Java -> Editor -> Templates. If you create a Java template you won't be able to use it in XML editor, that's quite expected. So click on the New button, to get a dialog. Here it is, in all its glory: [img_assist|nid=1430|title=|desc=|link=popup|align=middle|width=640|height=316] Name is the name of the template. Choose it well, because it will serve as a shortcut to your template. After you type the name of the template (or at least a few characters from its name) and hit CTRL+SPACE it will be expanded. Description is what you will see next to the template name when the template name is ambiguous. [img_assist|nid=1433|title=|desc=|link=none|align=middle|width=415|height=296] Pattern is the template body. And the Context? This varies in every editor. If you look in the combobox in Java templates, you will see Java and Javadoc. It is simple a context within the respective editor in which the template would be applicable. Check Automatically insert if you want the template to expand automatically on ctrl-space when there is no other matching template available. It is usually good idea to leave the checkbox checked, otherwise you would get a template proposal "popup". See what happens when I uncheck it on sysout template. [img_assist|nid=1432|title=|desc=|link=none|align=middle|width=256|height=46] If I would have checked it, it would automatically expand, as there is no other template matching sysout* pattern. My list So here is the list I promised. I have categorized it. Java (Java->Editor->Templates) logger - create new Logger private static final Logger logger = Logger.getLogger(${enclosing_type}.class.getName()); Notice the usage of ${enclosing_type} variable. This way you can create a logger in few hits. After the template expands, you will probably get red lines, indicating that Logger clas could not be found. Just hit CTRL + SHIFT + O to invoke the organize imports function. You are using shortcuts, aren't you? loglevel - log with specified level if(${logger:var(java.util.logging.Logger)}.isLoggable(Level.${LEVEL})) { ${logger:var(java.util.logging.Logger)}.${level}(${}); } ${cursor} Let me explain the details. ${logger:var(java.util.logging.Logger)} uses a builtin "var" variable. It starts with logger, the default name, in case the var variable finds no match. It is then followed by var(java.util.logging.Logger), what will evaluate to the name of the variable (member or local) of the specified type (in our case of the Logger type). Further, the ${cursor} variable marks the place where the cursor will jump after you press enter. So the result after expanding could be [img_assist|nid=1429|title=|desc=|link=none|align=middle|width=297|height=66] You might wonder what is the purpose of the if. It is there only for performance gain. If specified level is not allowed the logging method will never be called and we can spare JVM some string manipulation to build the message. readfile - read text from file Never can remember how to open that pesky file and read from it? Nor can I, so I have a template for it. BufferedReader in; try { in = new BufferedReader(new FileReader(${file_name})); String str; while ((str = in.readLine()) != null) { ${process} } } catch (IOException e) { ${handle} } finally { in.close(); } ${cursor} Maven (Web and XML -> XML Files -> Templates) dependency - maven dependency ${groupId} ${artifactId} ${version} ${cursor} parent - maven parent project definition ${artifactId} ${groupId} ${version} {$path}/pom.xml ${cursor} web.xml (Web and XML -> XML Files -> Templates) servlet - new servlet definition ${servlet_name} ${servlet_class} ${0} ${servlet_name} *.html ${cursor} JSP pages (Web and XML -> JSP Files -> Templates) spring-text - spring text field with label and error ${cursor} spring-checkbox ${cursor} spring-select ${cursor} spring-generic ${cursor} These are my favorites. They regularly save me a huge amount of time. Creating spring forms has never been easier for me. In some editor types you can set the template to 'new', for example, in XML editor it is new XML. This is really useful, as you can prepare the skeleton of a new file. For example, this is what I use to create new Spring servlet configuration for freemarker application. true messages Now, I can create new XML file from template and it will be ready to use. Before I knew about templates, I used to copy this from an older project, or search for it in Spring documentation. Now I don't have to.. [img_assist|nid=1431|title=|desc=|link=none|align=middle|width=640|height=201] If you can overcome the initial laziness and create your own templates from the pieces of code you really use, than this investment will shortly return in form of less typing. If you have some interesting templates, please, share them with us. You can download the templates mentioned in this post and import them using the Import button in the editor template settings.
February 28, 2008
by Tomas Kramar
· 232,715 Views · 1 Like
article thumbnail
Ruby: Escape, Unescape, Encode, Decode, HTML, XML, URI, URL
This example will show you how to escape and un-escape a value to be included in a URI and within HTML. require 'cgi' # escape name = "ruby?" value = "yes" url = "http://example.com/?" + CGI.escape(name) + '=' + CGI.escape(value) + "&var=T" # url: http://example.com/?ruby%3F=yes&var=T html = %(example) # html: example # unescape name_encoded = html.match(/http:([^"]+)/)[0] # name_encoded: http://example.com/?ruby%3F=yes&var=T href = CGI.unescapeHTML(name_encoded) # href: http://example.com/?ruby%3F=yes&var=T query = href.match(/\?(.*)$/)[1] # query: ruby%3F=yes&var=T pairs = query.split('&') # pairs: ["ruby%3F=yes", "var=T"] name, value = pairs[0].split('=').map{|v| CGI.unescape(v)} # name, value: ["ruby?", "yes"]
February 26, 2008
by Snippets Manager
· 4,023 Views
article thumbnail
SVNKit: Tame Subversion with Java!
SVNKitis an Open Source pure Java Subversion library. SVNKit literally brings Subversion, popular open source version control system, to the Java world. With SVNKit you can do the following: All standard Subversion operations: For instance, the following snipped checks out project from repository: File dstPath = new File("c:/svnkit"); SVNURL url = SVNURL. parseURIEncoded("http://svn.svnkit.com/repos/svnkit/branches/1.1.x/"); SVNClientManager cm = SVNClientManager.newInstance(); SVNUpdateClient uc = cm.getUpdateClient(); uc.doCheckout(url, dstPath, SVNRevision.UNDEFINED, SVNRevision.HEAD, true); Updates it to the latest revision: uc.doUpdate(dstPath, SVNRevision.HEAD, true); And finally commits local changes in "www" subdirectory if there are any: SVNCommitClient cc = cm.getCommitClient(); cc.doCommit(new File[] {new File(dstPath, "www")}, false, "message", false, true); SVNKit supports all standard Subversion operations and compatible with the latest version of Subversion. Access Subversion repository directly: Some applications will benefit from working with repository directly, without keeping working copy locally. Example below displays list of files in "www" directory. SVNURL url = SVNURL.parseURIEncoded("http://svn.svnkit.com/repos/svnkit/branches/1.1.x/"); SVNRepository repos = SVNRepositoryFactory.create(url); long headRevision = repos.getLatestRevision(); Collection entriesList = repos.getDir("www", headRevision, null, (Collection) null); for (Iterator entries = entriesList.iterator(); entries.hasNext();) { SVNDirEntry entry = (SVNDirEntry) entries.next(); System.out.println("entry: " + entry.getName()); System.out.println("last modified at revision: " + entry.getDate() + " by " + entry.getAuthor()); } Direct repository access API allows to perform operations like update, commit, diff and many other. Additionaly to the performance benefits of the direct access to repository, this API makes it possible to version arbitrary objects or object models within Subevrsion repository, not only files from the file system. Replace JNI Subversion bindings with SVNKit: Native Subversion provides Java interface that works with Subversion binaries through JNI. In case you already using it or would like to use as an option, you may also use SVNKit through exactly the same interface. This way you'll let your application dynamically switch between JNI and SVNKit implementation of the same API or let your application work on the platforms where there are no native Subversion binaries. For example: // pure Java implementation of the standard Subversion Java interface SVNClientInterface jniAPI = SVNClientImpl.newInstance(); byte[] contents = jniAPI.fileContent("http://svn.svnkit.com/repos/svnkit/branches/1.1.x/changelog.txt", Revision.HEAD); SVNKit is widely used in different applications, including IntelliJ IDEA, Eclipse Subversion integrations, SmartSVN, JDeveloper, bug tracking server side applications (e.g. Atlassian JIRA) and repository management and tracking tools (e.g. Atlassian FishEye) and many others. Where to get more information: Recently we've released SVNKit version 1.1.6 which is bugfix release. At http://svnkit.com/ you will find more information on that new version and, of course, downloads, documentation, source code example and articles explaining how to use SVNKit. In case of any questions you're welcome at our mailing list, or just contact us at [email protected] SVNKit is widely used in different applications, including IntelliJ IDEA, Eclipse Subversion integrations, SmartSVN, JDeveloper, bug tracking server side applications (e.g. Atlassian JIRA) and repository management and tracking tools (e.g. Atlassian FishEye) and many others. With best regards, TMate Software, http://svnkit.com/ - Java [Sub]Versioning Library!
February 26, 2008
by Alexander Kitaev
· 11,335 Views · 2 Likes
article thumbnail
Creating an "Body Border" with CSS
hicksdesign has been " fiddling " with their site design. the new design features what someone called in the comments a "body border". it's basically a stroke of color just inside the entire viewable area, all the way around, in the browser window. i thought it was a nice touch and a pretty spiffy little css trick so i thought i'd feature how it was done here. check out the example page . the code four unique page elements are neccecery. div's work fine for this: here is the css for them. notice how clean the css can be. some properties are shared by all of the elements, some by only the top/bottom and left/right, and some unique to themselves. this css is coded like that, instead of repeating properties and values unnecessarily. #top, #bottom, #left, #right { background: #a5ebff; position: fixed; } #left, #right { top: 0; bottom: 0; width: 15px; } #left { left: 0; } #right { right: 0; } #top, #bottom { left: 0; right: 0; height: 15px; } #top { top: 0; } #bottom { bottom: 0; } browser compatibility works great in firefox, safari, and opera, and ie 7. does it work in ie 6 (or below)? of course not! mostly has to do with positioning. ie 6 doesn't love fixed positioning and the hacks i find ugly and not terribly reliable. the solution is just to ditch the body border for ie: header html for conditional stylesheet (put comment tags around this in use): [if lte ie 6]>
February 26, 2008
by Chris Coyier
· 29,187 Views
article thumbnail
Let's Create a Tetris Game in Compiled JavaFX Script
i thought it would be fun to spend a few posts creating a tetris game in compiled javafx script together. today i made a rough start on it, and if you promise not to laugh, i'll show you the humble beginnings. here's a screenshot of its current status: in tetris, there are several types of tetrominoes , each having a letter that it resembles. the four buttons on the left represent four of these shapes. when you press one of these buttons, the corresponding tetromino appears at the top and begins moving down the screen. when you click the rotate button, the tetromino rotates to the right, and the left / right buttons move the tetromino left and right, respectively. the code is contained in four fx program files, and needs some refactoring already. :-) before showing you the code in its current state, i'd like to point out a couple of helpful things: as explained in the spinning wheel post, the key frame animation syntax that you see here will become much less verbose as the javafx script compiler team continues to address animation. javafx script programs should always be designed with the ui binding to a model. in this program, the model is represented in one class named tetrismodel , located in the fx file of the same name. you may find it helpful to take a look the creating a compiled javafx script program with multiple fx source files post to see a hello world style program that has more than one fx file. please notice the package statments in this tetris program, as that influences where you need to put the source files and how you build them. you can obtain the javafx compiler by following the instructions in the obtaining the openjfx script compiler post. the source code (so far) here's the main program, named tetrismain.fx , that declaratively expresses the ui, and starts things up: /* * tetrismain.fx - the main program for a compiled javafx script tetris game * * developed 2008 by james l. weaver (jim.weaver at lat-inc.com) * to serve as a compiled javafx script example. */ package tetris_ui; import javafx.ui.*; import javafx.ui.canvas.*; import java.lang.system; import tetris_model.*; frame { var model = tetrismodel { } var canvas:canvas width: 480 height: 500 title: "tetrisjfx" background: color.white content: borderpanel { center: canvas = canvas {} bottom: flowpanel { content: [ button { text: "i" action: function() { canvas.content = []; insert tetrisshape { model: model shapetype: tetrisshapetype.i } into canvas.content; model.t.start(); } }, button { text: "t" action: function() { canvas.content = []; insert tetrisshape { model: model shapetype: tetrisshapetype.t } into canvas.content; model.t.start(); } }, button { text: "l" action: function() { canvas.content = []; insert tetrisshape { model: model shapetype: tetrisshapetype.l } into canvas.content; model.t.start(); } }, button { text: "s" action: function() { canvas.content = []; insert tetrisshape { model: model shapetype: tetrisshapetype.s } into canvas.content; model.t.start(); } }, button { text: "rotate" action: function() { model.rotate90(); } }, button { text: "left" action: function() { model.moveleft(); } }, button { text: "right" action: function() { model.moveright(); } } ] } } visible: true onclose: function():void { system.exit(0); } } i made the tetrisshape class a custom graphical component. therefore, it is a subclass of the compositenode class, and overrides the composenode function. note: there is a typo in line 62 of the tetrisshape.fx listing. "returnreturn" should read "return". it will be corrected asap. /* * tetrisshape.fx - a tetris piece, configurable to the * different shape types. they are: * i, j, l, o, s, t, and z * * developed 2008 by james l. weaver (jim.weaver at lat-inc.com) * to serve as a compiled javafx script example. * */ package tetris_ui; import javafx.ui.*; import javafx.ui.canvas.*; import java.awt.point; import java.lang.system; import tetris_model.*; class tetrisshape extends compositenode { private static attribute squareoutlinecolor = color.black; private static attribute squareoutlinewidth = 2; private attribute squarecolor; public attribute model:tetrismodel; public attribute shapetype:tetrisshapetype on replace { if (shapetype == tetrisshapetype.i) { squarelocs = []; insert new point(0, model.square_size * 1) into squarelocs; insert new point(0, 0) into squarelocs; insert new point(0, model.square_size * 2) into squarelocs; insert new point(0, model.square_size * 3) into squarelocs; squarecolor = color.red; } else if (shapetype == tetrisshapetype.t) { squarelocs = []; insert new point(model.square_size * 1, 0) into squarelocs; insert new point(0, 0) into squarelocs; insert new point(model.square_size * 2, 0) into squarelocs; insert new point(model.square_size * 1, model.square_size * 1) into squarelocs; squarecolor = color.green; } else if (shapetype == tetrisshapetype.l) { squarelocs = []; insert new point(0, model.square_size * 1) into squarelocs; insert new point(0, 0) into squarelocs; insert new point(0, model.square_size * 2) into squarelocs; insert new point(model.square_size * 1, model.square_size * 2) into squarelocs; squarecolor = color.magenta; } else if (shapetype == tetrisshapetype.s) { squarelocs = []; insert new point(model.square_size * 1, 0) into squarelocs; insert new point(model.square_size * 2, 0) into squarelocs; insert new point(0, model.square_size * 1) into squarelocs; insert new point(model.square_size * 1, model.square_size * 1) into squarelocs; squarecolor = color.cyan; } } private attribute squarelocs:point[]; public function composenode():node { return group { transform: bind [ translate.translate(model.square_size * model.tetrominohorzpos, (model.a / model.square_size).intvalue() * model.square_size), rotate.rotate(model.tetrominoangle, squarelocs[0].x + model.square_size / 2, squarelocs[0].y + model.square_size / 2) ] content: [ for (squareloc in squarelocs) { rect { x: bind squareloc.x y: bind squareloc.y width: bind model.square_size height: bind model.square_size fill: bind squarecolor stroke: squareoutlinecolor strokewidth: squareoutlinewidth } } ] }; } } the tetrisshapetype class defines the tetromino types: /* * tetrisshapetype.fx - a tetris shape type, which are * i, j, l, o, s, t, and z * * developed 2008 by james l. weaver (jim.weaver at lat-inc.com) * to serve as a compiled javafx script example. * */ package tetris_ui; import javafx.ui.*; class tetrisshapetype { public attribute id: integer; public attribute name: string; public static attribute o = tetrisshapetype {id: 0, name: "o"}; public static attribute i = tetrisshapetype {id: 1, name: "i"}; public static attribute t = tetrisshapetype {id: 2, name: "t"}; public static attribute l = tetrisshapetype {id: 3, name: "l"}; public static attribute s = tetrisshapetype {id: 4, name: "s"}; } and finally, here's a model class, named tetrismodel: /* * tetrismodel.fx - the model behind the tetris ui * * developed 2008 by james l. weaver (jim.weaver at lat-inc.com) * to serve as a compiled javafx script example. * */ package tetris_model; import javafx.ui.animation.*; import java.lang.system; import com.sun.javafx.runtime.pointerfactory; public class tetrismodel { public static attribute square_size = 20; public attribute a:integer; private attribute pf = pointerfactory {}; private attribute bpa = bind pf.make(a); private attribute pa = bpa.unwrap(); private attribute interpolate = numbervalue.linear; public attribute t = timeline { keyframes: [ keyframe { keytime: 0s; keyvalues: numbervalue { target: pa; value: 0; interpolate: bind interpolate } }, keyframe { keytime: 20s; keyvalues: numbervalue { target: pa; value: 370 interpolate: bind interpolate } } ] }; public attribute tetrominoangle:number; public attribute tetrominohorzpos:number = 10; public function rotate90():void { (tetrominoangle += 90) % 360; } public function moveleft():void { if (tetrominohorzpos > 0) { tetrominohorzpos--; } } public function moveright():void { if (tetrominohorzpos < 20) { //todo:replace 10 with a calculated number tetrominohorzpos++; } } } compile and execute this example, and examine the code. i'll get busy making it behave a little more like a tetris game, and show you some progress in the next post. please feel free to get ahead of me, and make your own version! regards, jim weaver javafx script: dynamic java scripting for rich internet/client-side applications immediate ebook (pdf) download available at the book's apress site
February 22, 2008
by James Weaver
· 17,642 Views
  • Previous
  • ...
  • 888
  • 889
  • 890
  • 891
  • 892
  • 893
  • 894
  • 895
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×