Sunday, September 29, 2013

Create zip file

In the previous post, you learned to create a simple program to extract an existing zip file. Sometimes, you might want to implement file zipping in your programs. So it is worth to learn how to write Java code to create a zip file or many zip files.

In contrasting to zip file extraction, you need to use the ZipOutputStream class to write the contents of the source files or directories to the output file. The ZipEntry class is used to create a zip entry object. This object can be file or directory. The putEntry method of the ZipOutputStream class is used to add the zip entry to the output zip file. Its write method is used to write the content of a source file object to the output zip file.

The below example program allows the user to add many files or directories to the JList component. When the OK button is clicked, all paths of the source files or directories are processed to create zip files. The output zip files are placed in your current working project folder.
The zipFile method is the main path of the program. The sources to be zipped can be file or directory so that they are processed separately. We create additioal two methods, compressFile and compressDir. If the source is a file object, the compressFile method is invoked to compress the file. Otherwise, the compressDir is invoked to compress the contents of the directory. The contents of the directory can be files or directories so the compressFile and compressDir methods are invoked recursively until all files and directories are written to the output zip file.



import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

class ZipUI extends JFrame implements ActionListener{
DefaultListModel<String> listModel;
JList<String> listPaths;
JTextField textPath;
JLabel lblwait;

ZipUI(String title){
Container cont=getContentPane();
cont.setLayout(new BorderLayout());
setTitle(title);
setPreferredSize(new Dimension(600,300));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lbl=new JLabel("Path:");
textPath=new JTextField(30);
JButton btadd=new JButton("Add");
btadd.addActionListener(this);
JButton btremove=new JButton("Remove");
btremove.addActionListener(this);
JPanel panelnorth=new JPanel();
panelnorth.add(lbl);
panelnorth.add(textPath);
panelnorth.add(btadd);
panelnorth.add(btremove);
listModel=new DefaultListModel<String>();
listPaths=new JList<String>(listModel);
listPaths.setVisibleRowCount(10);
listPaths.setFixedCellWidth(200);
JScrollPane pane=new JScrollPane(listPaths);
JButton btok=new JButton("OK");
lblwait=new JLabel();
JPanel panelsouth=new JPanel();
panelsouth.add(btok);
panelsouth.add(lblwait);
btok.addActionListener(this);
cont.add(panelnorth, BorderLayout.NORTH);
cont.add(pane, BorderLayout.CENTER);
cont.add(panelsouth, BorderLayout.SOUTH);
pack();
setVisible(true);
}

public void actionPerformed(ActionEvent e){
if(e.getActionCommand().equals("Add")){
if(!textPath.getText().equals("")){
listModel.addElement(textPath.getText());
textPath.setText("");
}
else
JOptionPane.showMessageDialog(null, "Please enter the file or directory path", "Add path",JOptionPane.INFORMATION_MESSAGE);


}
else if(e.getActionCommand().equals("Remove")){
if(listModel.getSize()>0){
int selIndex=listPaths.getSelectedIndex();
if(selIndex>=0)
listModel.removeElementAt(selIndex);
else
JOptionPane.showMessageDialog(null, "No selected item", "Delete error",JOptionPane.ERROR_MESSAGE);
}
else
JOptionPane.showMessageDialog(null, "No item in the list", "Delete error",JOptionPane.ERROR_MESSAGE);
}
else if(e.getActionCommand().equals("OK")){
if(listModel.getSize()>0){
Thread t=new Thread(){
public void run(){
lblwait.setText("Please wait...");

for(int i=0;i<listModel.size();i++){
zipFile(listModel.get(i));
}
//dispose();
lblwait.setText("Complete! check the file(s) in /zip");
}
};
t.start();
}
else
JOptionPane.showMessageDialog(null, "No such file or directory", "Error",JOptionPane.ERROR_MESSAGE);
}
}

//zip file or directory
public void zipFile(String src){
File f=new File(src);
File foutdir=new File(System.getProperty("user.dir")+"/zip");
if(!foutdir.exists()) foutdir.mkdir();
ZipOutputStream zos=null;
try{
zos=new ZipOutputStream(new FileOutputStream(foutdir.getPath()+"/zip"+System.currentTimeMillis()+".zip"));
if(f.exists()){
String fname=getName(f.getPath());
if(f.isFile()){
compressFile(f.getPath(),fname,zos);
}
else{ //source is a directory
File[] files=f.listFiles();
for(File sf:files){
compressDir(sf.getPath(),fname,zos);
}
}


}
else{
System.out.println("Soure not found!");
}
zos.close();

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

}
//get the name of source file or directory
public String getName(String srcpath){

String name="";
if(srcpath.endsWith(File.separator)){
name=srcpath.substring(0,srcpath.length()-1);
name=name.substring(name.lastIndexOf(File.separator)+1);
}
else
name=srcpath.substring(srcpath.lastIndexOf(File.separator)+1);

return name;
}
//zip the directory and its contents
public void compressDir(String srcpath, String dirname, ZipOutputStream zos){
File fsrcdir=new File(srcpath);
String curDirName=getName(srcpath);
if(fsrcdir.isDirectory()){
try {
//add the blank folder to the zip file
//its previous path is maintained
curDirName=dirname+File.separator+curDirName;
zos.putNextEntry(new ZipEntry(curDirName+File.separator));
zos.closeEntry();
//read the contents of the directory and place them in the zip file
File[] files=fsrcdir.listFiles();
for(File f:files){
if(f.isDirectory()){ //process one directory download
compressDir(f.getPath(),curDirName,zos);
}
else{//process the file
compressFile(f.getPath(),curDirName,zos);
}
}

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else{
compressFile(srcpath,dirname,zos);
}
}
//zip the file
public void compressFile(String srcfile, String dirname,ZipOutputStream zos){

String rpath=getName(srcfile);
//The rpath is a directory name that the file will be stored in
//It is the immediate parent directory of the file
try {
//placing one file entry
zos.putNextEntry(new ZipEntry(dirname+File.separator+rpath));
//create FileInputStream object to read content of the file
FileInputStream fis=new FileInputStream(srcfile);
int content=0;
while((content=fis.read())!=-1){
zos.write(content);
}
zos.closeEntry(); //closing one file entry
fis.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}


public class CreateZipFile {
public static void main(String[] args){
new ZipUI("Zipper");
}


}


add file and directories to the zip file program


Tuesday, September 17, 2013

Extract zip

Sometimes, you might want to create a simple program in Java to extract zip files. If this is your case, this post can help you.  Java provides ZipFile class that can be used to read all entries in the zip file.  The ZipFile class allows you to create a zip file object by passing the path of the zip file to its constructor.  When you have the zip file object you are able to query all entries of the zip file. Each entry of the zip file is represented by a ZipEntry object. To query all entries of the zip file, you can use the entries method of the zip file object. The entries method returns an enumeration that contains all the entries.
Before extracting the content of an entry, we need to check whether the entry is a directory or file. This can be done by using the isDirectory method of the the entry object. If it is a file, then its content can read. To read the content of the file entry, you need to use the getInputStream method of the zip file object. This method return an InputStream object that has the read method to read the content of the file entry.
So far, i have talked about getting the content of the file entry. What are about directories in the zip file? Do we ignore them? The ZipFile treats a directory as one entry and also every file in the directory as one entry. When you get a file entry, its parent directory comes with it. And then you can create the parent directory that does not exist for storing the files. See the example code below.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

public class ZipExtractor {
public static void main(String[] ars){
selectZip();
}

//allow zip file selection
public static void selectZip(){

JFileChooser chooser = new JFileChooser();
    FileNameExtensionFilter filter = new FileNameExtensionFilter("ZIP","zip");
    chooser.setFileFilter(filter);
    chooser.setMultiSelectionEnabled(false);
    int returnVal = chooser.showOpenDialog(null);
    if(returnVal == JFileChooser.APPROVE_OPTION) {
    File file=chooser.getSelectedFile();
    String path=file.toString();
    unZip(path,file.getParent());
           
            }

     
}

public static void unZip(String zippath,String storeDir){
try {
ZipFile zf=new ZipFile(zippath); //create  a zip file object
if(zf.size()>0){ //read through the zip file
Enumeration<ZipEntry> entries=(Enumeration<ZipEntry>) zf.entries();
while(entries.hasMoreElements()){
ZipEntry entry=entries.nextElement();
if(!entry.isDirectory() && !entry.getName().endsWith(File.separator)){
//start extracting the files
extractFiles(zf.getInputStream(entry),entry.getName(),storeDir);

}


}

}
zf.close();
} catch (IOException e) {

e.printStackTrace();
}
}

public static void extractFiles(InputStream is, String fname, String storeDir){

FileOutputStream fos;
File fi=new File(storeDir+File.separator+fname); //output file
File fparent=new File(fi.getParent()+File.separator);
if(!fparent.exists()) fparent.mkdirs();//create parent directories for output files

try {

fos=new FileOutputStream(fi);
int content=0;
while((content=is.read())!=-1){
fos.write(content);
}
is.close();
fos.close();
} catch (Exception e) {

e.printStackTrace();
}

}
}

Thursday, September 12, 2013

TreeMap

TreeMap is a data structure that most its operations (e.g. containsKey, get,put, remove) cost log(n) time. Like HashMap, TreeMap can be used to store pairs of keys and values. However, the TreeMap uses Binary Search Tree technique in its internal structure. You can sort entries in the TreeMap (key-based sorting).  The following code fragment creates a TreeMap object with default native sorting.

import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;

public class TreeMapDemo {
TreeMap<String,String> tmap;
TreeMapDemo(){
tmap=new TreeMap<String, String>(); //create TreeMap object with default sort order

}

public static void main(String[] args){
TreeMapDemo hmd=new TreeMapDemo();

}


}
You can add a new entry that contains key and value by using the put<Object key,Object value) method. The following code adds some entries to the TreeMap, tmap.
public void addEntries(){

tmap.put("85516500379","Sunrise Child Care & Development Center");
tmap.put("85523880502","Krousar Thmey - Temporary Street Children");
tmap.put("855545483","Ming Hour Home Service");
tmap.put("85515907797","Happy Kid Care");


}

The get(Object key) method can be used to return a value for a specified key input. The following code fragment accepts the key input. Then its checks whether the key contains in the TreeMap, tmap. If true, the value of an entry that contains the specified key will be returned.

public String searchMap(String key){
if(tmap.containsKey(key)) return tmap.get(key);
else return null;
}

To traverse through the TreeMap, you can use its keySet method. The keySet method returns a set object that contains all keys in the TreeMap. The set object has the iterator method that can be used to read every key in the set object. The following code below displays all keys and their values in the TreeMap, tmap.

public void showTreeMapContent(){
Set<String> keys=tmap.keySet();
Iterator<String> i=keys.iterator();
while(i.hasNext()){
String key=i.next();
System.out.println(key+"\t"+tmap.get(key));

}

}

For the native sorting, the smaller key comes first, then the next is the larger key. You can change this order by using the Comparator interface. You need to create a class that implements this interface and override the compare(Object obj1, Object obj2) method. Then create an instance of the class and supply it to the constructor of the TreeMap. The program below can be compiled and run to see the result. First, you can give -1 value to the Sorter and compile and run the program. Again give 1 value to the Sorter and compile and run the program. You will notice that different sort orders are made to the entries of the TreeMap.

import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;

public class TreeMapDemo {
TreeMap<String,String> tmap;
TreeMapDemo(){
tmap=new TreeMap<String, String>(new Sorter(-1));
}

class Sorter implements Comparator<Object>{
int order=-1;
Sorter(int order){
this.order=order;
}

public int compare(Object ob1,Object ob2){
if(ob1.toString().compareTo(ob2.toString())==0) return 0;
else if(ob1.toString().compareTo(ob2.toString())<0)
return order;
else
return(-1*order);
}

}

public void addEntries(){
tmap.put("85516500379","Sunrise Child Care & Development Center");
tmap.put("85523880502","Krousar Thmey - Temporary Street Children");
tmap.put("855545483","Ming Hour Home Service");
tmap.put("85515907797","Happy Kid Care");


}

public String searchMap(String key){
if(tmap.containsKey(key)) return tmap.get(key);
else return null;
}
public void showTreeMapContent(){
Set<String> keys=tmap.keySet();
Iterator<String> i=keys.iterator();
while(i.hasNext()){
String key=i.next();
System.out.println(key+"\t"+tmap.get(key));

}

}

public static void main(String[] args){
TreeMapDemo tmd=new TreeMapDemo();
tmd.addEntries();
tmd.showTreeMapContent();

}


}

Wednesday, September 11, 2013

HashMap

HashMap is a data structure that can store pairs of keys and values. The internal structure of the HashMap is constructed based on the hashing organization technique in which its items are grouped in buckets. When creating a hash map object, you are allowed to specify the number of buckets or capacity and the load factor. The good value of the load factor is 0.75 so that the cost of lookup processes can be minimized. The lookup processes here refer to the operations to read an entry from the hash map object or to put a new entry to the hash map object.  The initial capacity should be greater than the result of the number of entries divided the load factor. This can ensure that the structure of the map is not reorganized so that the efficiency can be maintained. For example, if you plan to store 100 entries in the hash map object, its initial capacity should be greater than 133.  The code fragment below creates a hash map object with 134 of capacity and 0.75 of load factor.

import java.util.HashMap;
import java.util.Set;

public class HashMapDemo {
HashMap<String,Integer> hmap;
HashMapDemo(){
//create a hash map object with its number of buckets or capacity 134
//and loader factor 0.75
hmap=new HashMap<String, Integer>(134,(float) 0.75);
}

public static void main(String[] args){
HashMapDemo hmd=new HashMapDemo();
}

}
The HashMap has two important methods-put(Object Key, Object Value) and get(Object Key). The put method is an operation to add a new entry to the hash map object. The code fragment below adds somes country codes and country names to the hash map object.

public void initCodesCountries(){
hmap.put("Australia",61);
hmap.put("Austria",43);
hmap.put("Bhutan",975);
hmap.put("Cambodia",855);
hmap.put("Canada",1);
hmap.put("China",86);
hmap.put("Denmark",45);
hmap.put("Japan",81);
hmap.put("United Kingdom",44);
hmap.put("United States",1);

}

The get method returns the value of an entry in the hash map object for the specified key. In the code fragment below, the containKey(Object key) method is used to check whether the specified key contains in the hash map object. If this operation returns true, the searchMap method returns the value for the specified key. Otherwise, it returns -1.

public int searchMap(String key){
if(hmap.containsKey(key)) return hmap.get(key); //returns the value for the specified key input
else return -1;
}

To get all keys in the hash map object, you can use its keySet() method. The keySet method returns a set object that contains all keys stored in the hash map object. When you have the set of keys, you can read all values in the hash map as well. See the example code fragment below.

public void listCodesCountries(){
Set<String> countries=hmap.keySet(); //read all keys in the hash map
Object[] keyCs=countries.toArray(); //convert the set object to array of Objects
for(Object k:keyCs){  //display country codes and names
System.out.println(k+"\t"+hmap.get(k.toString()));
}
}

Sunday, September 8, 2013

NumberFormat

NumberFormat is an abstract class that is useful to format a number. You can not create number format object directly from this class. Instead, you will use the getNumberInstance(), getCurrencyInstance(), and getPercentInstance() methods to format a general number, currency value, and percentage value respectively.
For example, the below code fragment formats a double number in the default locale.

NumberFormat nf=NumberFormat.getNumberInstance();
double num=987999.988;
String result=nf.format(num);
System.out.println(result);

The result from this code fragement is 987,999.988. When you format a number using the getNumberInstance() method, the thousand separator is taken in to account.

The another code fragment format a currency value in the default locale.

NumberFormat nf=NumberFormat.getCurrencyInstance();
double cur=987999.988;
String mycur=nf.format(cur);
System.out.println(mycur);

The result from this code fragment is $987,999.99. The thousand separator and currency symbol are included in the string representing the currency value. The number of digits after the decimal point (.) is two. If you want specify the number of digits after the decimal point, use DecimalFormat instead. For example, to format a number 12345.9123 to include the thousand separator and with two digits after the decimal point, you write the code below.

NumberFormat nf=NumberFormat.getInstance();
DecimalFormat df=(DecimalFormat)nf;
df.applyPattern("#,###.00");
double num=23024.9000;
String mynum=df.format(num);
System.out.println(mynum);

 To instruct the decimal formatter object to format a value according to your requirments, you will use the applyPattern(String pattern) method. The # symbol represents a digit. It treats zero digits as absent. The , symbol is a thousand separator. The 0 also represents a digit. However, it deos not treat zero digits as absent.

In the examples above, the format object is created to format numbers in the default locale. You can specify the locale for the format object by using getNumberInstance(Locale locale), getCurrencyIntance(Locale locale), and getPercentInstance(Locale locale) methods so that you can have a format object that can format number, currency, or percentage specific to your locale.
For example, the code fragment below formats a currency in French locale.

NumberFormat nf=NumberFormat.getCurrencyInstance(Locale.FRANCE);
double num=7444.9883;
String frCur=nf.format(num);
System.out.println(frCur);

The result from this code is 7 444,99 €. The , symbol is the decimal point and space is used as the thousand separator.

Besides formatting a number, the NumberFormat class can be used to convert or parse a string representing a number to a number.
The example code fragment below converts the string "123.9" to a number.

NumberFormat nf=NumberFormat.getNumberInstance();
try{
String numstr="123.9";
Number mynum=nf.parse(numstr);
double n=mynum.doubleValue();
System.out.println(n);
}catch(ParseException e){e.printStackTrace();
}

You must place the code that converts a string to number in try...catch block since a string might not represent a number so that the conversion fails and your progrm crashes. If you want to get the interger number instead of a double one, you can use intValue() instead of doubleValue() method.

Saturday, September 7, 2013

DateFormat

DateFormat is a useful class in Java to format, date, time, or both.  In general, when formatting a date, time, or both, you don't need to create the date formatter object directly from the DateFormat class. Instead, the date, time, and both formatter objects can be obtained by calling the getDateInstance(int style), getTimeInstance(int style), and getDateTimeInstance(int style) methods respectivly.

For example, the code fragment below format the current date and time as a short date.
DateFormat df=DateFormat.getDateInstance(DateFormat.SHORT);
Date d=new Date();
String date=df.format(d);
System.out.println(date);

The code fragment below formats the current time as a long time.
DateFormat df=DateFormat.getTimeInstance(DateFormat.LONG);
Date d=new Date();
String time=df.format(d);
System.out.println(time);

The two code fragments above format current date and time in the default locale. A locale represents a geographical, political, and cultural region. You can format date, time, and both for a specific locale by calling the getDateInstance(int style, Locale lo), getTimeInstance(int style,Locale lo), and getDateTimeInstance(int style, Locale lo) methods respectively. The code below format the current date as a short local UK date.

DateFormat df=DateFormat.getDateInstance(DateFormat.SHORT,Locale.UK);
Date d=new Date();
String ukdate=df.format(d);
System.out.println(ukdate);

The table below shows the countries and their locale constants that can be used in formatting date value for specific countries.

CountryLocale Constant
CanadaLocale.CANDA
ChinaLocale.CHINA
GermanyLocale.GERMANY
ItalyLocale.ITLAY
JapanLocale.JAPAN
KoreaLocale.KOREA
TaiwanLocale.TAIWAN
United KingdomLocale.UK
United StatesLocale.US


Besides formatting date, time, or both you can use the DateFormat to convert or parse a string presenting date, time, and both to date, time, and both objects that can be used later in Java programs. The code below converts the string "08/09/2013" to date object.

DateFormat df=DateFormat.getDateInstance(DateFormat.SHORT);
String sdate="08/09/2013";
try {
Date mydate=df.parse(sdate);
System.out.println(mydate);
} catch (ParseException e) {
e.printStackTrace();
}

If you want to format a date to match your own pattern, you can use the SimpleDateFormat class. It is a sub-class of the DateFormat class. By using the SimpleDateFormat class you can construct a date formatter object to match your pattern. For example, you can format the current date to display as a form of dd-MM-yyyy. The code below is an example.

DateFormat df=new SimpleDateFormat("dd-MM-yyyy");
String mydate=df.format(new Date());
System.out.println(mydate);

Thursday, September 5, 2013

Drag and Drop

Sometimes, you may want to enable the drag and drop in your programs so they are more friendly. In this post, you are going to learn drag and drop task in Java. It is interesting when the user can select some files from other applications and place them in your applications.

In Java, the drag and drop can be performed by using the DropTarget (Component c, DropTargetListener dl). This tool attaches a component to a drop listener to handle the drop processing. The dragged and dropped data are stored in DataFlavor objects. You can get an array of DataFlavor  objects by using the getTransferDataFlavors() of the Tranferable object.  The DropTartgetDropEvent or DropTartgetDragEvent class can give you the Transferable object. To take the data in the DataFlavor object, you will use the getTransferData(DataFlavor) method of the Transferable object. The data can be text, image, or a list of files.

In the example below, the program allows the user to drag some image files  from the drive D to display in the JFrame window. The images are resized to 100X100 dimension before they are shown.

drag and drop java program


import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

class JLabelShow extends JFrame{
Container contpane;
JLabelShow(String title){
setTitle(title);
setSize(600,300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contpane=getContentPane();
contpane.setLayout(new FlowLayout(FlowLayout.LEFT));
new DropTarget(contpane, new DropList());
setVisible(true);

}


class DropList implements DropTargetListener{

public void drop(DropTargetDropEvent e){
e.acceptDrop(DnDConstants.ACTION_COPY);
Transferable transfer=e.getTransferable();
DataFlavor[] df=transfer.getTransferDataFlavors();
for(int i=0;i<df.length;i++){
try{
Object x=transfer.getTransferData(df[i]);
if(x instanceof List){
List lst=(List)x;
int size=lst.size();
for(int count=0;count<size;count++){
File f=(File)lst.get(count);
String fName=f.getName();
if(fName.endsWith("png") || fName.endsWith("jpg") || fName.endsWith("gif") )
{


         BufferedImage img=resizedImage(f);
JLabel lbl=new JLabel(new ImageIcon(img));                          
        contpane.add(lbl);
validate();

}
}

}


}catch(Exception ep){ep.printStackTrace();}


}

e.dropComplete(true);

}
public void dropActionChanged(DropTargetDragEvent e){

}
public void dragOver(DropTargetDragEvent e){

}
public void dragExit(DropTargetEvent e){

}
public void dragEnter(DropTargetDragEvent e){

}
}

public BufferedImage resizedImage(File f){
BufferedImage bi=new BufferedImage

(100,100,BufferedImage.TYPE_INT_ARGB);

try{
BufferedImage or=ImageIO.read(f);
Graphics2D g2d=bi.createGraphics();
g2d.drawImage(or,0,0,100,100,null);
}catch(IOException e){e.printStackTrace();}
return bi;
}

}


public class DragAndDrop {
public static void main(String[] args){
new JLabelShow("Drag and Drop");
}
}

Tuesday, September 3, 2013

Toolkit

Toolkit is a class in awt package. It is useful when you wan to read image file to display in a component, get screen dimension, get screen resolution, or get data that is stored in a clipboard object.

Reading image file
To get an image in your local disk to display on a component, you can use the getImage(String path) method of the Toolkit class. The code fragment reads the image file called image02.png in drive D and displays it in the JLabel object.

contpane=getContentPane();
Image img=Toolkit.getDefaultToolkit().getImage("d:/image02.png");
JLabel lbl=new JLabel();
lbl.setIcon(new ImageIcon(img));

Getting the screen dimension
Sometimes, you might want to know the width and the height of the screen so that you can find the center point of the screen to place text, a component, or image. The code fragment below displays a JFrame window at the center of the screen.

class Show extends JFrame{
Show(String title){
setTitle(title);
setSize(400,300);
Dimension ds=Toolkit.getDefaultToolkit().getScreenSize();
int x=(int)ds.getWidth()/2-this.getWidth()/2;
int y=(int)ds.getHeight()/2-this.getHeight()/2;
setLocation(x,y);
setVisible(true);
}
}

Getting the screen resolution
To get the screen resolution in dots-per-inch, you need to use the getScreenSolution method of the Toolkit class. The code fragment below read the screen resolution in dots-per-inch.

int resolution=Toolkit.getDefaultToolkit().getScreenResolution();
System.out.println("Screen resolution:"+resolution);

Getting data stored in a clipboard object
When text, image, or even a list of files are copied outside  of your Java applications, those data are stored in a system clipboard object and can be read in to your Java applications. The below code fragment gets the data stored in the system clipboard object and output them to the console window.

class JLabelShow extends JFrame{
JLabelShow(String title){
setTitle(title);
setSize(400,300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contpane=getContentPane();
contpane.add(new JLabel("Copy something and click the mouse

here"),BorderLayout.CENTER);

addMouseListener(new MouseList());
setVisible(true);

}

class MouseList extends MouseAdapter{
public void mousePressed(MouseEvent e){
Clipboard cb=Toolkit.getDefaultToolkit().getSystemClipboard();
DataFlavor[] df=cb.getAvailableDataFlavors();

for(int i=0;i<df.length;i++){
try{
Object x=cb.getData(df[i]);
if(x instanceof String) //text data
System.out.println(x.toString());

else if(x instanceof List){
List lst=(List)x;
int size=lst.size();
for(int count=0;count<size;count++){ //list of files
File f=(File)lst.get(count);
                                System.out.println(f.getPath());
}

}
else if(x instanceof Image){ //image data
//do something with the image data
}
}catch(Exception ep){ep.printStackTrace();}
}
}

}

Sunday, September 1, 2013

JTree

JTree is a component that can be used to display data hierarchically. Below are some useful constructors and methods of the JTree class.

Constructors of the JTree class:
-JTree()
creates an empty tree.
-JTree(TreeModel tm)
creates a tree that its data are from TreeModel, tm.
-JTree(TreeNode rootNode)
creates a tree with the specified root node.
Some useful methods of the JTree class:
-getSelectedPath(): TreePath
returns the selected path of the tree.
-getLastSelectedPathComponent(): TreeNode
returns the last selected node of the tree.
-setModel(TreeModel tm):void
sets the data model of the tree.

A tree can have many nodes. The tree always starts with a root node. A root node is parent of all its child nodes. A node can have at most one parent and two child nodes. A node that does not have a child is call leaf node. To create node, you can use the DefaultMutableTreeNode(Object object) class. The instance of this class is node object that can be added to the tree. To determine whether or not a node is a leaf, a root, you can use the isLeaf(), isRoot() methods respectively. You can also add a child node to its parent node by using the add(TreeNode childNode) method.

A tree generate tree selection event. So you need to implement the TreeSelectionListener interface and override the valueChanged(TreeSelectionEvent e) method to perform action.

The example code below creates a tree to display a hierarchical files and directories in a drive. When the program firstly starts, the tree displays the files and directories in the drive determined by the first item of the combobox. You can change the drive so that it leads to the change of the files and directories by selecting a drive from this combobox. When the user selects a node of the tree, the program checks whether this node of the tree is a directory or a file. If it is a directory, its sub-directories and files are listed.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.util.ArrayList;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

class JTreeShow extends JFrame implements TreeSelectionListener{
JTree tree;
DefaultMutableTreeNode rootNode;
JLabel lblpath;
JComboBox cboDrives;
JTreeShow(String title){
setTitle(title);
setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contpane=getContentPane();
contpane.setBackground(Color.WHITE);
contpane.setLayout(new BorderLayout());
cboDrives=new JComboBox(getDrives().toArray());
cboDrives.addItemListener(new ItemList());
tree=new JTree();
tree.addTreeSelectionListener(this);
JScrollPane scroll=new JScrollPane(tree);
JPanel p=new JPanel(new FlowLayout(FlowLayout.LEFT));
p.add(cboDrives);
lblpath=new JLabel();
p.add(lblpath);
contpane.add(p,BorderLayout.NORTH);
contpane.add(scroll,BorderLayout.CENTER);
lstShow();

/*
Enumeration iterator=rootNode.preorderEnumeration();
while(iterator.hasMoreElements()){
System.out.println(iterator.nextElement().toString());
}
*/
setVisible(true);

}

class ItemList implements ItemListener{
public void itemStateChanged(ItemEvent e){
lstShow();
}
}

public void lstShow(){
String pathRoot=cboDrives.getSelectedItem().toString();
rootNode=getTree(new DefaultMutableTreeNode(pathRoot),pathRoot);
DefaultTreeModel tmodel=new DefaultTreeModel(rootNode);
tree.setModel(tmodel);

}

public ArrayList<String> getDrives(){
ArrayList<String> drlist=new ArrayList<String>();
File[] dr=File.listRoots();
for(File d:dr){
drlist.add(d.toString());

}
return drlist;
}
public void valueChanged(TreeSelectionEvent te){
try{

TreePath path=tree.getSelectionPath();
DefaultMutableTreeNode selnode=(DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
Object[] paths=path.getPath();
String pat="";
for(Object o:paths){
pat+="/"+o.toString();
}
pat=pat.substring(1);
DefaultMutableTreeNode tempnode=getTree(selnode,pat);
lblpath.setText(pat);
tempnode=null;
}catch(Exception err){}

}


public DefaultMutableTreeNode getTree(DefaultMutableTreeNode rootNode, String path){
File f=new File(path);
if(f.isDirectory()){
rootNode.setAllowsChildren(true);
File[] fs=f.listFiles();
for(File myf:fs){
DefaultMutableTreeNode node=new DefaultMutableTreeNode(myf.getName());
node.setAllowsChildren(true);
if(myf.isDirectory()){
node.setAllowsChildren(true);

}
else{
node.setAllowsChildren(false);

}
rootNode.add(node);

}
}
return rootNode;
}

}


public class JFrameSwing {
public static void main(String[] args){
new JTreeShow("JTree");
}
}
JTree Swing