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 Java Topics

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
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,336 Views · 2 Likes
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
article thumbnail
VisualVM: Free and Open Source Java Troubleshooter
Trying to troubleshoot Java? VisualVM is a great, free, open source tool.
February 21, 2008
by Geertjan Wielenga
· 69,545 Views
article thumbnail
Lorem Ipsum: Now Generated in Java
February 14th, the international day of sweet nothings, saw the release of Lorem Ipsum for Java, the new Java generator of space filler text. Never again will you need to put "aaaaa" in a demo field, or "xxxx", or something similar. Instead, you will be able to ooze the air of the Greeks of old, by generating text into your otherwise bare ui. And all that text will not need to have been typed, or copy/pasted, or anything similar. Instead, you will be able to use Java itself to generate the above filler text. The above 5 paragraphs of high minded mumbo jumbo came about like this: LoremIpsum ipsum = new LoremIpsum(); String words = ipsum.getParagraphs(5); And the lorem ipsum library is quite versatile: So not only can you choose to generate either words or paragraphs, but the exact number of words and paragraphs can also be specified. Here's looking forward to seeing lorem ipsumized space fillers in all the demos of the future!
February 18, 2008
by Geertjan Wielenga
· 15,507 Views
article thumbnail
Plugging into Lobo's Pure Java Web Browser
Lobo's Java Web Browser, still at a dot zero release, drew my attention today because it very recently was Java Posse's project of the week. I love the fact that this browser is pure Java! Plus, it is open source and under active development. Let's help things along by explaining how to create plugins, because this project is smart enough to expose an API for this purpose. At the end of this article, you'll be able to start up the Lobo browser and you will then see a new menu, with a new menu item, that will produce a "Hello World" greeting in a JOptionPane. It will all look thusly: Even though there is no "Hello world" document for Lobo plugin development (which I am hoping to remedy by means of this article), the Lobo Browser Plugin HOWTO provides most of the information you need. It is all quite intuitive, once you have the basics. Here they are: After you download the Lobo distro, put its lobo-pub.jar on your plugin-to-be's classpath. At a bare minimum, you need a class that extends org.lobobrowser.ua.NavigatorExtension. Here's mine, just to give you an idea. Note the overrides, of course, because these are the main hooks into the browser: public class ExtensionImpl implements NavigatorExtension { private JMenu menu; private JMenuItem item; @Override public void init(NavigatorExtensionContext ctx) {} @Override public void windowOpening(NavigatorWindow window) { menu = new JMenu("Greetings"); item = new JMenuItem("Hello"); menu.add(item); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { JOptionPane.showMessageDialog(null, "hello world"); } }); window.addMenu("Demo", menu); } @Override public void windowClosing(NavigatorWindow window) {} @Override public void destroy() {} } That's all we need for our small scenario. Since we're simply using Swing, it is easy to imagine other things that you might do when the window opens/closes, etc. Use code completion and other tools in your IDE to figure out other things you might be able to do to the Lobo browser: Now create a properties file called lobo-extension.properties, in your src structure, at the highest level, and add the following info: extension.name=Demo Lobo Extension extension.description=This is a demo extension extension.by=Geertjan Wielenga extension.version=0.1 extension.class=demoloboplugin.ExtensionImpl extension.priority=4 The extension class is the one shown in step 2, registered by its FQN. The priority is described in the API docs, it's not so important at this stage, since w're just doing a hello world scenario. Finally, you'll have a plugin that looks similar to this: Now compile the plugin, creating a JAR that you put in the distro's ext folder. Below, mine is called "DemoLoboPlugin.jar": Just restart the browser and there's your new menu. Since it is this easy to extend the browser, I'm hoping this intro has grabbed your imagination and that you'll support this super cool browser. If you love Java, you'll love this browser. Downloading the distro and setting things up was as simple as unjarring and then running java -jar from the command line. Here's hoping that the people behind this project will publish MANY small samples demonstrating the ways in which the browser can be extended. That way, they'd be giving developers handholds to making this browser all that it should be.
February 6, 2008
by Geertjan Wielenga
· 34,305 Views
article thumbnail
How to Add Resize Functionality to Visual Applications in Java?
In How to Create Visual Applications in Java?, I introduced you to the NetBeans Visual Library, specifically in the context of standard Java SE applications. Here we continue where we left off, but we add resize functionality... in very few lines of code! At the end of the previous article, it was clear that (a) the NetBeans Visual Library is a very powerful framework for creating graphical widgets (for example, to make a widget move, you simply add one line of code), (b) one doesn't need the NetBeans Platform even though one is using one of its libraries and (c) one doesn't even need NetBeans IDE, even though one could do so, of course, but only if one wanted to do so. Simply put, you just download NetBeans IDE once, remove two of its JARs and then, if that's how you feel, you can remove NetBeans IDE completely. Next, simply put those two JARs on your classpath and you're good to go. At the end of that article, we had created Chuk, one of the Sun evangelists, as a movable object with an editable label text field. We then also created Gregg, who is also a Sun evangelist, as another instance of the same object: However, there was one problem with the above scenario, at least, according to Gregg: "Hey, how come Chuk's picture is larger?" That's the message he left in my blog, where I had also discussed this scenario in detail. So, this time, we're going to help Gregg. (So, all of this is for you, Gregg!) We're going to do two things, both of which are really cool, mostly undocumented, and illustrative of a whole host of things, as you'll discover if you stick with this article until the very end. At the end, when your mouse moves over a widget, its borders will become resizable. Then, when you drag the handles on the border, the image will resize itself according to the movement of the mouse. So, you'll be able to make Chuk a whole lot smaller. And, Gregg can be made bigger (or smaller still): Let's begin by asking ourselves how to create that border with the handles, i.e., the one that, when you see it, you think: "I am now able to resize something". Probably lots of code, right? Wrong. The Visual Library extends the borders offered by the JDK's Border classes. It provides a package called org.netbeans.api.visual.border.BorderFactory and another called org.netbeans.api.visual.border.Border. (I learned about all of this from Fabrizio Giudici's Creative Uses of the Visual Library, a document which I highly recommend.) Here we begin by declaring two constants, one for a normal border and one for resizing: private static final Border RESIZE_BORDER = BorderFactory.createResizeBorder(8,Color.BLACK,true); private static final Border DEFAULT_BORDER = BorderFactory.createEmptyBorder(8); Even though our default border is empy, we set its thickness to 8, so that the area reserved for our border is the same for both. (If you experiment later, you'll see that if you don't set a thickness, strange effects result when the resize border is enabled/disabled.) Now that we have our borders, we need to specify when they should be shown. To do this, we create a class that extends IconNodeWidget, unlike the last time where we were extending GraphScene and then creating new nodes in attachNodeWidget. Creating a separate class gives us more room to maneouvre, allowing us to add a lot of behavior to an individual widget. Here we call our widget PhotoWidget, we expect to receive the scene, an image, and a name. We assign those to the widget's label and image. We then add, as before, the MoveAction, so that the widget can move. (Just one line of code and no listeners!) We also, for the first time, add the HoverAction, which will make the widget sensitive to our mouse, as it hovers over it: private static final class PhotoWidget extends IconNodeWidget { public PhotoWidget(Scene scene, Image pic, String name) { super(scene); setLabel(name); setImage(pic); setPreferredLocation(new Point(10, 20)); getActions().addAction(ActionFactory.createMoveAction()); getActions().addAction(scene.createWidgetHoverAction()); } @Override public void notifyStateChanged(ObjectState previousState, ObjectState newState) { super.notifyStateChanged(previousState, newState); getImageWidget().setBorder( newState.isSelected() ? ( newState.isHovered() ? RESIZE_BORDER : DEFAULT_BORDER) : ( newState.isHovered() ? RESIZE_BORDER : DEFAULT_BORDER)); } } Finally, notice that we have overridden IconNodeWidget.notifyStateChanged, which will determine whether our border will be shown! And that depends on our calculations in the setBorder method, which returns a border, as calculated above. If the widget is selected or hovered over, the border changes. Currently, however, even though the border changes, the image doesn't resize when we drag the border's handles. To be able to do that, we need to add four lines of additional code, just lines 7-10 below: public PhotoWidget(Scene scene, Image pic, String name) { super(scene); setLabel(name); setImage(pic); setPreferredLocation(new Point(10, 20)); //Add lines 7-10 below: setLayout(LayoutFactory.createVerticalFlowLayout(LayoutFactory.SerialAlignment.JUSTIFY, 1)); setChildConstraint(getImageWidget(), 1); setCheckClipping(true); getImageWidget().getActions().addAction(ActionFactory.createResizeAction()); getActions().addAction(ActionFactory.createMoveAction()); getActions().addAction(scene.createWidgetHoverAction()); } It is very important that the ResizeAction appear BEFORE the MoveAction, otherwise the MoveAction will consume the event, which will result in your resize gesture causing a move action instead. Also note that we don't resize the WHOLE widget, but just the image. The other three lines change the layout and grab the image, such that they can be resized. We set the clipping check to true, so that the image is clipped as it resizes, otherwise bits of it would remain as we resized. At this point, I should reveal that the above doesn't actually work, because of a known issue in the Visual Library. Guided by David Kaspar, the creator of the library, I hacked the sources of the library to make it work. You can do the same. Just attach the sources to your project, instead of the JAR. Then find ImageWidget.paintWidget and change this line: gr.drawImage(image, 0, 0, observer); ...to these lines: Rectangle bounds = getBounds(); gr.drawImage(image, bounds.x, bounds.y, bounds.width, bounds.height, 0, 0, width, height, observer); Now that your image has bounds, it can be resized. You'll have to make this change in the sources yourself too, until the issue is fixed, hopefully soon. Just to recap, starting from last time, we have a JFrame with a JScrollPane. We've added a Visual Library "scene" to the JScrollPane. Then we added a LayerWidget to which we added two IconNodeWidgets. Both can move, they're sensitive to hovering, they have names, and images. And now the IconNodeWidgets get new resize borders when hovered over. And the handles on those borders can be dragged to resize the widget, including its image. For the record, here is our constructor, together with our declarations at the top of the class: private static final Border RESIZE_BORDER = BorderFactory.createResizeBorder(8, Color.BLACK, true); private static final Border DEFAULT_BORDER = BorderFactory.createEmptyBorder(8); private LayerWidget mainLayer; private Image CHUK = Utilities.icon2Image( new ImageIcon(getClass().getResource("/demo/chuk.png"))); private Image GREGG = Utilities.icon2Image( new ImageIcon(getClass().getResource("/demo/gregg.png"))); public DemoVisualFrame() { Scene scene = new Scene(); initComponents(); jScrollPane1.setViewportView(scene.createView()); mainLayer = new LayerWidget(scene); scene.addChild(mainLayer); mainLayer.addChild(new PhotoWidget(scene, CHUK, "Chuk")); mainLayer.addChild(new PhotoWidget(scene, GREGG, "Gregg")); } Hope you're happy now Gregg!
February 5, 2008
by Geertjan Wielenga
· 44,839 Views
article thumbnail
How to Create Visual Applications in Java?
My excellent colleague Java evangelist Chuk Munn Lee wrote me an e-mail in response to my description yesterday of how to create JConsole plugins: "I did not know that the visual library can be used outside of NetBeans. Do you need a special build of the library? Do I need to build it myself or is there a standalone version that I can download?" This is a good question and the answer is illustrative of how interwoven NetBeans IDE is with the NetBeans Platform. Look in your NetBeans installation folder and you'll find a folder called "platform7", with this content: In other words, literally, the content of the folder above is the NetBeans Platform. Many of the JARs that make up the NetBeans Platform can be used outside a NetBeans Platform application. Last October I wrote about this, in a blog entry entitled NetBeans APIs Outside of the NetBeans Platform. Follow the steps in that tutorial and you'll have a standard Java application that makes use of some of the typical JARs from the NetBeans Platform. In other words, several typical scenarios developed on the NetBeans Platform can also be developed outside of it. Another similar scenario is illustrated in the article I wrote yesterday, How to Get Started with JConsole Plugins, where the Visual Library API is used to inject some graph functionality into the JConsole. And so, in response to Chuk's questions "Do you need a special build of the library? Do I need to build it myself or is there a standalone version that I can download?", the answer is: "No, you don't." Download NetBeans IDE, take the two JARs that are highlighted in the screenshot above, put them on your app's classpath, and you're ready to create visual Java applications: Let's get started for real now. To create visual applications, you need some kind of Swing container within which you need a JScrollPane. Then you create your visual "scene" within that JScrollPane. There are several interesting classes that you can extend to make your visual application. Have a look at the Javadoc or take a stroll through the tutorial, though not all of the tutorial is intended for use outside of the NetBeans Platform. Now that you have a Swing container with a JScrollPane, create a new Java class that extends GraphScene. Fill it out as follows: package demo; import java.awt.Image; import java.awt.Point; import java.util.Random; import javax.swing.ImageIcon; import org.netbeans.api.visual.graph.GraphScene; import org.netbeans.api.visual.widget.LayerWidget; import org.netbeans.api.visual.widget.Widget; import org.netbeans.api.visual.widget.general.IconNodeWidget; import org.openide.util.Utilities; public class DemoGraphScene extends GraphScene { private LayerWidget mainLayer; private Image image; private Random r = new Random(); public DemoGraphScene() { mainLayer = new LayerWidget(this); addChild(mainLayer); image = Utilities.icon2Image( new ImageIcon(getClass().getResource("/demo/chuk.png"))); addNode("Chuk"); } @Override protected Widget attachNodeWidget(Object arg0) { IconNodeWidget widget = new IconNodeWidget(this); widget.setImage(image); widget.setPreferredLocation(new Point(10, 20)); mainLayer.addChild(widget); return widget; } @Override protected Widget attachEdgeWidget(Object arg0) { return null; } @Override protected void attachEdgeSourceAnchor(Object arg0, Object arg1, Object arg2) { } @Override protected void attachEdgeTargetAnchor(Object arg0, Object arg1, Object arg2) { } } Most of the above code is self-explanatory, I believe. You have a LayerWidget which you add to the scene. Then you add an IconWidget, which you add to the layer. One interesting thing to note is how the icon is converted to an image, via a utility method from the NetBeans Utilities API, which you have already put on your classpath, together with the Visual Library API. In other words, there's a bunch of stuff that NetBeans Platform developers use that can also be used in your own smaller Java applications, as is the case here. To wrap up, we need to instantiate the GraphScene class from our JFrame and then set the JScrollPane so that its port view will contain the "scene". Here's how we do that, nice and easy via the JFrame constructor: private DemoGraphScene scene = new DemoGraphScene(); public DemoVisualFrame() { initComponents(); jScrollPane1.setViewportView(scene.createView()); } Next, I added a pic of Chuk to my app's source structure and then ran the application. And here's the result: Next, let's turn Chuk into a movable object. The user should be able to drag and drop him with their mouse. Hmmm. That will mean a lot of coding, right? Wrong. Here's all I needed to add, i.e., just line 6 below: protected Widget attachNodeWidget(Object arg0) { IconNodeWidget widget = new IconNodeWidget(this); widget.setImage(image); widget.setPreferredLocation(new Point(10, 20)); //I only needed to add this line: widget.getActions().addAction(ActionFactory.createMoveAction()); mainLayer.addChild(widget); return widget; } And now, when I run my app, I can use my mouse to drag Chuk to a different location: A MoveAction can only mean one thing, i.e., it can only mean that you want to move the widget. However, other actions could be implemented in a variety of ways, hence there is no default. You need to provide the content of the action yourself, as in the case of the LabelTextFieldEditor. Here, we begin by defining a class-level LabelTextFieldEditor: private WidgetAction editorAction = ActionFactory.createInplaceEditorAction(new LabelTextFieldEditor()); Next, we define out LabelTextFieldEditor, extending the TextFieldInplaceEditor class: private class LabelTextFieldEditor implements TextFieldInplaceEditor { public boolean isEnabled(Widget widget) { return true; } public String getText(Widget widget) { return ((LabelWidget) widget).getLabel(); } public void setText(Widget widget, String text) { ((LabelWidget) widget).setLabel(text); } } Finally, we add a label to our widget. We also assign the editor action defined above to our widget. Here we go, just line 7 and 8 below: @Override protected Widget attachNodeWidget(Object arg0) { IconNodeWidget widget = new IconNodeWidget(this); widget.setImage(image); widget.setPreferredLocation(new Point(10, 20)); //I added the following two lines: widget.setLabel("Chuk"); widget.getLabelWidget().getActions().addAction(editorAction); widget.getActions().addAction(ActionFactory.createMoveAction()); mainLayer.addChild(widget); return widget; } That's it. Let's run our app again. You now have a label which you can click and then it is editable: When you press Enter, the label is changed. But what's the point of having just Chuk in our application? Let's add another evangelist, Gregg Sporar: private Image CHUK = Utilities.icon2Image(new ImageIcon(getClass().getResource("/demo/chuk.png"))); private Image GREGG = Utilities.icon2Image(new ImageIcon(getClass().getResource("/demo/gregg.png"))); Next, we'll create a hash table, so that we can manipulate them more effectively: private final Hashtable mapping; { mapping = new Hashtable(); mapping.put("Chuk", CHUK); mapping.put("Gregg", GREGG); } Then, we'll add them both, rather than just one: public DemoGraphScene() { mainLayer = new LayerWidget(this); addChild(mainLayer); //Here we create our two evangelists: addNode("Chuk"); addNode("Gregg"); getActions().addAction(editorAction); } We'll need to rewrite our earlier method just a bit, so that it is more generic, because now it will have to handle both Chuk and Gregg: @Override protected Widget attachNodeWidget(Object node) { Image image = (Image) mapping.get(node); if (image != null) { return createNewWidget(node, image); } throw new IllegalArgumentException(node.toString()); } And we move all the code from the previous implementation of the above method to a new one: protected Widget createNewWidget(Object label, Image image) { IconNodeWidget widget = new IconNodeWidget(this); widget.setImage(image); widget.setPreferredLocation(new Point(10, 20)); widget.setLabel(label.toString()); widget.getLabelWidget().getActions().addAction(editorAction); widget.getActions().addAction(ActionFactory.createMoveAction()); mainLayer.addChild(widget); return widget; } Run the app again and now you'll have two evangelists in your "scene", instead of just one, with the same properties because they're both the same widget, as you can see from the code above: You might now think about connecting them together, which we can look at in a future article. In general, there's a lot more that can be done, of course, and the documentation on all of this goes into it all. Here's the homepage of the library. I also highly recommend Fabrizio Giudici's Creative use of the NetBeans Visual Library: the Light Table. In summary, you don't even need to like NetBeans IDE to benefit from its graph library. Just download the IDE, get the two JARs specified above, and then add them to your classpath. That's all. And then code in whatever IDE has your preference.
January 29, 2008
by Geertjan Wielenga
· 198,521 Views · 1 Like
article thumbnail
From Java to Groovy in a Few Easy Steps
Groovy and Java are really close cousins, and their syntaxes are very similar, hence why Groovy is so easy to learn for Java developers.
January 27, 2008
by Guillaume Laforge
· 121,895 Views · 3 Likes
article thumbnail
3D Model Interaction with Java 3D
This tutorial is based on a computer graphics assignment for which i was given the task of creating an application in which some articulated animal would walk using a hierarchical model. I had 4 days to complete this assignment, so i had to learn java 3d quickly, but i ended up having to read fragmented documentation, mostly focused on theory i already knew, with practical examples that were either too simple or too complex. The objective of this tutorial is to provide a guide for writing a basic java 3d application with a 3d model loaded from disk; it's less generic than the official java3d application tutorial and less focused on theory than other tutorials, but more straightforward for the experienced java developer who already knows basic cg theory and just wants to know what goes where very quickly - going deeper in the APIs is up to you. Requirements JDK version 1.5 or above (the examples use java 5 features) java 3d version 1.4 or above installed experience with jfc basic computer graphics knowledge (3d transforms, illumination types) a 3d model visualizer, like poseray a 3d model converter like 3dwin will be useful if you find some interesting 3d model in a format not supported by any java 3d loader Models You can download free 3d models on websites like turbosquid or the 3d archive . Free models may not have the quality you are looking for, so if you are on a serious/commercial project, you should probably consider purchasing a quality model. If you really want to model your objects you can try blender. Visualizing the model I will use a cockroach I downloaded from the 3d archive. You can choose another model if you will as long you know what you're doing. I will use poseray to visualize the model. Poseray cannot open every 3d format, so if the format of your model is not supported by poseray, you will have to use some other program like 3dwin to convert it to a format poseray accepts. poseray is actually intended to work with moray and povray, but it works very well for the purpose of viewing 3d models. 1. load the model 2. check the model (shot #1) 3. check the model (shot #2) 4. check how this model is branched These are the pieces that form the complete model. you will have to analyze how your model is branched to see if you can animate or interact with it as you plan. Every component of the model has a name - let it be the parts of your main subject or just other components from the scene. You can get these names on your program, but it's easier to check which part is which here. you can use the update function if the names aren't descriptive enough. You will need to know the name of every part if you plan to texturize or animate them independently. In the end, all that matters is that you save your file in a format that java loaders will recognize. preferably, save it in the wavefront .obj or lightwave . LWO format because java 3d comes with loaders for these file formats by default. Other loaders are available, but you will have to download them separately. Other java3d loaders Loading the model Wavefront .obj format import java.io.filereader; import java.io.ioexception; import com.sun.j3d.loaders.scene; // contains the object loaded from disk. import com.sun.j3d.loaders.objectfile.objectfile; // loader of .obj models public static scene loadscene(string location) throws ioexception { objectfile loader = new objectfile(objectfile.resize); return loader.load(new filereader(location)); } Lightwave .lwo format import com.sun.j3d.loaders.lw3d.lw3dloader; // loader of .lwo models public static scene loadscene(string location) throws ioexception { lw3dloader loader = new lw3dloader(); return loader.load(new filereader(location)); } Recommended reading: objectfile javadoc , lw3dloader javadoc . Basic setup Now that you know how to load the model let's see how it will look on your program before proceeding to further manipulation. the most important class of this example is the simple universe, which saves you from having to configure the view of your scene. a directional light is added to allow you to view your object (no light and you will see a plain black). You can view the source in . Roach as seen on the example program Recommended reading: simpleuniverse javadoc Getting the scene components We need to obtain a reference to every body part we need to manipulate (or just scene component, if you are not using a model of an animal). If you want to create a variable for every component and assign a meaningful name to each one, you will have to know what name maps to what component. the following piece of code demonstrates how to list the name of every named object from the scene: import javax.media.j3d.shape3d; void listscenenamedobjects(scene scene) { map namemap = scene.getnamedobjects(); for (string name : namemap.keyset()) { system.out.printf("name: %s\n", name); } } Have in mind that every shape3d is already part of the branchgroup of the scene, you have loaded. If you want to create another graph with your custom hierarchy, you will have to get a reference to one specific shape3d and then remove it from the branchgroup : import javax.media.j3d.branchgroup; /* obtains a reference to a specific component in the scene */ shape3d eyes = namemap.get("eyes"); /* the graph that still contains a reference to "eyes" */ branchgroup root = scene.getscenegroup(); /* removes "eyes" from this graph */ root.removechild(eyes); /* now you are free to use "eyes" in your custom graph */ Always remember you cannot add a component to more than one graph. If one component is already part of a graph and you try to add it to another, you will get a multipleparentexception. If you need the same component in more than one graph, you can clone them. Transformations Basic transformation steps: Add the parts you want to transform to a transformgroup ; Apply the transformgroup.allow_transform_write capability to the group if it wasn't set; Create or use some previously created instance of transform3d ; Configure this instance of transform3d as / if necessary; Apply this transform3d instance on the transformgroup instance. That implies you will have to keep references to instances of these classes in order to transform specific nodes of your graph. The following piece of code demonstrates translation, rotation on multiple axis and non-uniform scaling. It uses code created on previous sections. import javax.vecmath.vector3f; import javax.vecmath.vector3d; import javax.media.j3d.transformgroup; import javax.media.j3d.transform3d; map namemap = scene.getnamedobjects(); /* get the node you want to transform */ shape3d wing = namemap.get("wing"); /* add it to a transformgroup */ transformgroup transformgroup = new transformgroup(); transformgroup.addchild(wing); /* necessary to allow this group to be transformed */ transformgroup.setcapability(transformgroup.allow_transform_write); /* accumulates all transforms */ transform3d transforms = new transform3d(); /* creates rotation transforms for x, y and z axis */ transform3d rotx = new transform3d(); transform3d roty = new transform3d(); transform3d rotz = new transform3d(); rotx.rotx(15d); // +15 degrees on the x axis roty.roty(30d); // +30 degrees on the y axis rotz.rotz(-20d); // -20 degrees on the z axis /* combines all rotation transforms */ transforms.mul(rotx, roty); transforms.mul(transforms, rotz); /* translation: translates 2 on x, 3 on y and -10 on z */ vector3f translationvector = new vector3f(2f, 3f, -10f); transforms.settranslation(translationvector); /* non uniform scaling: scales 3x on x, 1x on y and 2x on z */ vector3d scale = new vector3d(3d, 1d, 2d); transforms.setscale(scale); /* apply all transformations */ transformgroup.settransform(transforms); Recommended reading: transform3d javadoc , transformgroup javadoc Hierarchical model Now that you have access to all components separately, you can build your custom hierarchical graph. If you have been using swing or awt, you are already familiar with the hierarchical model. for instance, you can have a jframe , which then adds a jpanel , which then adds a jlabel and so forth. Many properties applied on the root are propagated to children, like the isvisible() property. With a 3d model, all transforms and texturizations will be applied to all children (subgraphs). imagine if you had to apply the same transform over and over to many model parts just to make one movement? Java 3d has a class called group , which is basically an n-tree: every children has only one parent and an arbitrary number of children. you will use subclasses of group to create your scenes. java 3d has also the leaf class, which is used to construct objects on the tree which wouldn't make sense with children, like background, camera, behaviour, etc. hierarchical model of the scene I will use the transformgroup class as the default node for building the graph. you may use other subclasses of group if you have other needs. You may want to keep a reference of every transformgroup you create if you are going to do some interaction (like making a cockroach walk). Note that the code above suffers from the same flaws of programatic gui construction. you can define the graph in xml and create a custom parser if you need reusability. if possible, you can also edit the model graph in a model editor to avoid having to perform these steps on your program. Hierarchical construction of the graph transformgroup getcockroach(scene scene) { /* obtain the scene's branchgroup, from which components are removed */ branchgroup root = scene.getscenegroup(); map namemap = scene.getnamedobjects(); /* remove all children (you don't want a multiparentexception) */ root.removeallchildren(); /* construct the groups */ transformgroup leftlegs = new transformgroup(); transformgroup rightlegs = new transformgroup(); transformgroup body = new transformgroup(); transformgroup roach = new transformgroup(); /* build the graph --> left legs */ leftlegs.addchild(namemap.get("luplegf")); leftlegs.addchild(namemap.get("luplegm")); leftlegs.addchild(namemap.get("luplegr")); leftlegs.addchild(namemap.get("lmidlegf")); leftlegs.addchild(namemap.get("lmidlegm")); leftlegs.addchild(namemap.get("lmidlegr")); leftlegs.addchild(namemap.get("llowlegf")); leftlegs.addchild(namemap.get("llowlegm")); leftlegs.addchild(namemap.get("llowlegr")); leftlegs.addchild(namemap.get("lfootf")); leftlegs.addchild(namemap.get("lfootm")); leftlegs.addchild(namemap.get("lfootr")); /* build the graph --> right legs */ rightlegs.addchild(namemap.get("ruplegf")); rightlegs.addchild(namemap.get("ruplegm")); rightlegs.addchild(namemap.get("ruplegr")); rightlegs.addchild(namemap.get("rmidlegf")); rightlegs.addchild(namemap.get("rmidlegm")); rightlegs.addchild(namemap.get("rmidlegr")); rightlegs.addchild(namemap.get("rlowlegf")); rightlegs.addchild(namemap.get("rlowlegm")); rightlegs.addchild(namemap.get("rlowlegr")); rightlegs.addchild(namemap.get("rfootf")); rightlegs.addchild(namemap.get("rfootm")); rightlegs.addchild(namemap.get("rfootr")); /* build the graph --> remaining body */ body.addchild(namemap.get("antena")); body.addchild(namemap.get("antenar")); body.addchild(namemap.get("wing")); body.addchild(namemap.get("abdomen")); body.addchild(namemap.get("head")); body.addchild(namemap.get("prothorx")); body.addchild(namemap.get("eyes")); body.addchild(namemap.get("lpalp")); body.addchild(namemap.get("rpalp")); /* build the graph --> roach */ roach.addchild(leftlegs); roach.addchild(rightlegs); roach.addchild(body); /* enable transform capability (it is not enabled by default) */ enabletransformcapability(leftlegs, rightlegs, body, roach); return roach; } void enabletransformcapability(transformgroup... parts) { for (transformgroup part : parts) { part.setcapability(transformgroup.allow_transform_write); } } Note that i have declared the transform groups locally, but on your program you will have to declare them globally or keep a reference to them somewhere if you plan to add interaction to your model. we will configure the camera (actually a view) and add lights . I did a fairly simple hierarchy because the movement this cockroach will do is just as simple. in my assignment i had to do an interaction in which the legs would articulate, which implied in a different (i.e. more complex) setup for the hierarchy of the legs. Appearance The loaded cockroach is quite pale since no material descriptors were associated with it, but this is not a problem, as you can define your textures for each component of your graph. you must read the material javadoc to understand what is being done here. To save some effort, I will declare some constants for ambient, emissive and specular light colors. the user may choose the diffuse color - the light which is emitted when the object is under the influence of some light. import javax.vecmath.color3f; private static final color3f specular_light_color = new color3f(color.white); private static final color3f ambient_light_color = new color3f(color.light_gray); private static final color3f emissive_light_color = new color3f(color.black); Now you can create a method that returns an apperance based on a given color : import javax.media.j3d.material; import javax.media.j3d.appearance; appearance getappearance(color color) { appearance app = new appearance(); app.setmaterial(getmaterial(color)); return app; } material getmaterial(color color) { return new material(ambient_light_color, emissive_light_color, new color3f(color), specular_light_color, 100f); } It's possible to use an image as a texture, but there are some constraints: the image must be equal in width and height and must be a power of 2. If you have ever used swing, you know you have to pass an instance of component to mediatracker if you want to track the loading of an image. loading a texture uses a similar process: import javax.media.j3d.texture2d; import com.sun.j3d.utils.image.textureloader; appearance getappearance(string path, component canvas, int dimension) { appearance appearance = new appearance(); appearance.settexture(gettexture(path, canvas, dimension)); return appearance; } texture gettexture(string path, component canvas, int dimension) { textureloader textureloader = new textureloader(path, canvas); texture2d texture = new texture2d(texture2d.base_level, texture2d.rgb, dimension, dimension); texture.setimage(0, textureloader.getimage()); return texture; } Applying the material: scene cockroach = getscenefromfile("roach_mod.obj"); map namemap = cockroach.getnamedobjects(); color brown = new color(165, 42, 42); appearance brownappearance = getappearance(brown); namemap.get("wing").setappearance(brownappearance); a material responds to different light positions As far as I've tested, if you assign a texture instead of a material, the object will not respond to different light configurations, instead, it will look like being constantly illuminated. roach with a texture Lights As you have seen, we still need to add two lights and one camera (a view). if you have read the , you have seen a directional light being added to the root of the scene. it's interesting to make the light go with the roach wherever it goes if you don't want it to get completely black after walking out of the reach of the light - in this case you will need to add your lights as leafs on the same node which contains the object you want to illuminate. On the other hand, if you want your object to become shadowed as it moves, you should add the lights to a node other than the one you used to add the model. Except from finding the right vector to point the light to your object, creating and configuring lights is mostly simple. the following figure demonstrates how to construct an ambient light and a directional light: import javax.media.j3d.directionallight; import javax.media.j3d.ambientlight; color3f directionallightcolor = new color3f(color.blue); color3f ambientlightcolor = new color3f(color.white); vector3f lightdirection = new vector3f(-1f, -1f, -1f); ambientlight ambientlight = new ambientlight(ambientlightcolor); directionallight directionallight = new directionallight(directionallightcolor, lightdirection); bounds influenceregion = new boundingsphere(); ambientlight.setinfluencingbounds(influenceregion); directionallight.setinfluencingbounds(influenceregion); Why do you need an influence region? for the same reason you need clipping: to avoid doing useless calculations. see the light javadoc for more information. camera If you want to view your scene on different angles, you will need a camera. java 3d uses a view based model - there are no camera objects, but a viewplatform object. Whenever you want to change the view of your scene, all you have to do is to change parameters on the viewplatform object. If you are using simpleuniverse to facilitate the view configuration of your program, you don't need to add any viewplatform instance to the root node because simpleuniverse has already added that for you. the viewplatform created by simpleuniverse is inside a multitransformgroup , which you can obtain via view ing platform . The following code demonstrates how to obtain this multitransformgroup and use it to change the view of the scene: import com.sun.j3d.utils.universe.viewingplatform; /* you don't have to create a viewingplatform if you are using simpleuniverse */ viewingplatform vp = universe.getviewingplatform(); /* you don't need to add the vp to a transformgroup because the vp is already added in a multitransformgroup; 0 is the topmost transformgroup */ transformgroup vpgroup = vp.getmultitransformgroup().gettransformgroup(0); /* you can transform the view platform as you do with other objects */ transform3d vptranslation = new transform3d(); vector3f translationvector = new vector3f(1.9f, 1.2f, 6f); vptranslation.settranslation(translationvector); vpgroup.settransform(vptranslation); example: translation vectors used on the viewplatorm 0.0, -1.2, 6.0 1.9, 1.2, 6.0 0.0, 1.2, 6.0 -1.9, 1.2, 6.0 Do not confuse viewplatform with view ing platform - the latter is a convenience class used to "set up the view side of the graph" - it contains a viewplatform . Recommended reading: viewingplatform javadoc , viewplatform javadoc Background Unless you want your background to be plain black, you should specify one. just remember to always add the background to the root node of your scene; add it anywhere else and you will get an undesirable illegalsharingexception . color background import javax.media.j3d.background; /* a dull gray background */ background background = new background(new color3f(color.light_gray)); /* incluencregion is a boundingsphere. see the "lights" section for details */ background.setapplicationbounds(influenceregion); /* root is a branchgroup, root node of your scene object */ root.addchild(background); Image background textureloader t = new textureloader("leaves.jpg", canvas); background background = new background(t.getimage()); background.setimagescalemode(background.scale_repeat); // tiles the image background.setapplicationbounds(influenceregion); root.addchild(background); This static background is quite boring. If you are looking for something more interesting, such as a celestial sphere, you should use apply a geometry to a background. you can find examples on java2s website. Recommended reading: background javadoc Interacting with the model Now it's time to use the transformgroup references you've kept a while ago. You will use them to control the movement of the model. The cockroach will do a very silly movement: the left legs will move forward while the right legs stand still, then the right legs move forward while left legs stand still; the body will always move a little bit forward on every movement. it's far from realistic, but you can derive more complex movements if you learn this one. (if you're concerned, as far as my assignment, the movement was more complex than that...) the class behavior will be used to interact with the model. The behavior class is like a listener - you have to implement it to achieve the desired reaction. It has to be activated every time it's used, or it won't react to the next stimulus . The stimulus used on this section will be a key press, but you can use many others - check wakeupcriterion 's direct known subclasses to check for other options. After implementing your behavior subclass, all you have to do is to add it on the node you want to animate. Instance variables /** groups that will be animated. */ transformgroup[] groups; /** used to transform the groups you will animate. */ transform3d[] transforms; /** used to translate the groups you will animate. */ vector3f[] translations; /** type of event for which groups will react. */ wakeuponawtevent wake; /** increments 1 every time the user hits a key. */ int hitcount; /** decides which group will be animated based on the hitcount. */ int bodypartindex; Constructor simpletripodmovement(transformgroup... groups) { this.groups = groups; // you can add a groups count security check if you will wake = new wakeuponawtevent(keyevent.key_pressed); // you decide which key later translations = new vector3f[groups.length]; transforms = new transform3d[groups.length]; for (int i = 0; i < groups.length; i++) { translations[i] = new vector3f(0f, 0f, 0f); transforms[i] = new transform3d(); } } Implementation of initialize public void initialize() { // overriden method wakeupon(wake); // inherited method } Implementation of processstimulus public void processstimulus(enumeration enumeration) { keyevent k = (keyevent) wake.getawtevent()[0]; /* moves only if the key pressed is the right directional key and if the hit count is a multiple of 4 */ if ((k.getkeycode() == keyevent.vk_right) && (hitcount++ % 4 == 0)) { /* selects the body part to be moved */ bodypartindex = (bodypartindex + 1) % 3; /* moves 0.1 on z axis */ translations[bodypartindex].set(translations[bodypartindex].x, translations[bodypartindex].y, translations[bodypartindex].z + 0.1f); transforms[bodypartindex].settranslation(translations[bodypartindex]); groups[bodypartindex].settransform(transforms[bodypartindex]); } /* if you don't put it here, it won't respond the next time you press a key */ wakeupon(wake); } Applying the behavior /** * adds a simple tripod movement to the given roach. * * @param parts parts that will be animated * @param roach supernode of parts * @param bounds world bounds, the smae used for lighting */ void addbehavior(transformgroup[] parts, transformgroup roach, bounds bounds) { behavior behavior = new cockroachbehavior(parts); /* behavior will not work if you don't set the scheduling bounds! */ behavior.setschedulingbounds(bounds); roach.addchild(behavior); } As you have probably noticed, this class is tightly coupled with the objects it animates, but that is predictable; from behavior 's javadoc: the application must provide the behavior object with references to those scene graph elements that the behavior object will manipulate. The application provides those references as arguments to the behavior's constructor when it creates the behavior object. alternatively, the behavior object itself can obtain access to the relevant scene graph elements either when java 3d invokes its initialize method or each time java 3d invokes its processstimulus method. Recommended reading: behavior javadoc Resources cockroach object [you may have to convert it] cockroach wings texture cockroach head texture ground texture leaves background source code [you will need to download the model separately] executable jar [you will need to download the model separately] executable jar + model complete project [src + resources] References java3d javadoc com.sun.j3d.* packages javadoc java3d application tutorial from sun a basic hierarchical model of the top part of a human torso
January 26, 2008
by Dalton Filho
· 65,095 Views
article thumbnail
Class Loading Fun with Groovy
Sometimes you need special measures. Not to make Groovy work, but to make your applications or frameworks a little bit more powerful or versatile.
January 17, 2008
by Steven Devijver
· 42,981 Views · 1 Like
article thumbnail
Get All Classes Within A Package
The code below gets all classes within a given package. Notice that it should only work for classes found locally, getting really ALL classes is impossible. /** * Scans all classes accessible from the context class loader which belong to the given package and subpackages. * * @param packageName The base package * @return The classes * @throws ClassNotFoundException * @throws IOException */ private static Class[] getClasses(String packageName) throws ClassNotFoundException, IOException { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); assert classLoader != null; String path = packageName.replace('.', '/'); Enumeration resources = classLoader.getResources(path); List dirs = new ArrayList(); while (resources.hasMoreElements()) { URL resource = resources.nextElement(); dirs.add(new File(resource.getFile())); } ArrayList classes = new ArrayList(); for (File directory : dirs) { classes.addAll(findClasses(directory, packageName)); } return classes.toArray(new Class[classes.size()]); } /** * Recursive method used to find all classes in a given directory and subdirs. * * @param directory The base directory * @param packageName The package name for classes found inside the base directory * @return The classes * @throws ClassNotFoundException */ private static List findClasses(File directory, String packageName) throws ClassNotFoundException { List classes = new ArrayList(); if (!directory.exists()) { return classes; } File[] files = directory.listFiles(); for (File file : files) { if (file.isDirectory()) { assert !file.getName().contains("."); classes.addAll(findClasses(file, packageName + "." + file.getName())); } else if (file.getName().endsWith(".class")) { classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6))); } } return classes; }
November 30, 2007
by Victor Tatai
· 124,702 Views · 7 Likes
article thumbnail
Java: RegEx: Splitting A Space-, Comma-, And Semi-colon Separated List
// Greedy RegEx quantifier used // X+ = X, one or more times // [\\s,;]+ = one or more times of either \s , or ; String test_data = "hello world, this is a test, ;again"; _logger.debug("Source: " + test_data); for (String tag : test_data.split("[\\s,;]+")) { _logger.debug("Received tag: [" + tag + "]"); }
August 5, 2007
by Snippets Manager
· 38,172 Views · 1 Like
article thumbnail
Java: Lucene: Simple In-Memory Search Example
// Adapted from http://javatechniques.com/blog/lucene-in-memory-text-search-example // Works with present APIs in Lucene 2.1.0 /** * A simple example of an in-memory search using Lucene. */ import java.io.IOException; import java.io.StringReader; import org.apache.lucene.search.Hits; import org.apache.lucene.search.Query; import org.apache.lucene.document.Field; import org.apache.lucene.search.Searcher; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.document.Document; import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.queryParser.ParseException; import org.apache.lucene.analysis.standard.StandardAnalyzer; public class InMemoryExample { public static void main(String[] args) { // Construct a RAMDirectory to hold the in-memory representation // of the index. RAMDirectory idx = new RAMDirectory(); try { // Make an writer to create the index IndexWriter writer = new IndexWriter(idx, new StandardAnalyzer(), true); // Add some Document objects containing quotes writer.addDocument(createDocument("Theodore Roosevelt", "It behooves every man to remember that the work of the " + "critic, is of altogether secondary importance, and that, " + "in the end, progress is accomplished by the man who does " + "things.")); writer.addDocument(createDocument("Friedrich Hayek", "The case for individual freedom rests largely on the " + "recognition of the inevitable and universal ignorance " + "of all of us concerning a great many of the factors on " + "which the achievements of our ends and welfare depend.")); writer.addDocument(createDocument("Ayn Rand", "There is nothing to take a man’s freedom away from " + "him, save other men. To be free, a man must be free " + "of his brothers.")); writer.addDocument(createDocument("Mohandas Gandhi", "Freedom is not worth having if it does not connote " + "freedom to err.")); // Optimize and close the writer to finish building the index writer.optimize(); writer.close(); // Build an IndexSearcher using the in-memory index Searcher searcher = new IndexSearcher(idx); // Run some queries search(searcher, "freedom"); search(searcher, "free"); search(searcher, "progress or achievements"); searcher.close(); } catch (IOException ioe) { // In this example we aren’t really doing an I/O, so this // exception should never actually be thrown. ioe.printStackTrace(); } catch (ParseException pe) { pe.printStackTrace(); } } /** * Make a Document object with an un-indexed title field and an indexed * content field. */ private static Document createDocument(String title, String content) { Document doc = new Document(); // Add the title as an unindexed field… doc.add(new Field("title", title, Field.Store.YES, Field.Index.NO)); // …and the content as an indexed field. Note that indexed // Text fields are constructed using a Reader. Lucene can read // and index very large chunks of text, without storing the // entire content verbatim in the index. In this example we // can just wrap the content string in a StringReader. doc.add(new Field("content", new StringReader(content))); return doc; } /** * Searches for the given string in the "content" field */ private static void search(Searcher searcher, String queryString) throws ParseException, IOException { // Build a Query object QueryParser parser = new QueryParser("content", new StandardAnalyzer()); Query query = parser.parse(queryString); // Search for the query Hits hits = searcher.search(query); // Examine the Hits object to see if there were any matches int hitCount = hits.length(); if (hitCount == 0) { System.out.println("No matches were found for \"" + queryString + "\""); } else { System.out.println("Hits for \"" + queryString + "\" were found in quotes by:"); // Iterate over the Documents in the Hits object for (int i = 0; i < hitCount; i++) { Document doc = hits.doc(i); // Print the value that we stored in the "title" field. Note // that this Field was not indexed, but (unlike the // "contents" field) was stored verbatim and can be // retrieved. System.out.println(" " + (i + 1) + ". " + doc.get("title")); } } System.out.println(); } }
May 15, 2007
by Snippets Manager
· 6,186 Views
article thumbnail
Java DOM : Creating An XML Document From XML File
// description of your code here try { // // Create the XML Document // DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); Document doc = docBuilder.parse(filePath); // ... } catch (Exception e) { // ... }
May 14, 2007
by Snippets Manager
· 19,220 Views
article thumbnail
Range() In Java
A range is a very handy feature of programing languages like Python. * range( 10 ) -> 0 1 2 3 4 5 6 7 8 9 * range( 5, 10 ) -> 5 6 7 8 9 * range( 0, 10, 3 ) -> 0 3 6 9 * range( '0', '9' ) -> 012345678 With an extended for loop it is possible to use such a feature too: /* * This project is made available under the terms of the BSD license, more information can be found at * http://www.opensource.org/licenses/bsd-license.html * * Copyright (c) 2007. Christian Ullenboom (http://www.tutego.com/) and contributors. All rights reserved. */ package com.tutego; import java.util.Iterator; /** * Class that generates immutable sequences (ranges) as Iterable * objects. A range represents a start (0 if not given), an stop (mandatory) and * an optional step (1 by default). The start value is included in the range, * the stop value is exclusive. Every range is handled by an Iterable * which can by used in an extended for loop. * * * for ( int i : range( 0, 10, 3 ) ) * System.out.print( i + " " ); // 0 3 6 9 * * * @author Christian Ullenboom (tutego) * @version 1.0 */ public class Range { public static Iterable range( final int start, final int stop, final int step ) { if ( step <= 0 ) throw new IllegalArgumentException( "step > 0 isrequired!" ); return new Iterable() { public Iterator iterator() { return new Iterator() { private int counter = start; public boolean hasNext() { return counter < stop; } public Integer next() { try { return counter; } finally { counter += step; } } public void remove() { } }; } }; } public static Iterable range( final int start, final int stop ) { return range( start, stop, 1 ); } public static Iterable range( final int stop ) { return range( 0, stop, 1 ); } } This is an example: package com.tutego; import static com.tutego.Range.range; public class RangeDemo { public static void main( String[] args ) { for ( int i : range( 10 ) ) System.out.print( i + " " ); System.out.println(); for ( int i : range( 5, 10 ) ) System.out.print( i + " " ); System.out.println(); for ( int i : range( 0, 10, 3 ) ) System.out.print( i + " " ); System.out.println(); for ( int i : range( '0', '9' ) ) System.out.print( (char) i ); System.out.println(); String[] a = { "Mary", "had", "a", "little", "lamb" }; for ( int i : range(a.length ) ) System.out.printf( "%d %s%n", i, a[i] ); } }
April 24, 2007
by Snippets Manager
· 32,575 Views · 1 Like
article thumbnail
Get MD5 Hash In A Few Lines Of Java
1 import java.security.*; 2 import java.math.*; 3 4 public class MD5 { 5 public static void main(String args[]) throws Exception{ 6 String s="This is a test"; 7 MessageDigest m=MessageDigest.getInstance("MD5"); 8 m.update(s.getBytes(),0,s.length()); 9 System.out.println("MD5: "+new BigInteger(1,m.digest()).toString(16)); 10 } 11 }
March 18, 2007
by Greg Miller
· 46,089 Views · 2 Likes
article thumbnail
Add A Jar File To Java Load Path At Run Time
import java.net.URL; import java.io.IOException; import java.net.URLClassLoader; import java.net.MalformedURLException; public class JarFileLoader extends URLClassLoader { public JarFileLoader (URL[] urls) { super (urls); } public void addFile (String path) throws MalformedURLException { String urlPath = "jar:file://" + path + "!/"; addURL (new URL (urlPath)); } public static void main (String args []) { try { System.out.println ("First attempt..."); Class.forName ("org.gjt.mm.mysql.Driver"); } catch (Exception ex) { System.out.println ("Failed."); } try { URL urls [] = {}; JarFileLoader cl = new JarFileLoader (urls); cl.addFile ("/opt/mysql-connector-java-5.0.4/mysql-connector-java-5.0.4-bin.jar"); System.out.println ("Second attempt..."); cl.loadClass ("org.gjt.mm.mysql.Driver"); System.out.println ("Success!"); } catch (Exception ex) { System.out.println ("Failed."); ex.printStackTrace (); } } }
February 23, 2007
by Snippets Manager
· 31,578 Views
article thumbnail
Retrieving All Parameters to a Java Servlet
Here's a really simple code snippet for retrieving parameters to a Java servlet.
February 10, 2007
by Snippets Manager
· 27,192 Views · 2 Likes
  • Previous
  • ...
  • 246
  • 247
  • 248
  • 249
  • 250
  • 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
×