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
Effective Eclipse: Don't write the code, generate it
I hope that we will never be able to generate applications. I would be without a job then and you probably too. But what we can generate are various repetitive and boring pieces of code. The first thing that can be generated is class file. You are using it, but you have probably never realized how much time does it save you. If there was no class skeleton generation, you would have to: create new file in the proper directory (with respect to package (and create the folders too)) and place the package statement at the beginning of a class. I will make a short stop here. I noticed that all people generate their classes, but not all of them specify implemented interfaces and extended class. Surely, you can generate the class and write the extends and implements part afterwards, but it involves moving the cursor, writing and eventually generating abstract or implemented methods. I found it much easier to press ALT + E (extend) to add extended class and ALT + A (add interface) to add interfaces in the new class wizard. My class will then come out with empty overridden methods and correct imports. If you look at the Source menu you can find more "Generate" commands. But none of them is so valuable and useful as Eclipse templates. They are the true gem in my daily work and it is pity they are hidden out of sight. And they are hidden well. What are they and how to get them? Templates serve as a shorthand for a snippet of code. You type in the magical word and it will be transformed into the snippet. Some examples: Type sysout and press CTRL + SPACE (the autocompletion) and it will be automagically changed to System.out.println(); with the caret waiting right in the middle between the parenthesizes. While we are here, let's explore the next interesting feature. Type "for" and press CTRL + SPACE to change it to a skeleton of a for loop. The for template is a showcase of templates' power. Notice the blue boxes around some of the commands. They represent the caret stop and you can move between them using the TAB key. Now, with the caret on "iterator", type the name of the variable representing the iterator. Its name will be changed in the whole loop as you type (the occurrences are marked with a light blue background). Now just two more TABs to change the collection variable and the type. Noticed the green line waiting in the empty line? It marks the position where the caret will jump when Enter key is pressed. So after changing the variable type you can just press Enter and the caret will jump to the empty line. When you use autocompletion the green marker is always somewhere around, waiting for you to press Enter. Every particular template is closely bound to editor. Each editor has its own defined set of templates, which are applicable only in that editor type. It is quite logical that the sysout template will not work in JSP editor. Furthermore, each template is applicable only within the specified context of the particular editor. There are two contexts in the Java editor for example, Java and Javadoc. To see list of all templates open Window -> Preferences and type templates into the search box. You will get a list of all editors and their respective template settings. Your list may vary from my list, because it depends on installed plugins. I encourage you to walk through the list to see what predefined templates are available. Not all of them are useful, but you need to see it, because what does not work for me might work for you. The true and real power of templates lies in custom templates, but I will leave this topic for the next week article. Apart from the fact, that it can expand templates, CTR + SPACE has few more interesting uses. It is an autocompletion shortcut and it can complete the names of variables or methods and in fact, it is its most obligate and the most famous usage. But it has some more surprises to offer. If you get used to it, you will be hitting it often, even in situations where there is obviously nothing to autocomplete. Or is it? Guess what is on the picture above? It is eclipse trying to autocomplete the name of a variable. It is pity it cannot read my mind. I often find myself hitting the shortcut in the middle of the string ever wondering why it doesn't complete the word. Never can remember the signature of a method you want to override? Never mind, hit CTRL + SPACE and you will get a list. It can assist you in private method creation, and it can guess what to complete even from the upper case letters. Warning: Using autocompletion and templates can lead to uncontrolled ctrl + space hitting, surprises and productivity boost.
February 22, 2008
by Tomas Kramar
· 102,870 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
Patching from Local History
Using patches is a popular way to share changes between the teammates or supply updates to software products to the customers. With IntelliJ IDEA, creating and applying versioned patches is quite simple and intuitive: you can do it from the main Version Control menu, or from the Changes tool window. However, IntelliJ IDEA suggests an additional way to create and apply your “personal” patches. As we have discussed earlier, numerous changes pass unnoticed by the version control systems, because you just do not check in every change you make to your files while working. You know that IntelliJ IDEA keeps your own “personal version control” – the local history. Besides the possibility to roll back to a certain revision, you can also create a patch on the base of a revision or action, share it with your colleagues, and apply it when necessary. Local history applies to the folders, files, members and fragments of text, but the technique of creating a patch is common in all cases. Let’s see how it’s done. Select a folder in the Project tool window, and choose Local History on its context menu. In the Local History view, right-click the desired revision, and choose Create Patch: [img_assist|nid=1204|title=|desc=|link=none|align=left|width=505|height=357] In the dialog box that opens, specify the name and location of the patch file: [img_assist|nid=1205|title=|desc=|link=none|align=left|width=415|height=136] An interesting possibility is suggested by the Reverse patch checkbox. If you check this option, IntelliJ IDEA will create a patch that rolls back the selected action. For example, it you have created a file, the patch will delete it. Applying your “personal” patch is done as usual, using the Apply Patch command on the main Version Control menu. If a patch file is stored in project, you can invoke this command on the context menu of the patch file in the Project tool window: [img_assist|nid=1206|title=|desc=|link=none|align=left|width=249|height=195]
February 21, 2008
by Irina Megorskaya
· 9,835 Views
article thumbnail
Binding a JTable to Swing Controls in NetBeans IDE
Here is an outline of a scenario that binds Swing controls to columns in a JTable, via the tools that NetBeans IDE provides.
February 20, 2008
by Geertjan Wielenga
· 183,935 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
Effective Eclipse: Shortcut Keys
The less you touch the mouse, the more code you can write. Below you will find a set of essential keyboard shortcuts that I love for Eclipse.
February 15, 2008
by Tomas Kramar
· 1,510,209 Views · 29 Likes
article thumbnail
Effective Eclipse: Setup Your Environment
Today, I was taught an important lesson. The lesson of effectiveness. I was attending a presentation, called "Python Django: Advanced web application in 40 minutes". The guy was a geek, he was writing the code in a very basic vim installation. I bet, that if he used something better (no offense, it was really basic installation and he was apparently no vim master) he could crack it in half the time. It was an "oh, I made a typo here" presentation. It was then, when I realized that you really need a good editor if you want to be productive. Choose your tool Just do it. Find what suits you best and use it. I found Eclipse. Basic setup The first thing you should do, is to set up your font. If you are using Windows, you are lucky, as the font looks probably good and is well readable. If you are using Ubuntu like me, you might have less luck. When I first started eclipse, I was stunned. The font was big and crappy. But not for too long. Open: Window->Preferences->General->Appearance->Color and Fonts->Basic->Text Font and change the font size to 8. Much better now. The font used is called Monospace, some people recommend Bitstream Vera Sans Mono. This is how it looked before and how it looks now. Before: After: I recommend lowering the font size for your whole desktop. You will be surprised how much more can you see now. You can improve the font rendering too. Don't be greedy Eclipse is running with very small memory by default, but there is really no reason to be greedy. Just give your toy what it needs. Fire up the text editor, open eclipse.ini and enter: -vmargs -Xms512M -Xmx1024M -XX:PermSize=128M -XX:MaxPermSize=256M The -Xms option specifies the minimum and -Xmx the maximum heap size. The same holds for PermSize and MaxPermSize. Heap is that part of memory, where all your objects live. PermGen means "Permanent Generation" and it is a part of memory where all permanent objects are stored. By permanent, I mean those, which are not going to be garbage collected (for example Strings, classes etc.). Here you can find a better explanation of what PermGen is. If you are running a linux box, you might experience OutOfMemoryError-s if you do not adjust memory size. The values provided above are only for example, you should enter the values appropriate to your RAM size. You can further tune the performance by providing additional arguments. In his article, Jim Bethancourt recommends using Throughput garbage collector (-XX:+UseParallelGC), Robi Sen recommends using CMS Collector (-XX:+UseConcMarkSweepGC) as more effective. Help, I am giving the crap all my memory and it still keeps OutOfMemoryErroring! The reason is that you are simply not giving it enough memory. But don't worry, you don't have to buy another memory module (well, unless you have 128MB RAM). It is possible that you have made a typo in eclipse.ini, or maybe you used wrong eclipse.ini or maybe it simply doesn't work. I cannot tell you how to fix it, but I can tell how much memory are you giving it. Open Window->Preferences->General and check the "Show heap status" checkbox. You should now see the memory status in the bottom right corner. If you see values which correspond to the values you entered, everything should be fine. Set it up You should really take a time to walk through all the options under Window -> Preferences and customize your eclipse installation. I am going to list few ba General Always run in background: when eclipse is doing something time consuming, it will bother you with a modal popup window showing the progress of a task. I used to dismiss the popup with "Run in background" button. I am usually not interested in watching the lazy progressbar. If you enable this option eclipse will no longer bother you, and all tasks will run in background by default. There is nothing worse than breaking your workflow with messages: Hey I am building, can you see? Appearance: You can set various font related options here. If you are interested, you can change the position of tabs from top to bottom. Editors->File associations: if you have some exotic extension you can map it to the appropriate editor here. If you have xml file called myfile.exotic you can map .exotic extension to the xml editor. Editors->Text Editors -> Show line numbers: If you like, you can see line numbers. Very useful. Editors->Text Editors -> Spelling: Eclipse comes bundled with a spell checking turned on by default. This is a good idea and I really liked it, until I opened localized messages for my web application. Every word in my file was marked as misspelled, I was looking at an yellow sea of warnings, editor became quickly unresponsive as it wasn't able to handle hundreds of spelling errors. I had to turn this feature off, at least until some kind of ignore list is implemented or some good folk creates dictionary for my language. Java Java->Code style: Under Cleanup and Formatter are code formatting settings which are applied everytime the file is saved. If you tune it, it can save you much time. Java->Code style->Code templates: Here you can find and edit various templates. The only thing I do here is changing the "new Type" template to show my real name as author instead of my operating system username. Run/Debug Run/Debug->Launching: In previous Eclipse releases if you hit the run button, the last launched application was started. In Eclipse 3.3 this behavior changed a bit, and the selected resource gets launched. I found it annoying as I usually have only one runnable class. You can switch to the old style by choosing the right option under Launch Operation fieldset. I know I am repeating myself, but it is essential that you walk through the options and set it, such that it works with you, not against you.
February 8, 2008
by Tomas Kramar
· 49,715 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,303 Views
article thumbnail
Optimizing Your Website Structure For Print Using CSS
As much as I read articles online, I still print a fair amount of them out. Sometimes I print them to pass on to others, other times to read again when I have more time. Unfortunately a great deal of websites put no effort into providing their content in a printer-friendly fashion. The result of them overlooking the print audience is a great article not being read. If only these writers knew how easy it can be to optimize their site for print and how it can greatly enhance the value of their website. The secret to creating printable pages is being able to identify and control the "content area(s)" of your website. Most websites are composed of a header, footer, sidebars/subnavigation, and one main content area. Control the content area and most of your work is done. The following are my tips to conquering the print media without changing the integrity of your website. Create A Stylesheet For Print Of course you have at least one stylesheet to control the layout of the page and formatting of the content, but do you have a stylesheet to control how your page will look like in print? Add the print style sheet, with the media attribute set to "print", at the end of the list of stylesheets in the header. This will allow you to create custom CSS classes applied only at the time of print. Make sure your structure CSS file is given a media attribute of "all." Avoid Unnecessary HTML Tables As much as I try to steer clear of using tables, there's no way to avoid the occasional experience. Forms are much easier to code when using tables. Tables are also great for...get this...data tables. Other than these two situations, a programmer should try to avoid using table, especially when considering print. Controlling the content area of your website can be extremely challenging when the page structure is trapped in a table. Know Which Portions Of The Page Don't Have Any Print Value You know that awesome banner you have at the top of your site? Ditch it. And those ads on the right and left sides of the page? Goodbye. Web visitors print your page because of the content on it, not to see the supporting images on your website. Create a class called "no-print" and add that class declaration to DIVS, images, and other elements that have no print value: .no-print { display:none; } .... Use Page Breaks Page breaks in the browser aren't as reliable as they are in Microsoft Word, especially considering the variable content lengths on dynamically created pages, but when utilized well make all the different in printing your website. The CSS specs don't provide a lot of print flexibility but the "page-break-before" / "page-break-after" properties prove to be useful. Page breaks are much more reliable when used with DIV elements instead of table cells. .page-break { page-break-before: always; } /* put this class into your main.css file with "display:none;" */ Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce eu felis. Curabitur sit amet magna. Nullam aliquet. Aliquam ut diam... Lorem ipsum dolor sit amet, consectetuer adipiscing elit.... Size Your Page For Print Obviously your computer monitor can provide a large amount of width to view a page, but I recommend setting the content area width to 600px (an inch equivalent may be better, but I try to deal with one unit specifically, which is pixels). This ensures that words wont bleed outside the print area. Use this width measurement with the page break DIVs you've created in your stylesheet. After you know the width of your printed content area, adjust the dimensions of content blocks inside the main content area if necessary. Test! Like any type of programming, testing is important. Note that if you have a website that serves dynamic data, you wont be able to win all the time but you may be able to figure a scheme to format content well most of the time. Be sure to test in multiple browsers (when creating customer websites, I try to check all "Grade A" browsers). Modifying your page structure for better print results is probably easier than you think -- at least improving your existing template will be. Check back soon for part two, where we analyze optimizing a website's content for print.
February 6, 2008
by David Walsh
· 14,101 Views · 1 Like
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,837 Views
article thumbnail
Custom Date Formatting in SQL Server
SQL Server doesn't always adhere to its date/time formatting. Here's how to create your own.
February 4, 2008
by Boyan Kostadinov
· 152,952 Views
article thumbnail
Use CSS to Override Default Text Selection Color
[img_assist|nid=654|title=|desc=|link=none|align=middle|width=500|height=146] One of those cool CSS3 declarations that you can use today is ::selection, which overrides your browser-level or system-level text highlight color with a color of your choosing. At the time of this writing, only Safari and Firefox are supporting this, and both in slightly different ways. Fortunately, this can be thought of as one of those "forward-enhancement" techniques. It's a nice touch for those using modern browsers, but it just gets ignored in other browsers and it's not a big deal. Here is the rub: ::selection { background: #ffb7b7; /* Safari */ } ::-moz-selection { background: #ffb7b7; /* Firefox */ } Within the selection selector, background is the only property that works. What you CAN do for some extra flair, is change the selection color for different paragraphs or different sections of the page. [VIEW EXAMPLE] All I did was use different selection color for paragraphs with different classes: p.red::selection { background: #ffb7b7; } p.red::-moz-selection { background: #ffb7b7; } p.blue::selection { background: #a8d1ff; } p.blue::-moz-selection { background: #a8d1ff; } p.yellow::selection { background: #fff2a8; } p.yellow::-moz-selection { background: #fff2a8; } Original post here.
February 1, 2008
by Chris Coyier
· 32,439 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,520 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
Inserting Variable Headers in Apache
A buddy of mine was discussing a problem he was having with his corporate web site. It's hosted on multiple web servers behind a load balancer. The problem is, they are having problems with one of the web servers but they can't figure out which. I remember that back at JupiterHosting, we had a similar problem and that one of my guys there injected a header that allowed us to track which server a specific request was coming from. Unfortunately for my friend, that was about as far as I remembered. (I was management then, I didn't pay attention to details) However, he's a bright guy and had already thought of this...the difference was, he knew basically how to do it. I started playing with ideas on my development server and got about 75% of the way there when he IMed me that he had it working. (So much for speed) I fired up FireFox and TamperData and sure enough, he had a custom header in there. (BTW, TamperData is invaluable for debugging things like this.) However, when I followed his direction, it just was not happening for me. Googling around found me a LOT of copies of the Apache manual, but no concrete examples. So, since I couldn't find the answer on the web, I decided to post how I did this in case some other Apache noob comes looking for it. First, an important detail, my development environment is a customized version of CentOS 5. I use yum for just about everything, except Apache, PHP, MySQL and their support programs. I use a script that comes with DirectAdmin, my production control panel of choice, to maintain those pieces. The important thing to note here is that CentOS does NOT use apachectrl to start and stop apache. The answer to inserting a header, of course, revolves around PassEnv. If you have mod_env installed in your Apache 1.3.7 or Apache 2.x, this will work. I'm working with Virtual Hosts and each development site has it's on conf file that is included into the main httpd.conf. The great thing about PassEvn though is you can put it in an .htaccess file as well. This means for testing, you don't have to constantly be bouncing the service. To identify my server, I decided I wanted to add a header that displayed the host name that the page was being served from. This means in my conf file or .htaccess, I need the following: PassEnv HOSTNAME Header set X-MyHeader "%{HOSTNAME}e" That gets us about 75% there. The PassEnv makes the HOSTNAME environment variable available to APache and the Header command actually sets the new header. "%{VARAIABLENAME}e" is the syntax for displaying the variable in the header. All that is fine and good and if you drop that in your .htaccess file and then hit a page on the site, you will get: X-MyHeader (null) Now, my friend said he added: export HOSTNAME=`hostname` to his apachectrl script and all was good. (note that those are backticks and not single quotes...very important) I tried this and (if you read the note above, you see this coming) it did not fix the problem. Digging deeper, I found that apachectrl sources a file /usr/sbin/envvars. Looking it, it's obvious that this is where they expect you to put these commands so you don't have to have a customized version of apachectrl. So I took my export out of apachectrl and put it in envvars. Still no dice, yeah, I know, you expected this. The problem, as I explained above, is that if you are using "service httpd start" on CentOS then apachectrl is being ignored. Lickily for us, /etc/init.d/httpd is another bash script. So I grabbed the lines out of apachectrl that sourced /usr/sbin/envvars, inserted them in /etc/init.d/httpd and BINGO, we have a header. if test -f /usr/sbin/envvars; then . /usr/sbin/envvars fi I put them high up in the file, near where it sources the functions file. So, it is possible, and even easy to add custom headers into Apache that include environment variables. You need to make sure that mod_env and mod_headers are both installed and the rest is just figuring out where to put things. Yes you can also access this new information in PHP via the $_ENV super global, just not in the way you might expect. A var_dump of the $_ENV on my development server now looks like this: array(8) { ["HOSTNAME"]=> string(5) "david" ["TERM"]=> string(5) "xterm" ["LD_LIBRARY_PATH"]=> string(15) "/etc/httpd/lib:" ["PATH"]=> string(29) "/sbin:/usr/sbin:/bin:/usr/bin" ["PWD"]=> string(1) "/" ["LANG"]=> string(11) "en_US.UTF-8" ["SHLVL"]=> string(1) "2" ["_"]=> string(15) "/usr/sbin/httpd" } As you can see, the header X-MyHeader is not exposed, the variable it contains, HOSTNAME, is. For the record, I do realize that hostname was probably not the best example since it's usually in the $_SERVER array. However, the point of the experiment was not to expose this information to PHP, it was to put it in the response from the server.
January 26, 2008
by Cal Evans
· 19,975 Views
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
FreeMarker in NetBeans IDE 6.0: First Scenario
NetBeans IDE 6.0 provides support for FreeMarker, on many levels, covering a variety of scenarios. To not confuse things, I'll deal with each scenario in a separate article. The first scenario is aimed at NetBeans plugin authors. Authors of plugins frequently need to provide file templates to the users of their plugins. In short, FreeMarker is the language you can use to define these file templates. Your users will not deal with these file templates, at least not necessarily. Instead, they will use a wizard that will generate a file. Under the hood, the wizard will pass the values typed by the user (in the wizard's panels) to a FreeMarker file template for processing. In this article, I will show how you create such a file template and how to hook it into a wizard. In short, you will create a NetBeans module that provides a wizard that passes values to a FreeMarker template to generate a document when the user clicks "Finish" in the wizard. Take the steps below: Install the FreeMarker plugin. Install the FreeMarker Template Sample into NetBeans IDE 6.0. When you do this, you will be providing a sample project that will install syntax coloring and code completion for FreeMarker. (The sample plugin will also install other things, but so as not to confuse things, we won't look at these other features in this article.) Get the sample and install it. After you install the above plugin, go to Samples | NetBeans Modules in the New Project wizard (Ctrl-Shift-N). There you will find "FreeMarker Support Sample". Complete the wizard by clicking Next and Finish. Right-click the project node and install it. Now, all files that end in "ftl" or "template" will have FreeMarker syntax coloring and code completion. We will see this in action in a future step below. Create the plugin's initial source structure. Create a new module project, choosing NetBeans Modules | Module in the New Project wizard, and then completing the wizard, giving the project any name and code name base you like. In this case, I am interested in creating a module containing file templates for the "ItsNat" web framework. Therefore, I've called the module "ItsNatFileTemplates" and the code name base "org.netbeans.modules.itsnatfiletemplates". Generate a wizard. Let's generate the wizard's structure. Right-click the project node and choose New | Other. In the New Project wizard, choose Module Development | Wizard. Click Next. Choose "New File" and type "1" in "Number of Wizard Panels". Click Next. Type something in the class name prefix, such as "ItsNatServlet". Set something appropriate in the Category, Icon, and Package fields. Click Finish. Here's my source structure at this point: We don't need to know much about the generated code. We'll deal with the files one by one, as we need them. First, we will work with the iterator class, above it is called "ItsNatServletWizardIterator". We are going to modify it in such a way that we will add an existing panel, from the NetBeans sources, to our sequence of panels. Currently, we only have one and it is blank (look at "ItsNatServletVisualPanel1" in Design mode). So, we are going to replace this panel with an existing panel. The existing panel provides the fields "Class Name", "Project", and "Package", which we therefore will not need to create ourselves. Before continuing, open the layer file and add one attribute below the other attributes (or anywhere in the list) that modify the file template, to specify that we will be making use of the FreeMarker template engine: Set dependencies. In the next steps, we'll be adding code to the wizard iterator. Before doing so, we need to set some dependencies on modules that provide the NetBeans APIs that we will need. Therefore, set dependencies on the following: 'Java Project Support', 'Project API', and 'Project UI API' (right-click the project in the Projects window, choose Properties, click Libraries, then set dependencies on the above three and click OK). Specify our wizard panel. The first lines of the "getPanels()" method in the "ItsNatServletWizardIterator" are as follows: private WizardDescriptor.Panel[] getPanels() { if (panels == null) { panels = new WizardDescriptor.Panel[]{ new ItsNatServletWizardPanel1() }; Replace the above lines with these: private WizardDescriptor.Panel packageChooserPanel; private WizardDescriptor.Panel[] getPanels() { Project project = Templates.getProject(wizard); Sources sources = (Sources)project.getLookup().lookup(Sources.class); SourceGroup[] groups = sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA); packageChooserPanel = JavaTemplates.createPackageChooser(project,groups); if (panels == null) { panels = new WizardDescriptor.Panel[] { packageChooserPanel, }; The above is a bit of magic that replaces the wizard panel that we created with a panel that all Java source file wizards have in NetBeans IDE. Clean up. Fix imports (Ctrl-Shift-I), making sure to select "org.netbeans.spi.project.ui.templates.support.Templates" from the Fix All Imports box. You can now delete the two classes that form the panel. That is, just delete the wizard panel and the visual panel. You don't need them. Then, having a nice little module which includes just one Java class, just install it. Try the plugin. Now, remember the category you selected, back in step 4, when you created the wizard? If not, look in the layer.xml file, which should give you a clue. Now that you have installed your plugin, you should be able to find your new wizard in the New File wizard and invoke it from there. You should see something that looks like this: Create the FreeMarker file template. When you click Finish above, nothing happens. That's what this step is all about. Let's create our FreeMarker template. Right-click the package where your Java class is found, choose New | Other and then, in the New File wizard, choose Other | Empty File. (You'll see a FreeMarker category, installed by the plugin that we installed in step 1 above, but let's leave that for a future article.) Type "ItsNatServlet.ftl" (or something else, so long as the extension is ".ftl"). Then... specify your FreeMarker template, as shown in the screenshot below. And now you can see the syntax coloring and code completion provided by NetBeans IDE 6.0, via the plugin you installed at the start of this tutorial. (It is at this point that FreeMarker becomes relevant, so apologies for the time it took to get here, but this is the exact context where FreeMarker begins to be useful in this scenario.) Hook the FreeMarker file template into the plugin. Now that our FreeMarker template is done, let's hook it into our wizard so that, when Finish is clicked by the user, it is used to create the user's file. First, open the layer.xml file and add a "URL" attribute to the file name definition of the template, pointing to the location of our FreeMarker template, and changing the extension of the file name to specify that we wll create a file with the ".java" file extension: Back in the iterator, i.e., our Java class, look at the instantiate method: public Set instantiate() throws IOException { return Collections.EMPTY_SET; } First, set dependencies on "File System API", "Datasystems API", and "Nodes API". Then change the above method to the following: public Set instantiate() throws IOException { String className = Templates.getTargetName(wizard); FileObject pkg = Templates.getTargetFolder(wizard); DataFolder targetFolder = DataFolder.findFolder(pkg); TemplateWizard template = (TemplateWizard) wizard; DataObject doTemplate = template.getTemplate(); doTemplate.createFromTemplate(targetFolder, className); FileObject createdFile = doTemplate.getPrimaryFile(); return Collections.singleton(createdFile); } Now install the module again. This time, when you complete the wizard, you will have a new "ItsNat" servlet: If you don't have the "ItsNat" JAR files on the classpath, you'll also have... helpful red error marks in the editor. At this point, there are several open items to explore in the next part of this series—for example, we defined a set of variables in the FreeMarker template. They were magically replaced when we created the file via the wizard. How did that happen? Also, the FreeMarker template starts with lines of code that seem to relate to a project license. But... when the file was created, there was no project license. Why? These two questions and others will be handled in the next part of this series.
January 21, 2008
by Geertjan Wielenga
· 33,979 Views
article thumbnail
Multiple Backgrounds: Oh, What a Beautiful Thing.
The current spec for CSS3 includes support for multiple backgrounds in the background property. This is going to be fantastic for semantically-minded CSS developers. Many of the extra hooks that get thrown into HTML are there only to help out extra background images. Think about this common technique for blockquotes. This is some blockquoted text. The extra span in there is completely un-semantic, but it is often used so that you can get an extra background image in there. One for the quote mark in the upper left and one for the quote mark in the lower right: [img_assist|nid=349|title=|desc=|link=none|align=center|width=500|height=149] Blockquote example from here. With multiple backgrounds the extra hook is not needed. You can apply both the upper left and lower right image both to the blockquote element. Here is what the CSS will look like: blockquote { background: url('left.jpg') top left no-repeat, url('right.jpg') top right no-repeat, url('middle.jpg') top center repeat-x; } Notice you can set both the location and how it will repeat in each of the comma-separated backgrounds. I like the clean syntax of this, but it does present a problem. It is not backwards-compatible whatsoever. Older browsers that are not supporting this will just see no background at all, instead of for example, just the first image which would make sense. That means we can't just start using this in a forward-enhancement movement, unless we declare browser-specific stylesheets for the browsers that support it. At the time of this writing, only Safari is supporting multiple backgrounds. Here is a link to a quick example of some buttons utilizing multiple backgrounds in order to shrink and grow seamlessly. Remember, Safari-only right now. Remind you of anything? Sliding doors. Multiple backgrounds completely absolute sliding doors. Better semantics... No more complicated work-around techniques.... Oh, what a beautiful thing.
January 21, 2008
by Chris Coyier
· 11,022 Views
article thumbnail
A Groovy DSL from Scratch in Two Hours
Through DZone I found Architecture Rules, a lovely little framework that abstracts JDepend. Architecture Rules is configured via its own XML schema.
January 20, 2008
by Steven Devijver
· 63,161 Views · 5 Likes
article thumbnail
GroovyShell and memory leaks
Time to talk about creating new classes at runtime in Groovy. There seems to be some fear, uncertainty and doubt about memory leaks and evaluating code with Groovy in the form of calling an eval() method. The code that seems to cause consternation is this: def shell = new GroovyShell() 1000.times { shell.evaluate "x = 100" } The groovy.lang.GroovyShell instance will call the parseClass() method on an internal groovy.lang.GroovyClassLoader instance, which will create a 1000 new classes. The classes will all extend the groovy.lang.Script class. With every new Class created a little bit more memory will be used. As long as the groovy.lang.GroovyShell instance and thus its internal groovy.lang.GroovyClassLoader instance is not garbage collected this memory will remain occupied, even if you don't keep a reference to these classes. This is standard Java ClassLoader behavior. So, how to solve this problem? Well, ClassLoaders in Java are somewhat hard to handle, but it's not so hard once you understand how they work. But lets also consider the root of the problem, namely the fact that Groovy creates a new Class for each script that is evaluated. Before answering why Groovy always creates new Class objects when evaluating code let's first try to fix the code above. One way to fix it is this: def shell = new GroovyShell() 1000.times { shell.evaluate "x = 100" } shell = null By setting the shell variable to null, will the GroovyClassLoader instance be garbage collected? We can guarantee it will in this bit of code. But then again this code does not do anything useful :-) Here's another way to fix it: def shell = new GroovyShell() def script = shell.parse "x = 100" 1000.times { script.run() } By evaluating - parsing - the code only once and calling the run() method on the groovy.lang.Script instance a 1000 times we only use 1/1000th of the memory :-) The parse() method returns a groovy.lang.Script instance. But again, let's consider a more realistic use case. After all, the article that originally critized Groovy for causing memory leaks implies that evaluating code any number of times is a valid requirement in entreprise applications. Let's say it's more of a corner case but still, the functionality is there and it can solve real-world problems. Evaluating Groovy code may be particularly useful and critical when evaluating code on demand. This could happen when an application reads code from file or a database to execute custom business logic. Let's consider the case where developers create a DSL or Domain Specific Language like this: assert customer instanceof Customer assert invoice instanceof Invoice letterHead { customer { name = customer.name address { line1 = "${customer.streetName}, ${customer.streetNumber}" line2 = "${customer.zipCode} ${customer.location}, ${customer.state}" } } invoiceSummary { number = invoice.id creationDate = invoice.createdOn dueDate = invoice.payableOn } } To parse this DSL developers wrote this code (using the iText PDF library): import com.lowagie.text.* import com.lowagie.text.pdf.* class LetterHeadFormatter { static byte[] createLetterHeadForInvoice(Customer cust, Invoice inv, String dsl) { Script dslScript = new GroovyShell().parse(dsl) dslScript.binding.variables.customer = cust dslScript.binding.variables.invoice = inv Document doc = new Document(PageSize.A4) def out = new ByteArrayOutputStream() PdfWriter writer = PdfWriter.getInstance(doc, out) doc.open() dslScript.metaClass = createEMC(writer, dslScript) dslScript.run() doc.close() return out.toByteArray() } static ExpandoMetaClass createEMC(PdfWriter writer, Script script) { ExpandoMetaClass emc = new ExpandoMetaClass(script.class, false) emc.letterHead = { Closure cl -> PdfContentByte content = writer.directContent cl.delegate = new LetterHeadDelegate(content) cl.resolveStrategy = Closure.DELEGATE_FIRST cl() } emc.initialize() return emc } } (Check the attachements of this article to download this code. Read the README.txt file if you want to run the load test yourself, and please report back the results. Also, check the PDF file for the output of the DSL.) On line 6 the parse() method is called. I wrote a load test that calls the createLetterHeadForInvoice() method 1 million (!) times (with regular calls to System.gc()). On my Windows XP machine, when I run the load test with Ant the java process memory usage fluctuates between 32 and 37Mb and remains stable over the course of several hours. Are the GroovyShell and internal GroovyClassLoader instances garbage collected? Yes they are. Is there a memory leak? No. So why does Groovy create Classes when evaluating scripts? Every bit of code in Groovy is a java.lang.Class. This means that it's loaded by a java.lang.ClassLoader and remains in memory unless the ClassLoader can be garbage collected. Why isn't a Class object garbage collected as soon as it's no longer used? Why does the ClassLoader itself have to be garbage collected before the classes it has loaded are removed from memory? If classes would be automatically discarded and reloaded their static variables and static initialization would be executed on each reload. That would be quite surprising and unpredictable. That's why ClassLoaders have to keep hold of their classes, to assure predictable behavior. There may be other technical reasons, but this is the most obvious one. Once the ClassLoader object itself gets garbage collected (because it's no longer referenced in any stack) the garbage collector will attempt to unload all its Class objects. Obviously, creating a lot of classes at runtime in the same ClassLoader will increase the memory usage and will typically create a memory leak. On the other hand, since every Groovy class is a real Java Class (without exception) you don't have to make the distinction. In conclusion: there is no memory leak in GroovyShell or GroovyClassLoader. Download the sample code and verify for yourself. Your code can create a memory leak by the way ClassLoaders are used - either explicitly by your code or implicitly.
January 19, 2008
by Steven Devijver
· 33,798 Views · 4 Likes
  • Previous
  • ...
  • 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
×