Thursday, June 5, 2014

Java & Batik: How to transform arbitrary SVG elements!

Batik is a powerful library for handling SVG documents. I recently wrote an answer on StackOverflow.com on how to display SVG document in a JavaFX ImageView component. Apart from that, I also needed a means to transform (i.e. rotate, scale, translate) an arbitrary SVG element.

Translating a rectangle is fairly easy: Get its x and y attributes using getAttribute(null, localName), modify them and reassign them back using setAttributeNS(null, qualifiedName, value).
The tricky bit comes into play if you also want to rotate or scale the rectangle. The solution is to use SVG's transform attribute, which combines translating, scaling, rotating and skewing effects in a transformation matrix. This option also allows one to modify arbitrary SVG elements (incl. groups)!

I've come up with two usable utility classes, which you can freely use.

I would like to sincerely thank:

tl;dr: Code!

Full source code at: GitHub Gist: Transformation of arbitrary SVG elements with Batik

Usage Example


AffineTransformUtils.java


SVGUtils.java

Monday, March 25, 2013

[Solution] java.net.ConnectException when using JUnit and KIS 2013

The problem is a blocking firewall in most cases.

But if you have Kaspersky Internet Security 2013 (KIS 2013) installed and though Java is already set as a trusted program, JUnit won't work!
There's a post from cicmildjordje which describes the workaround:
Open kasperky settings/application control and click on "Applications" and find folder "Oracle America". Right click on every file in that folder (one by one), choose "Application rules", click on "Exclusions" and check "Do not scan network traffic". 

SORRY FOR MY BAD ENGLISH
Here's a more detailed step-by-step solution:


  1. Open KIS control panel
  2. Click on "Settings" in the top right corner
  3. Select "Program control" in the left panel and click on the "Programs" button on the right.
  4. Then select "All programs" in the combobox and search for "java". Expand the "Trustful [Programs]/ORACLE" group:

  5. Then right-click for each Java entry and choose "Application rules". If the path which you'll see in the appearing dialog, isn't c:\program files (x86)\java\jre7\bin\java.exe or c:\program files\java\jre7\bin\java.exe, skip to the next entry.
  6. For each "valid" Java entry, go to Exclusions and choose "Do not scan network traffic".

Saturday, September 29, 2012

Windows 8 App Deployment error 0x80073cf6

Today, I have experienced this deployment issue when trying to build and run my Windows 8 app:
[...] 0x80073cf6 See here for more information: http://msdn.microsoft.com/en-us/library/hh973484.aspx
If you search the specifc error ID on the page, you'll see this reason:
The package can't be registered. Check the AppXDeployment-Server event log for more info.
There were indeed error messages in the event viewer. But I still hadn't found the solution.

I found out the solution by accident:
  1. Open the task manager
  2. Kill "explorer.exe" in the Details tab
  3. Restart "explorer.exe" via File->Run new task

Wednesday, August 1, 2012

How to delete Outlook aliases

The new Outlook is out there and will replace Hotmail. But what if you created an alias by accident (I actually didn't know that I cannot change the display name)?

AFAIK, the option is not directly available from the account options, but from this URI:

https://account.live.com/ManageAssocIds

Thursday, June 28, 2012

[Solution] Errors when updating ADT for Android Jelly Beanu under Windows

A very simple solution: just start Eclipse with administrator privileges!

Actionbars and tabs under Android 2.x+ with ActionBarSherlock

Introduction

ActionBarSherlock (ABS) is an extension of the Android Support Library which even more simplifies the life with ActionBars and their compatibilty until Android 2.x.

Here I'll show you a short Hello World introduction to ABS. Please note that I won't go in detail about all functions, I just want to give a starting point for using ABS.

The Android Developers documentation is a very good site to learn more about ActionBars, tabs, fragments and navigation!

Creating the ABS project

  1. Download and unpack the latest version of ABS from here:  abs.io/download.html
  2. Create a new Android project:
    -  choose the library folder as the project's source
    -  the build target should be at least API level 13 (Android 3.2)
Compile the project if you haven't turned on Automatic building.

If you get tons of errors, it's probably because of the default Java compliance level. Change it in the project options under Java Compiler to at least 1.6.

Hello World, ABS!

  1. Create new project with a build target set to API level 13 or higher. Set the main activity name to MainActivity, so you can just copy and paste (but also understand better) this code.
  2. Go to the Android options under your project's options. Add ABS as a library via the Add button.

Now, we're ready for the code...

MainActivity.java
package de.tutorials.comfreek.actionbar;
 
import android.os.Bundle;
 
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.SherlockFragmentActivity;
 
public class MainActivity extends SherlockFragmentActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        ActionBar actionbar = getSupportActionBar();
        actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
 
        Tab tab1 = actionbar.newTab().setText("Greeting 1");
        Tab tab2 = actionbar.newTab().setText("Greeting 2");
 
        tab1.setTabListener(new MyTabListener(this, "tab1",
                AFragment.class));
 
        tab2.setTabListener(new MyTabListener(this, "tab2",
                BFragment.class));
 
        actionbar.addTab(tab1);
        actionbar.addTab(tab2);
    }
}
The code should be mostly self-explanatory. The TabListener will receive three events from our ActionBar:

  • onTabSelected
  • onTabUnSelected
  • onTabReselected
