Tag: Java

JSF 2.2: Pass Through – Using custom attributes without headache

JSF taglib is very helpful to build HTML forms and reports. Not all W3C’s attributes are available in standard tags. The h:inputText does not contains the attribute “placeholder”, available only in HTML5.

To make up this “limitation” without overwriting a component or building a new one, JSF 2.2 has the “workaround” called Pass Through Attributes. A new tag to inhibit to remove any custom attributes.

Declare tag using xmlns:p=”http://xmlns.jcp.org/jsf/passthrough”. Now, you can put “p:” in any JSF tag as attribute, like “<h:outputText p:MyAttribute=”MyValue” … />”. This will write “<input type=”text” MyAttribute=”MyValue” … />”.

Go to work:

JSF without Pass Through

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://xmlns.jcp.org/jsf/html">
	<h:head>
	</h:head>
	<h:body>
		<f:view contentType="text/html">
			<h:form>
				<!-- Numeric input text and placeholder attribute -->
				<h:inputText ... placeholder="Age" type="number" />
			</h:form>
		</f:view>
	</h:body>
</html>

There is not “placeholder” attribute

With Pass Through

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:p="http://xmlns.jcp.org/jsf/passthrough">
	<h:head>
	</h:head>
	<h:body>
		<f:view contentType="text/html">
			<h:form>
				<!-- Numeric input text and placeholder attribute -->
				<h:inputText ... p:placeholder="Age" p:type="number" />
			</h:form>
		</f:view>
	</h:body>
</html>
There is "placeholder" attribute

There is “placeholder” attribute


Android – Transfering data between apps and computer over USB cable

There are many Android apps where you can run some tasks without wireless connection (4G, 3G, Wi-fi or Bluetooth), only using USB cable. Below, I’ll describe an easy way to do it.

As usual, you’ll need Android Development Kit, that can be found here.

At client development, we need to change ADB ports, used by socket connections. We can do this by running the following command:

<PLATFORM-TOOLS DIR>/adb forward tcp:59900 tcp:59900

Using Java:

Runtime.getRuntime().exec("<PLATFORM-TOOLS DIR>/adb forward tcp:59900 tcp:59900");

Remember that “<PLATFORM-TOOLS DIR>” is the path to “platform-tools” directory, located in Android SDK installation directory.

We only changed the “ears” of ADB to listen the port 59900, used in our connection.

Lets send a “Hello World!”:

Socket socket = new Socket("127.0.0.1", 59900);
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
bos.write("Hello World!".getBytes());
bos.flush();
bos.close();

Now the Client is ready, lets go to the application.

Add the permissions “android.permission.ACCESS_NETWORK_STATE” and “android.permission.INTERNET” to the AndroidManifest.xml.

Given the appropriate permissions, we do application to listen the requests coming from port 59900, using the class ServerSocket from package java.net:

ServerSocket server = new ServerSocket(59900);
Socket socket = server.accept();

With Socket object, we can get the data using getInputStream():

InputStreamReader reader = new InputStreamReader(socket.getInputStream());
BufferedReader br = new BufferedReader(reader);
msg = br.readLine();
br.close();

We are working with Strings, therefore I used the class BufferedReafer, to get entire line with method readLine();

It’s done! Now we can communicate application and computer using only USB cable.

It’s not allowed using main thread to opening socket, so, you’ll need to open the socket in a separated Thread or to extend the class AsyncTask.

If you still have doubts about this method, I’ll make available the example used in this tutorial here.


Android – Implementing Swipe-to-refresh method

Swipe-to-refresh (or pull-to-refresh) is a way used to refresh information pulling the view down, like GMail and Twitter apps.

swipetoupdate

Bellow, I’ll show how to implement a ListView to use this method.

First, we need to extend the ListView.

The magic happens when onTouchEvent is overridden. See below:

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		//Actual Y position
		float y = event.getY();

		switch(event.getAction()){
		case MotionEvent.ACTION_DOWN:
			//Stores the Y position when screen is touched
			startY = y;
			//Allows refresh if the first visible item is the first in the list
			allowRefresh = (getFirstVisiblePosition() == 0);
			break;

		case MotionEvent.ACTION_MOVE:
			if(allowRefresh){
				if((y - startY) > REFRESH_THRESHOLD){
					refresh = true;
				}
				else{
					refresh = false;
				}
			}

			break;
		case MotionEvent.ACTION_UP:
			//Refresh
			if(refresh){
				Toast.makeText(this.getContext(), "REFRESHING", Toast.LENGTH_SHORT).show();
			}
			refresh = false;
		}

		return super.onTouchEvent(event);

