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

Latest Articles - DZone

article thumbnail
How to Extract Video Still Frames with MPlayer
While working on a video content management system, I was in need of capturing frames from video files so they can be used as a preview for video. The system already had some code in place but it only worked for video encoding in Windows Media format (.wmv extension). That would not do, I thought, not in this day and age when we have so many file formats and video codecs. So I need to able to: Capture video frames from within .NET code Capture images from all kinds of different video formats Not reinvent the wheel while satisfying #1 and #2 Enter MPlayer Stolen directly from the Information page of MPlayer, "MPlayer is a movie player which runs on many systems (see the documentation). It plays most MPEG/VOB, AVI, Ogg/OGM, VIVO, ASF/WMA/WMV, QT/MOV/MP4, RealMedia, Matroska, NUT, NuppelVideo, FLI, YUV4MPEG, FILM, RoQ, PVA files, supported by many native, XAnim, and Win32 DLL codecs. You can watch VideoCD, SVCD, DVD, 3ivx, DivX 3/4/5 and even WMV movies..". To add my own description, MPlayer is an open source command line video player. So What Metallica has an old song called "So What", great tune for the metal heads in all of us. The answer is simple, MPlayer can do a lot more than play video. It can capture images, stream video over http and even transcode video from one format to another (but the last feature is grounds for another article). Putting It Together You will need: 1 download of MPlayer Windows executable from http://www.mplayerhq.hu/design7/dload.html 1 download of the MPlayer Windows binary codecs package from http://www.mplayerhq.hu/design7/dload.html 1 MPlayer .NET wrapper provided in this article Setup Extract the mPlayer executable (mplayer.exe) Extract the mPlayer codecs in a directory called "codecs" in the same directory as the mPlayer executable Add a reference to the mPlayerWrapper project or compiled DLL Usage Capture with default arguments in C# // Specify the path to the video filestring videoFilePath = @"drive letter:\path\to\myVideo.mpg";// Declare the mplayer instance with the mplayer executable residing in the// same directory as your executablemPlayerWrapper mPlayerInstance = new mPlayerWrapper();// Capture framesmPlayerInstance.captureFrames(videoFilePath); in VB.NET ' Specify the path to the video filedim videoFilePath As String = "drive letter:\path\to\myVideo.mpg"' Declare the mplayer instance with the mplayer executable residing in the' same directory as your executabledim mPlayerInstance As new mPlayerWrapper()' Capture framesmPlayerInstance.captureFrames(videoFilePath) This will capture 12 frames with 5 second interval between each frame and put them in the same directory as your video file. The filename of each frame will be "myVideo_thumb01.jpg" to "myVideo_thumb12.jpg". Each frame will be scaled to 270x200. Capture arguments mPlayerPath - sets the path where the mPlayer executable (mplayer.exe) is located. The default is in the same directory as your code is executing. currentFilePath - sets the file path to the video file you are using cleanOutputDirectory - deletes all the "jpg" images in the capture output directory before capturing captureInterval - sets the interval at which frames will be captured. Only applicable if using a time interval capture method (as outlined below) numberOfFramesToCapture - the number of frames to be captured captureExactNumberOfFrames - tells the wrapper to attempt to capture the exact number of frames as specified by the "numberOfFramesToCapture" property. This can be used if a file has too few frames but you still want to capture an exact number useTimeSeekToCapture - used to set the wrapper method of capture to seeking through the file instead of capturing a frame at an interval thumbnailPrefix - the prefix to be used when creating the filenames for captured frames. The default is the name of the video with "_thumb" append to it as in "myVideo_thumb01.jpg" capturedFrameWidthHeight - the width:height that each frame will be scaled to. The default is 270:200 scaleCapturedFrames - used in conjunction with the "capturedFrameWidthHeight" property to scale down the captured frames. Set to true by default Capture in a different output directory in C# // Specify the path to the video filestring videoFilePath = @"drive letter:\path\to\myVideo.mpg";// Specify the output directorystring outputPath = @"drive letter:\path\to\output directory";// Declare the mplayer instance with the mplayer executable residing in the// same directory as your executablemPlayerWrapper mPlayerInstance = new mPlayerWrapper();// Capture framesmPlayerInstance.captureFrames(videoFilePath, outputPath); in VB.NET ' Specify the path to the video filedim videoFilePath As String = "drive letter:\path\to\myVideo.mpg"' Specify the output directorydim outputPath As String = @"drive letter:\path\to\output directory"' Declare the mplayer instance with the mplayer executable residing in the' same directory as your executabledim mPlayerInstance As new mPlayerWrapper()' Capture framesmPlayerInstance.captureFrames(videoFilePath, outputDirectory) Using distinct capture methods: captureFramesWithInterval - by default captures a frame every 5 seconds with up to 12 frames captureFramesWithTimeSeek - by default captures 1 frame each second with up to 12 frames by seeking through the file Bonus getFileProperties - returns a SortedList of video and audio properties for the file getAudioProperties - returns a SortedList of audio properties for the file getVideoProperties - returns a SortedList of video properties for the file Downloads mPlayerWrapper: http://blog.tech-cats.net/examples/dotnet/mPlayerWrapper.dll mPlayerWrapper Source: http://blog.tech-cats.net/examples/dotnet/mplayerWrapper-v0.2.zip
March 4, 2008
by Boyan Kostadinov
· 24,032 Views
article thumbnail
A Domain-Specific Language for unit manipulations
Domain-Specific Languages are a hot topic, and have been popularized by languages like Groovy and Ruby thanks to their malleable syntax which make them a great fit for this purpose. In particular, Groovy allows you to create internal DSLs: business languages hosted by Groovy. In a recent research work, Tiago Antão has decided to use Groovy to model the resistance to drugs against the Malaria disease. In two blog posts, Tiago explains some of the tactics he used, and how to put them together to create a mini-language for health related studies. In this work, he needed to represent quantities of medecine, like 300 miligram of Chloroquinine, a drug used against Maralia. Groovy lets you add properties to numbers, and you can represent such quantities with just 300.mg. Inspired by this idea, the purpose of this article is to examine how to build a mini-DSL for manipulating measures and units by leveraging the JScience library. First of all, let's speak about JScience. JScience is a Java library leveraging generics to represent various measurable quantities. JScience is also the Reference Implementation for JSR-275: javax.measure.*. Whether it is for measuring mass, length, time, amperes or volts (and many more), the calculations you can do are type-safe and checked at compile-time: you cannot add a second to a kilogram, your program wouldn't compile. This is definitely one of the strength of the library. However fluent the library is, the notation used to represent an amount of some unit is still not as readable as scientist could wish. How do you represent a mass with JScience? import static javax.measure.unit.SI.*; import javax.measure.* import org.jscience.physics.amount.*; // ... Amount m3 = Amount.valueOf(3, KILO(GRAM)); Amount m2 = Amount.valueOf("2 kg"); Amount sum = m3.plus(m2); The first expression leverages static imports to represent the KILO (GRAM) unit, while the second simply parses the mass from a String. The last line does just an addition between the two masses. Still, it doesn't look like what a physicist would write. Wouldn't we want to use a mathematical notation, like 3 kg + 2 kg? We will see how you can do this in Groovy. Our first step will be to add units to numbers. We can't write 2 kg, as it's not valid Groovy, instead, we'll write 2.kg. To so, we'll add some dynamic properties to numbers, thanks to the ExpandoMetaClass mechanism. import javax.measure.unit.* import org.jscience.physics.amount.* // Allow ExpandoMetaClass to traverse class hierarchies // That way, properties added to Number will also be available for Integer or BigDecimal, etc. ExpandoMetaClass.enableGlobally() // transform number properties into an mount of a given unit represented by the property Number.metaClass.getProperty = { String symbol -> Amount.valueOf(delegate, Unit.valueOf(symbol)) } // sample units println( 2.kg ) println( 3.m ) println( 4.5.in ) See how we created kilograms, meters and inches? The "metaclass" is what represents the runtime behavior of a class. When assigning a closure to the getProperty property, all the requests for properties on Numbers will be rooted to this closure. This closure then uses the JScience classes to create a Unit and an Amout. The delegate variable that you see in this closure represents the current number on which the properties are accessed. Okay, fine, but at some point, you'll need to multiply these amounts by some factor, or you will want to add to lengths together. So we'll need to do leverage Groovy's operator overloading to do some arithmetics. Whenever you have methods like multiply(), plus(), minus(), div(), or power(), Groovy will allow you to use the operators *, +, -, /, or **. Some of the conventions for certain of these operations being a bit different from those of Groovy, we have to add some new operator methods for certain of these operations: // define opeartor overloading, as JScience doesn't use the same operation names as Groovy Amount.metaClass.multiply = { Number factor -> delegate.times(factor) } Number.metaClass.multiply = { Amount amount -> amount.times(delegate) } Number.metaClass.div = { Amount amount -> amount.inverse().times(delegate) } Amount.metaClass.div = { Number factor -> delegate.divide(factor) } Amount.metaClass.div = { Amount factor -> delegate.divide(factor) } Amount.metaClass.power = { Number factor -> delegate.pow(factor) } Amount.metaClass.negative = { -> delegate.opposite() } // arithmetics: multiply, divide, addition, substraction, power println( 18.4.kg * 2 ) println( 1800000.kg / 3 ) println( 1.kg * 2 + 3.kg / 4 ) println( 3.cm + 12.m * 3 - 1.km ) println( 1.5.h + 33.s - 12.min ) println( 30.m**2 - 100.ft**2 ) // opposite and comparison println( -3.h ) println( 3.h < 4.h ) We can also do comparisons, as shown on the last line above, since these types are comparable. Again, free of charge. Something we have covered yet is compound units, such as speed, which is a mix of a distance and a duration. So, if you wanted to use a speed limit, you would like to write 90.km/h but our DSL in its current state would only allow you to write 90.km/1.h, which doesn't really look nice. To circumvent this issue, we could create as many variables as units. We could have a h variable, a km variable, etc. But I'd prefer something more automatic, by letting the script itself provide these units. In Groovy scripts, you can have local variables (whenever you define a variable, it's a local variable), but you can also pass or access variables through a binding. This is a convenient way to pass data around when you integrate Groovy inside a Java application, for instance, to share a certain context of data. We are going to create a new Binding called UnitBinding which will override the getVariable() method, so that all non-local variables which are used withing the Groovy script are looked up in this binding. You'll notice a special treatment for the variable 'out', which is where the println() method looks for for the output stream to use. // script binding to transform free standing unit reference like 'm', 'h', etc class UnitBinding extends Binding { def getVariable(String symbol) { if (symbol == 'out') return System.out return Amount.valueOf(1, Unit.valueOf(symbol)) } } // use the script binding for retrieving unit references binding = new UnitBinding() // inverse units println( 30.km/h + 2.m/s * 2 ) println( 3 * 3.mg/L ) println( 1/2.s - 2.Hz ) The velocity now looks much more like the mathematical notation everybody would use. Now that all this magic is done, there's still one last thing we could do. Sometimes, you may want to convert different units, like feet and meters or inches and centimers. So, as the last step of our units DSL experiments, we'll add a to() method to do convertions. // define to() method for unit conversion Amount.metaClass.to = { Amount amount -> delegate.to(amount.unit) } // unit conversion println( 200.cm.to(ft) ) println( 1.in.to(cm) ) At this point, we are able to easily manipulate amounts of any unit in a very convenient and natural notation. The magic trick of adding properties to numbers makes the process of creating a unit DSL straightforward. This DSL is just a small part of the equation, as you may certainly want to represent other business related concepts, but this article will have shown you how to decorate a powerful existing library, so that the code becomes more natural to use by the end users of your DSL. In further articles, we'll discover some other tricks! Stay tuned!
March 1, 2008
by Guillaume Laforge
· 35,119 Views
article thumbnail
Who Needs EJB 3.1 (lite)?
There is an interesting statement about technologies dedicated to a given profile in the J2EE 6 spec. You may have noticed the descriptions of something called EJB 3.1 (lite). "EJB 3.1 (Lite)" refers to the idea of allowing implementations to deliver a subset of EJB 3.1. The contents of this "lite" subset are wholly undecided at this point, but as an example it might include the annotation-based programming model introduced in EJB 3.0, restricted to session beans with local interfaces (only). In other words, you could write an annotated session bean with a local interface and use it in your Web Profile-compliant product (assuming (B) is accepted, that is). But, for example, you could not write a EJB 2.1-style session bean, or an EJB 3.0 message-driven bean, or a EJB 3.0 stateful session bean with a remote interface. It seems that someone is obsessed with EJB. I don't see any advantage of EJB 3.1 (Lite) over POJO except complications that affect everyone. deployment and packaging - WAR vs EJB JAR, classloader isolation etc. need for an application server - forget about Tomcat or Jetty complexity overhead - you still need a lot of about EJB as a bean lifecycle, transaction, JNDI etc. From a developer's point of view there isn't much difference between EJB full and EJB lite. Both of them bring the same level of complexity and make development more complicated. I don't think that EJB 3.1 could be useful for developers. So, who really needs this EJB 3.1 lite?
March 1, 2008
by Roman Pichlik
· 19,972 Views
article thumbnail
Creating a Gmail Like Ajax Status Display
Most of us geeks know and love Gmail. It has a very nice interface and it is an inspiration to constantly improve our own web applications. Today, I set out to create an unobtrusive Gmail like page status message, much like the one shown in the screen shot: [img_assist|nid=1488|title=|desc=|link=none|align=undefined|width=501|height=79] My requirements were simple: Should look like the one used in Gmail Should be able to just include the source JavaScript file without any further configuration Should allow the user to specify a custom status message to be displayed Should allow for the use of custom styles but none are required Integrates with Prototype.js Ajax requests The only prerequisite is Prototype.js v1.6 Let's get started. If all you care about is the end result. Here how to include it in your page: That's it! Now whenever you make an Ajax request with Prototype, you will see a message popup with the text "Loading...". You can check out the end results at http://blog.tech-cats.net/examples/ajax/ajaxStatusDisplay-Simple.html Now to the advanced features. As stated #3 and #4 above, two of our requirements are to allow the user to specify a custom status message and custom CSS styles for the displayed message. Satisfying the first one of those requirements is done by having the user create an element on the page with the custom message like so: Loading...Wait a Minute! This element does not have to be a div. It could be a any text container such as span or even input (text or hidden). What is important is the id of the element, it has to be set to "ajaxStatusDisplay_userMessage" for the custom message to be picked up. The next requirement works much in the same way. Custom styles can be specified by creating two CSS classes with certain names: "ajaxStatusDisplay_userStyle" and "ajaxStatusDisplay_userMessageStyle". Here an example that will produce the default look: And here is another example that will produce a white text on black background in the top right corner: To use the your own CSS styles, you do not need to do anything but define them as shown above (as compared to the initial version where you needed to edit the file "ajaxStatusDisplay.js" and set the "useUserCssStyles" variable to "true"). A small extra feature is the ability to change the status message at runtime. This is done by using (you guessed it), the "setStatusMessage" function as follows: // Set the status message based on the value in the "userMessage" input field ajaxStatusDisplay.setStatusMessage($F('userMessage')); To see setting the status message in action along with using a custom CSS style, check out http://blog.tech-cats.net/examples/ajax/ajaxStatusDisplay-Advanced.html You can view all the sources at: JavaScript Source: ajaxStatusDisplay.txt Simple Example Source: ajaxStatusDisplay-Simple.txt Advanced Example Source: ajaxStatusDisplay-Advanced.txt You can download the JavaScript source at: http://blog.tech-cats.net/examples/ajax/ajaxStatusDisplay.js
February 29, 2008
by Boyan Kostadinov
· 25,720 Views
article thumbnail
Effective Eclipse: Custom Templates
The same way I try to avoid the redundancy in my code, the same way I try to avoid the redundancy in my writing. I am lazy and templates do the most writing for me. Eclipse comes bundled with predefined templates, but they are too general and not all of them are too useful. The real power is in custom templates. In this article I would like to show you how to create them and list a few useful pieces for inspiration. What are templates Exactly as the name suggests, templates are little pieces of code with defined placeholders. An example of simple template is System.out.println(${text}); Each template has a name, which serves as a shortcut to the template itself. You type the name, press CTRL + SPACE and it will be expanded. Our first template would expand to [img_assist|nid=1424|title=|desc=|link=none|align=middle|width=186|height=19] I will not explain here what it all means, I already did this in my previous post on templates. What is important now, is that the ${text} placeholder (variable) was highlighted and can be edited immediately. The true power of templates can be fully seen in more complex templates. The first power point lies in the fact, that you can have more than one variable with same name. Our second template will have more variables: int ${increment} = ${value}; y = ${increment} + ${increment}; and will expand to [img_assist|nid=1428|title=|desc=|link=none|align=middle|width=204|height=45] When you start typing now, all occurrences of increment variable will be changed. You can then switch to the next variable by pressing TAB key. In the end, you can have [img_assist|nid=1425|title=|desc=|link=none|align=middle|width=110|height=43] in just three key presses - one for i, one for TAB and one for 2. To make it even better, the template system provides predefined variables, which will be expanded depending on their context. I will not list them, you can find them under the Insert variable button. [img_assist|nid=1426|title=|desc=|link=popup|align=middle|width=640|height=274] Notice, that you are not getting only a list, you are also getting a description and an usage example. To make it clear, I will illustrate one builtin variable - ${enclosing_type}. When this one is expanded you will get a name of the class (or interface, enum) in which your template was expanded. "But how can I use it?", I hear you asking. I have prepared few templates just for inspiration, I believe that after reading this you will find thousands others and I believe that you will create them and share them with us. Custom templates Open Window -> Preferences and type Templates into the search box. [img_assist|nid=1427|title=|desc=|link=popup|align=middle|width=640|height=578] You will get a list of all editors, and their respective template settings. This is because templates are closely bound to editors - you will get different builtin variables in different editors. Also note, that your list may vary from my list, it all depends on installed plugins. Now you must decide what type of template you would like to create. If it is a Java template, which will be applicable in context of classes, interfaces and enums, then choose Java -> Editor -> Templates. If you create a Java template you won't be able to use it in XML editor, that's quite expected. So click on the New button, to get a dialog. Here it is, in all its glory: [img_assist|nid=1430|title=|desc=|link=popup|align=middle|width=640|height=316] Name is the name of the template. Choose it well, because it will serve as a shortcut to your template. After you type the name of the template (or at least a few characters from its name) and hit CTRL+SPACE it will be expanded. Description is what you will see next to the template name when the template name is ambiguous. [img_assist|nid=1433|title=|desc=|link=none|align=middle|width=415|height=296] Pattern is the template body. And the Context? This varies in every editor. If you look in the combobox in Java templates, you will see Java and Javadoc. It is simple a context within the respective editor in which the template would be applicable. Check Automatically insert if you want the template to expand automatically on ctrl-space when there is no other matching template available. It is usually good idea to leave the checkbox checked, otherwise you would get a template proposal "popup". See what happens when I uncheck it on sysout template. [img_assist|nid=1432|title=|desc=|link=none|align=middle|width=256|height=46] If I would have checked it, it would automatically expand, as there is no other template matching sysout* pattern. My list So here is the list I promised. I have categorized it. Java (Java->Editor->Templates) logger - create new Logger private static final Logger logger = Logger.getLogger(${enclosing_type}.class.getName()); Notice the usage of ${enclosing_type} variable. This way you can create a logger in few hits. After the template expands, you will probably get red lines, indicating that Logger clas could not be found. Just hit CTRL + SHIFT + O to invoke the organize imports function. You are using shortcuts, aren't you? loglevel - log with specified level if(${logger:var(java.util.logging.Logger)}.isLoggable(Level.${LEVEL})) { ${logger:var(java.util.logging.Logger)}.${level}(${}); } ${cursor} Let me explain the details. ${logger:var(java.util.logging.Logger)} uses a builtin "var" variable. It starts with logger, the default name, in case the var variable finds no match. It is then followed by var(java.util.logging.Logger), what will evaluate to the name of the variable (member or local) of the specified type (in our case of the Logger type). Further, the ${cursor} variable marks the place where the cursor will jump after you press enter. So the result after expanding could be [img_assist|nid=1429|title=|desc=|link=none|align=middle|width=297|height=66] You might wonder what is the purpose of the if. It is there only for performance gain. If specified level is not allowed the logging method will never be called and we can spare JVM some string manipulation to build the message. readfile - read text from file Never can remember how to open that pesky file and read from it? Nor can I, so I have a template for it. BufferedReader in; try { in = new BufferedReader(new FileReader(${file_name})); String str; while ((str = in.readLine()) != null) { ${process} } } catch (IOException e) { ${handle} } finally { in.close(); } ${cursor} Maven (Web and XML -> XML Files -> Templates) dependency - maven dependency ${groupId} ${artifactId} ${version} ${cursor} parent - maven parent project definition ${artifactId} ${groupId} ${version} {$path}/pom.xml ${cursor} web.xml (Web and XML -> XML Files -> Templates) servlet - new servlet definition ${servlet_name} ${servlet_class} ${0} ${servlet_name} *.html ${cursor} JSP pages (Web and XML -> JSP Files -> Templates) spring-text - spring text field with label and error ${cursor} spring-checkbox ${cursor} spring-select ${cursor} spring-generic ${cursor} These are my favorites. They regularly save me a huge amount of time. Creating spring forms has never been easier for me. In some editor types you can set the template to 'new', for example, in XML editor it is new XML. This is really useful, as you can prepare the skeleton of a new file. For example, this is what I use to create new Spring servlet configuration for freemarker application. true messages Now, I can create new XML file from template and it will be ready to use. Before I knew about templates, I used to copy this from an older project, or search for it in Spring documentation. Now I don't have to.. [img_assist|nid=1431|title=|desc=|link=none|align=middle|width=640|height=201] If you can overcome the initial laziness and create your own templates from the pieces of code you really use, than this investment will shortly return in form of less typing. If you have some interesting templates, please, share them with us. You can download the templates mentioned in this post and import them using the Import button in the editor template settings.
February 28, 2008
by Tomas Kramar
· 232,763 Views · 1 Like
article thumbnail
'Move with Replace' C# method
You may not realize that System.IO.File.Move() doesn't support overwriting of an existing file. In fact, it will throw an IOException if a file with the same path as sourceDestFilename already exists. As a workaround to that limitation, I wrote a simple, yet useful wrapper method below that allows for overwriting the destination file. public static void MoveWithReplace(string sourceFileName, string destFileName) { //first, delete target file if exists, as File.Move() does not support overwrite if (File.Exists(destFileName)) { File.Delete(destFileName); } File.Move(sourceFileName, destFileName); }
February 28, 2008
by Ttt Ddd
· 76,737 Views
article thumbnail
Ruby: Escape, Unescape, Encode, Decode, HTML, XML, URI, URL
This example will show you how to escape and un-escape a value to be included in a URI and within HTML. require 'cgi' # escape name = "ruby?" value = "yes" url = "http://example.com/?" + CGI.escape(name) + '=' + CGI.escape(value) + "&var=T" # url: http://example.com/?ruby%3F=yes&var=T html = %(example) # html: example # unescape name_encoded = html.match(/http:([^"]+)/)[0] # name_encoded: http://example.com/?ruby%3F=yes&var=T href = CGI.unescapeHTML(name_encoded) # href: http://example.com/?ruby%3F=yes&var=T query = href.match(/\?(.*)$/)[1] # query: ruby%3F=yes&var=T pairs = query.split('&') # pairs: ["ruby%3F=yes", "var=T"] name, value = pairs[0].split('=').map{|v| CGI.unescape(v)} # name, value: ["ruby?", "yes"]
February 26, 2008
by Snippets Manager
· 4,038 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,366 Views · 2 Likes
article thumbnail
Creating an "Body Border" with CSS
hicksdesign has been " fiddling " with their site design. the new design features what someone called in the comments a "body border". it's basically a stroke of color just inside the entire viewable area, all the way around, in the browser window. i thought it was a nice touch and a pretty spiffy little css trick so i thought i'd feature how it was done here. check out the example page . the code four unique page elements are neccecery. div's work fine for this: here is the css for them. notice how clean the css can be. some properties are shared by all of the elements, some by only the top/bottom and left/right, and some unique to themselves. this css is coded like that, instead of repeating properties and values unnecessarily. #top, #bottom, #left, #right { background: #a5ebff; position: fixed; } #left, #right { top: 0; bottom: 0; width: 15px; } #left { left: 0; } #right { right: 0; } #top, #bottom { left: 0; right: 0; height: 15px; } #top { top: 0; } #bottom { bottom: 0; } browser compatibility works great in firefox, safari, and opera, and ie 7. does it work in ie 6 (or below)? of course not! mostly has to do with positioning. ie 6 doesn't love fixed positioning and the hacks i find ugly and not terribly reliable. the solution is just to ditch the body border for ie: header html for conditional stylesheet (put comment tags around this in use): [if lte ie 6]>
February 26, 2008
by Chris Coyier
· 29,208 Views
article thumbnail
Let's Create a Tetris Game in Compiled JavaFX Script
i thought it would be fun to spend a few posts creating a tetris game in compiled javafx script together. today i made a rough start on it, and if you promise not to laugh, i'll show you the humble beginnings. here's a screenshot of its current status: in tetris, there are several types of tetrominoes , each having a letter that it resembles. the four buttons on the left represent four of these shapes. when you press one of these buttons, the corresponding tetromino appears at the top and begins moving down the screen. when you click the rotate button, the tetromino rotates to the right, and the left / right buttons move the tetromino left and right, respectively. the code is contained in four fx program files, and needs some refactoring already. :-) before showing you the code in its current state, i'd like to point out a couple of helpful things: as explained in the spinning wheel post, the key frame animation syntax that you see here will become much less verbose as the javafx script compiler team continues to address animation. javafx script programs should always be designed with the ui binding to a model. in this program, the model is represented in one class named tetrismodel , located in the fx file of the same name. you may find it helpful to take a look the creating a compiled javafx script program with multiple fx source files post to see a hello world style program that has more than one fx file. please notice the package statments in this tetris program, as that influences where you need to put the source files and how you build them. you can obtain the javafx compiler by following the instructions in the obtaining the openjfx script compiler post. the source code (so far) here's the main program, named tetrismain.fx , that declaratively expresses the ui, and starts things up: /* * tetrismain.fx - the main program for a compiled javafx script tetris game * * developed 2008 by james l. weaver (jim.weaver at lat-inc.com) * to serve as a compiled javafx script example. */ package tetris_ui; import javafx.ui.*; import javafx.ui.canvas.*; import java.lang.system; import tetris_model.*; frame { var model = tetrismodel { } var canvas:canvas width: 480 height: 500 title: "tetrisjfx" background: color.white content: borderpanel { center: canvas = canvas {} bottom: flowpanel { content: [ button { text: "i" action: function() { canvas.content = []; insert tetrisshape { model: model shapetype: tetrisshapetype.i } into canvas.content; model.t.start(); } }, button { text: "t" action: function() { canvas.content = []; insert tetrisshape { model: model shapetype: tetrisshapetype.t } into canvas.content; model.t.start(); } }, button { text: "l" action: function() { canvas.content = []; insert tetrisshape { model: model shapetype: tetrisshapetype.l } into canvas.content; model.t.start(); } }, button { text: "s" action: function() { canvas.content = []; insert tetrisshape { model: model shapetype: tetrisshapetype.s } into canvas.content; model.t.start(); } }, button { text: "rotate" action: function() { model.rotate90(); } }, button { text: "left" action: function() { model.moveleft(); } }, button { text: "right" action: function() { model.moveright(); } } ] } } visible: true onclose: function():void { system.exit(0); } } i made the tetrisshape class a custom graphical component. therefore, it is a subclass of the compositenode class, and overrides the composenode function. note: there is a typo in line 62 of the tetrisshape.fx listing. "returnreturn" should read "return". it will be corrected asap. /* * tetrisshape.fx - a tetris piece, configurable to the * different shape types. they are: * i, j, l, o, s, t, and z * * developed 2008 by james l. weaver (jim.weaver at lat-inc.com) * to serve as a compiled javafx script example. * */ package tetris_ui; import javafx.ui.*; import javafx.ui.canvas.*; import java.awt.point; import java.lang.system; import tetris_model.*; class tetrisshape extends compositenode { private static attribute squareoutlinecolor = color.black; private static attribute squareoutlinewidth = 2; private attribute squarecolor; public attribute model:tetrismodel; public attribute shapetype:tetrisshapetype on replace { if (shapetype == tetrisshapetype.i) { squarelocs = []; insert new point(0, model.square_size * 1) into squarelocs; insert new point(0, 0) into squarelocs; insert new point(0, model.square_size * 2) into squarelocs; insert new point(0, model.square_size * 3) into squarelocs; squarecolor = color.red; } else if (shapetype == tetrisshapetype.t) { squarelocs = []; insert new point(model.square_size * 1, 0) into squarelocs; insert new point(0, 0) into squarelocs; insert new point(model.square_size * 2, 0) into squarelocs; insert new point(model.square_size * 1, model.square_size * 1) into squarelocs; squarecolor = color.green; } else if (shapetype == tetrisshapetype.l) { squarelocs = []; insert new point(0, model.square_size * 1) into squarelocs; insert new point(0, 0) into squarelocs; insert new point(0, model.square_size * 2) into squarelocs; insert new point(model.square_size * 1, model.square_size * 2) into squarelocs; squarecolor = color.magenta; } else if (shapetype == tetrisshapetype.s) { squarelocs = []; insert new point(model.square_size * 1, 0) into squarelocs; insert new point(model.square_size * 2, 0) into squarelocs; insert new point(0, model.square_size * 1) into squarelocs; insert new point(model.square_size * 1, model.square_size * 1) into squarelocs; squarecolor = color.cyan; } } private attribute squarelocs:point[]; public function composenode():node { return group { transform: bind [ translate.translate(model.square_size * model.tetrominohorzpos, (model.a / model.square_size).intvalue() * model.square_size), rotate.rotate(model.tetrominoangle, squarelocs[0].x + model.square_size / 2, squarelocs[0].y + model.square_size / 2) ] content: [ for (squareloc in squarelocs) { rect { x: bind squareloc.x y: bind squareloc.y width: bind model.square_size height: bind model.square_size fill: bind squarecolor stroke: squareoutlinecolor strokewidth: squareoutlinewidth } } ] }; } } the tetrisshapetype class defines the tetromino types: /* * tetrisshapetype.fx - a tetris shape type, which are * i, j, l, o, s, t, and z * * developed 2008 by james l. weaver (jim.weaver at lat-inc.com) * to serve as a compiled javafx script example. * */ package tetris_ui; import javafx.ui.*; class tetrisshapetype { public attribute id: integer; public attribute name: string; public static attribute o = tetrisshapetype {id: 0, name: "o"}; public static attribute i = tetrisshapetype {id: 1, name: "i"}; public static attribute t = tetrisshapetype {id: 2, name: "t"}; public static attribute l = tetrisshapetype {id: 3, name: "l"}; public static attribute s = tetrisshapetype {id: 4, name: "s"}; } and finally, here's a model class, named tetrismodel: /* * tetrismodel.fx - the model behind the tetris ui * * developed 2008 by james l. weaver (jim.weaver at lat-inc.com) * to serve as a compiled javafx script example. * */ package tetris_model; import javafx.ui.animation.*; import java.lang.system; import com.sun.javafx.runtime.pointerfactory; public class tetrismodel { public static attribute square_size = 20; public attribute a:integer; private attribute pf = pointerfactory {}; private attribute bpa = bind pf.make(a); private attribute pa = bpa.unwrap(); private attribute interpolate = numbervalue.linear; public attribute t = timeline { keyframes: [ keyframe { keytime: 0s; keyvalues: numbervalue { target: pa; value: 0; interpolate: bind interpolate } }, keyframe { keytime: 20s; keyvalues: numbervalue { target: pa; value: 370 interpolate: bind interpolate } } ] }; public attribute tetrominoangle:number; public attribute tetrominohorzpos:number = 10; public function rotate90():void { (tetrominoangle += 90) % 360; } public function moveleft():void { if (tetrominohorzpos > 0) { tetrominohorzpos--; } } public function moveright():void { if (tetrominohorzpos < 20) { //todo:replace 10 with a calculated number tetrominohorzpos++; } } } compile and execute this example, and examine the code. i'll get busy making it behave a little more like a tetris game, and show you some progress in the next post. please feel free to get ahead of me, and make your own version! regards, jim weaver javafx script: dynamic java scripting for rich internet/client-side applications immediate ebook (pdf) download available at the book's apress site
February 22, 2008
by James Weaver
· 17,687 Views
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,921 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,629 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,859 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,981 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,538 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,359 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,772 Views
article thumbnail
Coordinating Threads
Java 5 introduced many new concurrency primitives and collections, and this post is going to look at two classes that can be used to coordinate threads: CountDownLatch and CyclicBarrier. A CountDownLatch is initialized with a counter. Threads can then either count down on the latch or wait for it to reach 0. When the latch reaches 0, all waiting threads are released. A common idiom is to use a latch to trigger a coordinated start or end between threads: import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CountDownDemo { public static void main(String[] args) throws Exception { int threads = 3; final CountDownLatch startLatch = new CountDownLatch(threads); final CountDownLatch endLatch = new CountDownLatch(threads); ExecutorService svc = Executors.newFixedThreadPool(threads); for (int i = 0; i < threads; i++) { svc.execute(new Runnable() { public void run() { try { log("At run()"); startLatch.countDown(); startLatch.await(); log("Do work"); Thread.sleep((int) (Math.random() * 1000)); log("Wait for end"); endLatch.countDown(); endLatch.await(); log("Done"); } catch (Exception e) { e.printStackTrace(); } } }); Thread.sleep(100); } } private static void log(String msg) { System.out.println(System.currentTimeMillis() + ": " + Thread.currentThread().getId() + " " + msg); } } In this code, you'll see two latches get initialized. Each thread that starts up counts down on the latch and awaits the latch counting down to 0 (when all threads have been initialized). Similarly, each thread waits for all threads to complete at the same time. Running this program yields: 1194812267416: 7 At run() 1194812267517: 8 At run() 1194812267618: 9 At run() 1194812267618: 9 Do work 1194812267618: 7 Do work 1194812267619: 8 Do work 1194812267673: 7 Wait for end 1194812267688: 8 Wait for end 1194812268023: 9 Wait for end 1194812268023: 9 Done 1194812268023: 7 Done 1194812268023: 8 Done You can see that each thread hits run() at different times, but proceeds past the barrier at the same time. They each then do some random amount of work and wait for the latch, then proceed past it together. In the example above, each thread waits forever for the latch to trigger. You can also choose to wait for a specified time period before giving up. And you can check the latch to see how many threads have arrived and are now waiting. Each CountDownLatch instance can only be used once and is then dead. If you want a set of threads to repeatedly meet at a common point, you are better served by using a CyclicBarrier. A common use for this is in multi-threaded testing where it is typical to start a bunch of threads, meet, do some stuff, meet, validate some assertions, repeatedly. The prior program can be simplified by replacing the two latches with a single barrier: import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CyclicBarrierDemo { public static void main(String[] args) throws Exception { int threads = 3; final CyclicBarrier barrier = new CyclicBarrier(threads); ExecutorService svc = Executors.newFixedThreadPool(threads); for (int i = 0; i < threads; i++) { svc.execute(new Runnable() { public void run() { try { log("At run()"); barrier.await(); log("Do work"); Thread.sleep((int) (Math.random() * 1000)); log("Wait for end"); barrier.await(); log("Done"); } catch (Exception e) { e.printStackTrace(); } } }); Thread.sleep(100); } } private static void log(String msg) { System.out.println(System.currentTimeMillis() + ": " + Thread.currentThread().getId() + " " + msg); } } We can see here that the threads can repeatedly wait at the barrier, which implicitly counts down until all threads have arrived, then releases all threads. Another nice trick with CyclicBarrier is that a Runnable action can be associated with the barrier to be run by the last thread reaching the barrier. You can very simply build a start/end timer for testing with this functionality: import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TimerBarrierDemo { public static void main(String[] args) throws Exception { int threads = 3; final CyclicBarrier barrier = new CyclicBarrier(threads, new BarrierTimer()); ExecutorService svc = Executors.newFixedThreadPool(threads); for (int i = 0; i < threads; i++) { svc.execute(new Runnable() { public void run() { try { barrier.await(); long sleepTime = (int) (Math.random() * 1000); System.out.println(Thread.currentThread().getId() + " working for " + sleepTime); Thread.sleep(sleepTime); barrier.await(); } catch (Exception e) { e.printStackTrace(); } } }); } } private static class BarrierTimer implements Runnable { private long start; public void run() { if (start == 0) { start = System.currentTimeMillis(); } else { long end = System.currentTimeMillis(); long elapsed = (end - start); System.out.println("Completed in " + elapsed + " ms"); } } } } Here we rely on knowing that the barrier will be reached exactly twice - once at start and once at end. The first time it's reached, we record a timestamp and the second time it's reached we print out the timing. When we construct our barrier, we give it an instance of this timer class. Each thread then waits to start on the barrier, works for a random amount of time, and waits for the end barrier. A run looks like this: 9 working for 35 7 working for 341 8 working for 371 Completed in 372 ms Generally, you should expect the recorded elapsed time to be the maximum of the working time of any of the threads. CyclicBarrier has a few additional tricks as well - threads can wait for a time period instead of forever, check whether a barrier has been broken (by interruption or forcibly with a reset() method), and determine the number of parties and the number currently waiting.
February 7, 2008
by Alex Miller
· 32,283 Views · 1 Like
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,481 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,141 Views · 1 Like
  • Previous
  • ...
  • 1620
  • 1621
  • 1622
  • 1623
  • 1624
  • 1625
  • 1626
  • 1627
  • 1628
  • 1629
  • 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
×