I am learning to develop a game using libgdix.I follow the book Learning LibGDX game development,second edition.
I am getting stuck on using Bitmapfont.
public class AssetsFonts
{
public final BitmapFont defaultSmall;
public final BitmapFont defaultNormal;
public final BitmapFont defaultBig;
public AssetsFonts()
{
defaultSmall = new BitmapFont(Gdx.files.internal("images/arial-15.fnt"),true);
defaultNormal = new BitmapFont(Gdx.files.internal("images/arial-15.fnt"),true);
defaultBig = new BitmapFont(Gdx.files.internal("images/arial-15.fnt"),true);
defaultSmall.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
defaultNormal.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
defaultBig.getRegion().getTexture().setFilter(TextureFilter.Linear,TextureFilter.Linear);
}
}
when i run this am getting the following error
Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: Error loading font file: images/arial-15.fnt
at com.badlogic.gdx.graphics.g2d.BitmapFont$BitmapFontData.load(BitmapFont.java:650)
at com.badlogic.gdx.graphics.g2d.BitmapFont$BitmapFontData.<init>(BitmapFont.java:465)
at com.badlogic.gdx.graphics.g2d.BitmapFont.<init>(BitmapFont.java:115)
at com.packtpub.libgdx.canyonbunny.game.Assets$AssetsFonts.<init>(Assets.java:125)
at com.packtpub.libgdx.canyonbunny.game.Assets.init(Assets.java:49)
at com.packtpub.libgdx.canyonbunny.CanyonBunnyMain.create(CanyonBunnyMain.java:22)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:143)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120)
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -7
at java.lang.String.substring(String.java:1918)
at com.badlogic.gdx.graphics.g2d.BitmapFont$BitmapFontData.load(BitmapFont.java:476)
... 7 more
The exception you've got is this one. Practically saying that something went wrong while loading the file. The inner exception shows what went wrong while loading:
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -7
at java.lang.String.substring(String.java:1918)
at com.badlogic.gdx.graphics.g2d.BitmapFont$BitmapFontData.load(BitmapFont.java:476)
Since there's no call to String#substring at line 476, this is an indication that you're using an older version of libgdx (which is to be expected, because a lot has changed to that file recently). So I'd suggest that you update to the latest nightly (or check the github history at the time of the version you're using), so you know which call is actually causing the error.
Either way, the fact that a substring call failed while loading your file is a good indication that the file is likely to be corrupt or doesnt meet the expected format in another way. Assuming you want to use the font that the libgdx tests uses, then you can download the correct version here and the required image here. Make sure to place the image in the same folder as the fnt file.
Your real problem is that it can't find the font file...
Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: Error loading font file: images/arial-15.fnt
Make sure the file is in the correct place, which is probably android/assets/images but depends on your project setup.
Also ensure that your run the desktop version with android/assets as the working folder.
I'm practicing web programming by using Spring 3.1, Hibernate and SiteMesh3.
I want to move 'sitemesh3.xml' file to other directory as WEB-INF/spring/ (not in WEB-INF directly). I've tried it, but sitemesh didn't work. Is it possible to move it? If it is, what properties, if any, should I add on other files like web.xml?
(I've read http://wiki.sitemesh.org/wiki/display/sitemesh3/Configuring+SiteMesh+3, which says "The configuration file should live in /WEB-INF/sitemesh3.xml in your web-application.")
Consider using java config, you can get rid of xml configuration totally.
Follow Sitemesh Java Config
Create a filter like this and register it in your web.xml or in java configuration file.
#WebFilter(urlPatterns = "/*")
public class ConfiguredSiteMeshFilter extends ConfigurableSiteMeshFilter {
#Override
protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
builder.addDecoratorPath("/*", "/WEB-INF/decorators/defaultDecorator.jsp");
}
}
My mapper will write some data to local disks and clean it up when mapper finishes. However, the cleanup() method won't be called if error occurs (exception happens).
I can catch exception inside my mapper but I can't handle the exception which is not invoked in my mapper ( Ex: Job tracker failover to standby node).
Is there any way that I can cleanup when the mapper get fails?
You can override the run method of mapper to include a try / catch around the iteration of input keys from the context and ensure that cleanup is called:
#Override
public void run() {
setup(context);
try {
while (context.nextKeyValue()) {
map(context.getCurrentKey(), context.getCurrentValue(), context);
}
} finally {
cleanup(context);
}
}
You'll need to make sure that your cleanup method doesn't have any logic in it to try and output records, or set a flag in your mapper to denote that an error occurred.
This may not protect against all types of task failure (JVM crash for example), for which i don't think you have any other method, other than to maybe run a job after the original job whose role is to ensure the resources used are properly cleaned up.
Using the job class you can definitely delete some folders if the job finishes, even if the directories are in the local filesystem, use the FileSystem class
More on filesystems in hadoop
In SSIS Script task I am able to load the package by providing the full path as following, but on the server I don't know the exact path after deployment, Is there any way to load the package and its configuration file.
public void Main()
{
Dts.TaskResult = (int)ScriptResults.Success;
Microsoft.SqlServer.Dts.Runtime.Application app = new Microsoft.SqlServer.Dts.Runtime.Application();
Package package = app.LoadPackage(#"C:\tfs01\AURA\DB\Main\Src\ReportSolution\AURA_ETL\AURA_ETL\DTS_PatientModel.dtsx", null);
}
As always, the documentation is your friend.
Instead of calling LoadPackage, you need to use LoadFromSqlServer. LoadPackage pulls from disk, LoadFromSqlServer talks to the msdb.
Note that if you are working with the 2012 project deployment, it's an entirely different mechanism.
How would I go about creating a modern, Gmail-like, multiple file upload in GWT and AppEngine Blobstore?
The solution most commonly proposed is gwtupload, an excellent GWT component written by Manolo Carrasco. However, the latest version 0.6.6 does not work with blobstore (at least I can't get it to work), and it does not support multiple file select. There's a patch for multiple file select in the latest 0.6.7 snapshot, but although it allows selection of multiple files (using the "multiple" attribute in HTML5), it stills sends them in one huge POST request (and progress is shown for the whole bunch of files).
There are also other questions on SO for this (for example here or here), but the answers usually uses the HTML5 "multiple" attribute and sends them as one big POST request. It works, but its not what I am after.
Nick Johnson wrote some great blog posts about this. He uses the common and well-accepted JavaScript upload component called Plupload, and uploads files to an AppEngine-app written in Python. Plupload supports different backends (runtimes) for supporting multiple file selection (HTML5, flash, Silverlight, etc) and handles upload progress and other upload related client-side events.
The problem with his solution is (1) it's in Python, and (2) it's in JavaScript. This is where gwt-plupload enters the picture. It is a JSNI-wrapper for Plupload written by Samuli Järvelä, which enables use of Plupload inside the GWT environment. However, the project is outdated (no commits since 2010), but we can use it for inspiration.
So, step-by-step instructions for building the multiple file upload component follows. This will all be in one project, but it (especially the JSNI-wrapper) could be extracted to its own .jar-file or library to be reused in other projects. The source code is available on Bitbucket here.
The application is available on AppEngine (non-billable, so don't count on it being available or working) at http://gwt-gaemultiupload-example.appspot.com/.
Screenshots
Step 1 - Servlets
Blobstore works in the following way:
Client asks blobstore for a URL it can use for uploading a file.
Client POSTs the file to the received URL.
When the whole POST is received, blobstore will redirect the client to a success URL (specified when creating the upload URL).
To support this, we will need two servlets. One for generating URLs for file uploads (note that each file upload will need an unique URL), and one for receiving finished uploads. Both will be quite simple. Below is the URL generator servlet, which will just write the URL in plain text to the HTTP response.
public class BlobstoreUrlGeneratorServlet extends HttpServlet {
private static BlobstoreService blobstore = BlobstoreServiceFactory.getBlobstoreService();
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setHeader("Content-Type", "text/plain");
resp.getWriter().write(blobstore.createUploadUrl("/uploadfinished"));
}
}
And then, the servlet for receiving successful uploads, which will print the blobkey to System.out:
public class BlobstoreUploadFinishedServlet extends HttpServlet {
private static BlobstoreService blobstore = BlobstoreServiceFactory.getBlobstoreService();
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Map<String, List<BlobKey>> blobs = blobstore.getUploads(req);
List<BlobKey> blobKeyList = blobs.get("file");
if (blobKeyList.size() == 0)
return;
BlobKey blobKey = blobKeyList.get(0);
System.out.println("File with blobkey " + blobKey.getKeyString() + " was saved in blobstore.");
}
}
We also need to register these in web.xml.
<servlet>
<servlet-name>urlGeneratorServlet</servlet-name>
<servlet-class>gaemultiupload.server.BlobstoreUrlGeneratorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>urlGeneratorServlet</servlet-name>
<url-pattern>/generateblobstoreurl</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>uploadFinishedServlet</servlet-name>
<servlet-class>gaemultiupload.server.BlobstoreUploadFinishedServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>uploadFinishedServlet</servlet-name>
<url-pattern>/uploadfinished</url-pattern>
</servlet-mapping>
If we run the app now and visit http://127.0.0.1:8888/generateblobstoreurl, we will see something like
http://<computername>:8888/_ah/upload/ahpnd3QtZ2FlbXVsdGl1cGxvYWQtZXhhbXBsZXIbCxIVX19CbG9iVXBsb2FkU2Vzc2lvbl9fGAEM
If we were to post a file to that URL, it would be saved in blobstore. Note however that the default URL for the local development web server is http://127.0.0.1:8888/ while the URL generated by blobstore is http://<computername>:8888/. This will cause problems later on, as for security reasons Plupload won't be able to POST files to another domain. This only happens with the local development server, the published app will have only one URL. Fix it by editing the Run Configurations in Eclipse, add -bindAddress <computername> to the arguments. This will cause the local development server to host the web app on http://<computername>:8888/ instead. You might need to allow <computername> in the GWT browser plugin for it to load the app after this change.
So far so good, we have the servlets we need.
Step 2 - Plupload
Download Plupload (I used the latest version, 1.5.4), unzip, and copy the js folder to the war directory in our GWT application. For this example, we won't be using jquery.plupload.queue or jquery.ui.plupload as we'll create our own GUI. We also need jQuery, which I downloaded from Google APIs.
Next, we need to include the JavaScripts in our application, so edit index.html and add the following to the <head> tag.
<script type="text/javascript" language="javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" language="javascript" src="js/plupload.full.js"></script>
So now we have Plupload included in our application. Next, we need to wrap it to be able to use it with GWT. This is where gwt-plupload is used. I didn't use the jar file from the project, but instead copied the source files to be able to make modifications to them. The wrapper's main object is the Plupload class, which is constructed by PluploadBuilder. There's also the interface PluploadListener, which can be implemented to receive client-side events.
Step 3 - Putting it together
So now we need to actually use Plupload in our GWT application. I added the following to an Index.ui.xml UIBinder:
<g:Button text="Browse" ui:field="btnBrowse" />
<g:Button text="Start Upload" ui:field="btnStart" /><br />
<br />
<h:CellTable width="600px" ui:field="tblFiles" />
There's a button for browsing files, a button to start uploading and a CellTable which we will use to display upload status. In Index.java, we initialize Plupload as follows:
btnBrowse.getElement().setId("btn-browse");
PluploadBuilder builder = new PluploadBuilder();
builder.runtime("html5");
builder.useQueryString(false);
builder.multipart(true);
builder.browseButton(btnBrowse.getElement().getId());
builder.listener(this);
plupload = builder.create();
plupload.init();
The runtime attribute tells Plupload which backends to use (I have only tested HTML5, but the others should work as well). Blobstore requires multipart to be enabled. We also need to set an ID for the browse button, and then tell Plupload to use that ID. Clicking this button will popup Plupload's file selection dialog. Last, we add ourselves as listener (implementing PluploadListener) and create() and init() Plupload.
To display the files ready to upload, we just need to add data to the tblFilesDataProvider list data provider in the events from UploadListener.
#Override
public void onFilesAdded(Plupload p, List<File> files) {
tblFilesDataProvider.getList().addAll(files);
}
To display progress, we simply update the list whenever we are notified progress have changed:
#Override
public void onFileUploadProgress(Plupload p, File file) {
tblFilesDataProvider.refresh();
}
We also implement a click handler for btnStart, which justs tells Plupload to start uploading.
#UiHandler("btnStart")
void btnStart_Click(ClickEvent event) {
plupload.start();
}
It is now possible to select files, they will be added to the pending uploads list and we can start the upload. The only piece left is to actually use the servlets we implemented earlier. Currently, Plupload does not know which URL to POST uploads to, so we need to tell it. This is where I have made a change to the gwt-plupload source code (apart from minor bug fixes); I added a function to Plupload called fetchNewUploadUrl. What it does is it performs an Ajax GET request at the servlet we definied earlier to fetch an upload URL. It does this synchronously (why will be clear later). When the requests returns, it sets this URL as the POST URL for Plupload.
private native void fetchNewUploadUrl(Plupload pl) /*-{
$wnd.$.ajax({
url: '/generateblobstoreurl',
async: false,
success: function(data) {
pl.settings.url = data;
},
});
}-*/;
public void fetchNewUploadUrl() {
fetchNewUploadUrl(this);
}
Plupload will post each file in its own POST request. This means we need to give it a new URL before each upload starts. Luckily, there's an event for that in PluploadListener which we can implement. And here's the reason why the request has to be synchronous: otherwise the upload would have started before we received the upload URL in the event handler below (pl.fetchNewUploadUrl() would have returned immediately).
#Override
public void onBeforeUpload(Plupload pl, File cast) {
pl.fetchNewUploadUrl();
}
And that's it! You now have GWT HTML5 multiple file upload functionality placing files in AppEngine Blobstore!
Passing parameters
If you want to additional parameters (such as an ID for the entity to which the uploaded files belong), I added an example on how to add one. There's a method on Plupload called setExtraValue() I implemented as:
public native void setExtraValue(String value) /*-{
this.settings.multipart_params = {extravalue: value}
}-*/;
Extra values can be passed as multipart_params. This is a map, so the functionality could be extended to allow many arbitrary key-value pairs. The value can be set in the onBeforeUpload() event handler
#Override
public void onBeforeUpload(Plupload pl, File cast) {
pl.setExtraValue(System.currentTimeMillis() + " is unique.");
pl.fetchNewUploadUrl();
}
and retrieved in the servlet receiving finished uploads as
String value = req.getParameter("extravalue");
The example project contains sample code for this.
Final words
I am no way an expert GWT developer. This is what I came up with after hours of frustration not finding the functionality I was after. After I got it working, I thought I should write up a complete example, as every component/blog post/etc I used/followed had left some part out. I do not imply this to be best practice code in any way. Comments, improvements and suggestions are welcome!