It has to handle how the fragments (=tab content) are exchanged and created. A fragment is a part of a UI. You can also have multiple fragments in a activity so they are displayed dependent of the device's screen size. (But at the moment a fragment cannot hold another fragment, so you can only display one fragment in tab and you have to manage the exchange yourself).

main.xml

  
 
 

The inner LinearLayout will act as the fragment container for the tab content.
In addition, we have to set either the app's theme or the MainActivity's theme to @style/Theme.Sherlock.
You can either use the ADT Manifest editor for it or you can directly edit the XML:

    



    

AFragment and its layout file for the first tab content:
package de.tutorials.comfreek.actionbar;
 
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
 
import com.actionbarsherlock.app.SherlockFragment;
 
public class AFragment extends SherlockFragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.hello, container, false);
    }
}

 
    
 

The code of BFragment is identical except the displayed text. Now TabListener.java which handles all tab events and their fragment exchanges:
package de.tutorials.comfreek.actionbar;
 
import android.app.Activity;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
 
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.ActionBar.TabListener;
 
public class MyTabListener implements TabListener {
    private Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class mClass;
 
    /** Constructor used each time a new tab is created. */
    public MyTabListener(Activity activity, String tag, Class clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }
 
    /* The following are each of the ActionBar.TabListener callbacks */
 
    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ignoredFt) {
        FragmentManager fragMgr = ((FragmentActivity) mActivity)
                .getSupportFragmentManager();
        FragmentTransaction ft = fragMgr.beginTransaction();
 
        // Check if the fragment is already initialized
        if (mFragment == null) {
            // If not, instantiate and add it to the activity
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
 
            ft.add(android.R.id.content, mFragment, mTag);
        } else {
            // If it exists, simply attach it in order to show it
            ft.attach(mFragment);
        }
 
        ft.commit();
    }
 
    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ignoredFt) {
        FragmentManager fragMgr = ((FragmentActivity) mActivity)
                .getSupportFragmentManager();
        FragmentTransaction ft = fragMgr.beginTransaction();
 
        // Check if the fragment is already initialized
        if (mFragment == null) {
            // If not, instantiate and add it to the activity
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
 
            ft.add(android.R.id.content, mFragment, mTag);
        } else {
            // If it exists, simply attach it in order to show it
            ft.detach(mFragment);
        }
 
        ft.commit();
    }
 
    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
        // User selected the already selected tab. Usually do nothing.
    }
}
You're finished! Just start the app on your Android device or in the simulator:



Wednesday, June 6, 2012

Logging full objects via console.log in VS 2012

If you call console.log() with an object, Visual Studio 2012 RC will output [Object], nothing more!
But I'm used to seeing its properties and its values, too, like in the Google Chrome Developer Console.

So I wrote my own function:
/**
 * Returns a human readable presentation of an object, its properties and its values.
 * @param obj The object
 * @param attr You can use this parameter in order to specify a prefix for each property
 * @return Returns a string
 *
 * @author ComFreek
 * @license Public Domain
 */
function logObject(obj, attr) {
    var str = "";
    attr = attr || "";
    for (var attrname in obj) {
        if (typeof obj[attrname] == "object") {
            str += "\n" + logObject(obj[attrname], attr + "." + attrname) + "\n";
        }
        else {
            str += attr + "." + attrname + "=" + obj[attrname] + "\n";
        }
    }
    return str;
}
Some sample inputs and outputs:
var obj = {
    "foo": "bar",
    "bar": "foo",

    "fooObj": {
        "barProp": "fooVal",
        "fooProp": "barVal",

        "barUnderObj": {
            "test": "test"
        }
    }
};
console.log(logObject(obj));
This outputs:
.foo=bar
.bar=foo

.fooObj.barProp=fooVal
.fooObj.fooProp=barVal

.fooObj.barUnderObj.test=test
The same code but with second argument given:
console.log( logObject(obj, "fooObj") );
Output:
fooObj.foo=bar
fooObj.bar=foo

fooObj.fooObj.barProp=fooVal
fooObj.fooObj.fooProp=barVal

fooObj.fooObj.barUnderObj.test=test