Basically, the method stores Y-axis position when screen is touched (MotionEvent.ACTION_DOWN) and, sliding down (MotionEvent.ACTION_MOVE), this position is compared  with initial Y-axis. If distance between initial position and end position is greater than REFRESH_THRESHOLD constant when MotionEvent.ACTION_UP occurs, the refresh command is triggered.

So far, only message “REFRESHING” will be displayed at refresh.

Implementing an interface can let this code more functional.

Create an interface with method onRefresh.

public void onRefresh();

Also, create a setter in our ListView. That will be your listener.

public void setRefreshListener(SwipeToRefreshListener listener){
	refreshListener = listener;
}

Change case MotionEvent.ACTION_UP to run implemented method.

//Executa a atualização
if(refresh &&
	refreshListener != null){
	//Chama o método que executará a atulização
	refreshListener.onRefresh();
}

In Activity we define the object that will run the update or, like the code below, shows the message “REFRESHING”.

swipeListView.setRefreshListener(new SwipeToRefreshListener() {
	@Override
	public void onRefresh() {
		Toast.makeText(MainActivity.this, "REFRESHING", Toast.LENGTH_SHORT).show();
	}
});

Now you can use this method to do anything you want, like importing data from text file, XML or database.

The complete example can be downloaded here.


Why to use File.separator and File.pathSeparator

Java programmers knows about methods quoted in title, but many doesn’t care with them.

These methods are useful for programmer that do not knows wich characters represents file separator and path separator at OS that supports your application.

Linux/Unix, the methods File.separator and File.pathSeparator returns “/” and “.”, while in Windows, these methods returns “\” (or “\\” – escape) and “;”.

In recent case, the code below threw exception FileNotFoundException running over Linux, but not running over Windows:

String appPath = ctx.getRealPath();
String filePath = appPath + "\\" + "WEB-INF/classes/my/application/packages/";

File file = new File(filePath, "report.pdf");
OutputStream out = new FileOutputStream(file);
...

Worked in both systems after to replace “\\” by File.separator in line 2:

String appPath = ctx.getRealPath();
String filePath = appPath + File.separator + "WEB-INF/classes/my/application/packages/";

File file = new File(filePath, "report.pdf");
OutputStream out = new FileOutputStream(file);
...

Utilization of these methods, besides a good practice, is very usefull when same version of an application is running over differents operacional systems.


How to read and write CLOB fields

The Character Large Object (or CLOB) is a commonly found in databases and used to store high quantity of characters.

At MySQL, for example, this field is called MEMO.

Writing CLOB field

The method setAsciiStream of PreparedStatement allow to pass data to a CLOB.

ps.setAsciiStream(bindPosition, inputStream, textLength);

bindPosition – Position in PreparedStatment’s CLOB field.
inputStream – Used to pass data.
textLength – Data (text) length.

Full code:

String sql = "INSERT INTO TABLE (text) VALUES(?)";
		try{
			String txt = readTxtFile();
			ByteArrayInputStream bais = new ByteArrayInputStream(txt.getBytes());

			PreparedStatement ps = conexao.prepareStatement(sql);
			//CLOB is '?' at first position
			ps.setAsciiStream(1, bais, txt.length());

			ps.execute();

			ps.close();
		}catch (Exception e) {
			e.printStackTrace();
		}

Retrieving CLOB data

We’re using SELECT clause, this clause returns a ResultSet to fetch data and, calling getClob method, passing column name or your position in the query, it give to you a Clob object.

rs.getClob("xml");

Full code:

String sql = "SELECT xml FROM TEST";
		try{
			PreparedStatement ps = conexao.prepareStatement(sql);
			ResultSet rs = ps.executeQuery();

			while(rs.next()){
				Clob clob = rs.getClob("xml");
				BufferedReader reader = new BufferedReader(clob.getCharacterStream());
				StringBuffer strBuf = new StringBuffer();

				String linha = null;
				while((linha = reader.readLine()) != null){
					strBuf.append(linha);
//Character.LINE_SEPARATOR insert break line
					strBuf.append((char)Character.LINE_SEPARATOR);
				}

				System.out.println("=========== CLOB ===========");
				System.out.println(strBuf.toString());
			}

			rs.close();
			ps.close();
		}catch (Exception e) {
			e.printStackTrace();
		}

That’s it! Easy and painless 😉

Download full code here

To write a BLOB see this tutorial.


  • Advertisement

  • Advertisement

  • Copyright © 1996-2010 André L. S.. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress