Creating a checked SWT Table

Main.java:

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
 
public class Main {
   public static void main(String[] args) {
      Display display = new Display();
      Shell shell = new Shell(display);
 
      // pos x, pos y, width, height
      shell.setBounds(200, 200, 300, 200);
      shell.setText("SWT Table Demonstration");
      shell.setLayout(new GridLayout());
 
      final Table table;
      String[] columnTitles = { "Wine", "Vintage", "Price" };
 
      Object[][] tabledata = {
            { "Chateau Meyney, St. Estephe",       new Integer(1994), "$18.75"},
            { "Chateau Montrose, St. Estephe",     new Integer(1975), "$54.25" },
            { "Chateau Gloria, St. Julien",        new Integer(1993), "$22.99" },
            { "Chateau Beychevelle, St. Julien",   new Integer(1970), "$61.63" },
            { "Chateau La Tour de Mons, Margeaux", new Integer(1975), "$57.03" },
            { "Chateau Brane-Cantenac, Margeaux",  new Integer(1978), "$49.92" },
      };
 
      Group tableGroup = new Group(shell, SWT.NULL);
      GridLayout gridLayout = new GridLayout();
      gridLayout.numColumns = 1;
      tableGroup.setLayout(gridLayout);
      tableGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
      tableGroup.setText("Table");
 
      table = new Table(tableGroup, SWT.FULL_SELECTION | SWT.CHECK);
      table.setHeaderVisible(true);
       
      for (int i=0; i<columnTitles.length; i++) {
         TableColumn tableColumn = new TableColumn(table, SWT.NULL);
         tableColumn.setText(columnTitles[i]);
      }  
       
      for (int i=0; i<tabledata.length; i++) {
         TableItem tableItem = new TableItem(table, SWT.NULL);
         for (int j=0; j<columnTitles.length; j++) {
            tableItem.setText(j, ""+tabledata[i][j]);
         }
      }
 
      for (int i=0; i<columnTitles.length; i++) {
         TableColumn tableColumn = table.getColumn(i);
         tableColumn.pack();
      }      
       
      shell.open();
       
      shell.addShellListener(new ShellAdapter() {
         public void shellClosed(ShellEvent se) {
            for (int i=0; i<table.getItemCount(); i++) {
               TableItem tableItem = table.getItem(i);
               System.out.println(tableItem.getText(0));
               System.out.println("tChecked: " + tableItem.getChecked());
            }                        
         }
      });
 
      while (!shell.isDisposed()) {
         if (!display.readAndDispatch()) {
            display.sleep();
         }
      }
       
      display.dispose();
      
   }
}

Creating a smooth ProgressBar in SWT

Main.java:

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
 
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
 
public class Main {
   private DownloadThread downloadThread = null;
   private boolean disposed = false;
    
   public Main() {
      final Display display = new Display();
      Shell shell = new Shell(display);
      shell.setText("SWT Smooth ProgressBar Demonstration");

      shell.setLayout(new FormLayout());
      shell.setBounds(200, 200, 700, 200);
       
      Label downloadLabel = new Label(shell, SWT.NONE);
      FormData data0 = new FormData();
      data0.left = new FormAttachment(0, 0);
      //data0.top = new FormAttachment(localLabel, 15);
      //data2.right = new FormAttachment(100, -100);
      downloadLabel.setLayoutData(data0);
      downloadLabel.setText("FTP file: ");
 
      final Text downloadField = new Text(shell, SWT.SINGLE | SWT.BORDER);
      FormData data1 = new FormData();
      data1.left = new FormAttachment(downloadLabel, 15);
      data1.right = new FormAttachment(100, -100);
      downloadField.setLayoutData(data1);
      downloadField.setText("ftp://ftp.mozilla.org/pub/mozilla/moz-sol/1.2a-02-09-25/mozilla-sparc-sun-solaris2.7.tar.gz");
            
      Label localLabel = new Label(shell, SWT.NONE);
      FormData data2 = new FormData();
      data2.left = new FormAttachment(0, 0);
      data2.top = new FormAttachment(localLabel, 15);
      localLabel.setLayoutData(data2);
      localLabel.setText("Save As: ");
      
      final Text localField = new Text(shell, SWT.SINGLE | SWT.BORDER);
      FormData data3 = new FormData();
      data3.left = new FormAttachment(localLabel, 15);
      data3.top = new FormAttachment(downloadField, 5);
      data3.right = new FormAttachment(100, -400);
      localField.setLayoutData(data3);
      localField.setText("c:\temp\tmp.bin");
      
      final Button downloadButton = new Button(shell, SWT.NONE);
      FormData data4 = new FormData();
      data4.left = new FormAttachment(downloadField, 5);
      data4.right = new FormAttachment(100, -5);
      downloadButton.setLayoutData(data4);
      downloadButton.setText("Download");
      
      Label progressLabel = new Label(shell, SWT.NONE);
      progressLabel.setText("Download progress:");
      FormData data5 = new FormData();
      data5.top = new FormAttachment(localField, 15);
      data5.left = new FormAttachment(10, 15);      
      data5.right = new FormAttachment(90, -15);
      progressLabel.setLayoutData(data5);      
             
      final ProgressBar progressBar = new ProgressBar(shell, SWT.SMOOTH);
      FormData data6 = new FormData();
      data6.top = new FormAttachment(localField, 35);
      data6.left = new FormAttachment(10, 15);      
      data6.right = new FormAttachment(90, -15);
      progressBar.setLayoutData(data6);
 
      shell.open();
 
      final DownloadListener downloadListener = new DownloadListener() {
         public void setMinimum(final int min) {
            display.asyncExec(new Runnable() {
               public void run() {
                  if (!disposed) {
                     progressBar.setMinimum(min);
                  }
               }
            });
         }
         
         public void setMaximum(final int max) {
            display.asyncExec(new Runnable() {
               public void run() {
                  if (!disposed) {
                     progressBar.setMaximum(max);
                  }
               }
            });
         }
         
         public void setSelection(final int selection) {
            display.asyncExec(new Runnable() {
               public void run() {
                  if (!disposed) {
                     progressBar.setSelection(selection);
                  }
               }
            });
         }
         
         public void downloadEnded() {
            if (!disposed) {
               display.asyncExec(new Runnable() {
                  public void run() {
                     System.out.println("disposed = " + disposed);
                     if (!disposed) {                  
                        downloadButton.setText("Download");  
                     }
                  }
               });
            }
         }
      };
      
      downloadButton.addSelectionListener(new SelectionAdapter() {
         public void widgetSelected(SelectionEvent event) {
            try {
               Button button = (Button) event.getSource();
               if (button.getText().equalsIgnoreCase("download")) {
                  if (downloadField.getText().trim().equals("")) return;
                  
                  File localFile = new File(localField.getText());
                  downloadThread = new DownloadThread(downloadListener, 
                                                      localFile,
                                                      new URL(downloadField.getText()));
                  downloadThread.start();
                  downloadButton.setText("Stop");
               }
               else {
                  downloadThread.terminate();
               }
            }
            catch(MalformedURLException e) {
               e.printStackTrace();
            }
         };
      });
 
      shell.addShellListener(new ShellAdapter() {
         public void shellClosed(ShellEvent se) {
            disposed = true;     
            if (downloadThread != null) {         
               downloadThread.terminate();
            }
         }
      });        
      
      while (!shell.isDisposed()) {
         if (!display.readAndDispatch()) {
            display.sleep();
         }
      }
      
      display.dispose();
   }
   
   public static void main(String[] args) {
      new Main();
   }
}
 
interface DownloadListener {
   public void setMinimum(int min);
   public void setMaximum(int max);
   public void setSelection(int selection);
   public void downloadEnded();
}
 
class DownloadThread extends Thread
{
   private int length = 0;
   private URL url = null;
   private File localFile = null;
   private DownloadListener listener = null;
   private boolean terminated = false;
   
   public DownloadThread(DownloadListener listener, File localFile, URL url) {
      this.url = url;
      this.localFile = localFile;
      this.listener = listener;
   }
   
   public void terminate() {
      terminated = true;
   }
   
   public void run() {
      try {
         System.out.println(url);
         URLConnection con = url.openConnection();
         System.out.println("Connecting...");
         con.connect();
         System.out.println("Connected!");
         int length = con.getContentLength();
 
         listener.setMinimum(0);
         listener.setMaximum(length);
          
         int block = 4096;
         int count = 0;
         FileOutputStream fos = new FileOutputStream(localFile);
         InputStream is = con.getInputStream();
         byte[] buff = new byte[block];
         int read = 0;
 
         listener.setSelection(0);
         while((read = is.read(buff, 0, block)) != -1) {
            byte[] bytes;
            if(read != buff.length) {
               bytes = new byte[read];
               System.arraycopy(buff, 0, bytes, 0, read);
            } 
            else {
               bytes = buff;
            }
            fos.write(bytes);
            count += read;
           
            if (terminated) {
               break;
            }
 
            listener.setSelection(count);
         }
         fos.flush();
         fos.close();
         
         listener.downloadEnded();
      } catch(Exception e) {
         System.out.println("Error downloading file " + url);
         e.printStackTrace();
      }
   }
}

Get a list of messages from a POP server in Java

Main.java:

import javax.mail.internet.*;
import javax.mail.*;
import java.util.*;
 
public class Main
{
   public static void main(String []args) {
      try {
         String host = "FILL IN POP3 SERVER HERE";
         String user = "FILL IN UN HERE";
         String pass = "FILL IN PW HERE";
  
         Session session = Session.getInstance(System.getProperties(), null);
  
         Store store = session.getStore("pop3");
         store.connect(host, user, pass);
  
         // only "INBOX" is supported
         Folder folder = store.getFolder("INBOX");
 
         // open the folder read-only
         folder.open(Folder.READ_ONLY);
 
         // get all the messages and print from and subject field 
         Message messages[] = folder.getMessages();
         for (int i=0; i<messages.length; i++) {
            System.out.print(messages[i].getMessageNumber() + "t");
            System.out.print(messages[i].getSentDate() + "t");
            System.out.print(messages[i].getFrom()[0] + "t");
            System.out.println(messages[i].getSubject());
         }
 
         // close the folder, but do not delete (expunge) the messages
         folder.close(false);
         store.close();
      }
      catch(Exception e) {
         e.printStackTrace();
      }
   }
}

Writing a custom FocusTraversalPolicy

[JDK 1.4+] Extend from FocusTraversalPolicy and implement the abstract methods!

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
  
public class Main extends JFrame
{
   JLabel label = new JLabel("Forward: TAB or alt-f, Backward: SHIFT-TAB or alt-b");
   ArrayList textfields = new ArrayList();
   JRadioButton leftToRight = new JRadioButton("Left to right", true);
   JRadioButton topToBottom = new JRadioButton("Top to bottom");
  
   public Main() {
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
      Container contentPane = getContentPane();
      contentPane.setLayout(new BorderLayout(10, 10));
  
      JPanel topPanel = new JPanel(new GridLayout(3, 1));
      topPanel.add(new JLabel("Change the focus traversal policy"));
 
      ButtonGroup group = new ButtonGroup();
      group.add(leftToRight);
      group.add(topToBottom);
      topPanel.add(leftToRight); 
      topPanel.add(topToBottom);
 
      JPanel bottomPanel = new JPanel(new GridLayout(4, 2));
      for (int i=0; i<4; i++) {
         for (int j=0; j<2; j++) { 
            JTextField textfield = new JTextField("" + i + ", " + j);
            textfields.add(textfield);
            bottomPanel.add(textfield);
         }
      }     
  
      contentPane.add(BorderLayout.NORTH, topPanel);
      contentPane.add(BorderLayout.SOUTH, bottomPanel);
  
      bottomPanel.setFocusTraversalPolicy(new MyFocusTraversalPolicy());
      bottomPanel.setFocusCycleRoot(true);
   } 
  
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(350, 200);
      main.setVisible(true);
   }
 
   class MyFocusTraversalPolicy extends FocusTraversalPolicy
   {
      // Returns the Component that should receive the focus after aComponent.
      public Component getComponentAfter(Container focusCycleRoot, Component aComponent) {
         if (leftToRight.isSelected()) {
            int index = textfields.indexOf(aComponent);
            return (Component) textfields.get((index + 1) % textfields.size());
         }
         else if (topToBottom.isSelected()) {
            int index = textfields.indexOf(aComponent);
            int nextIndex = (index + 2) % textfields.size();
            if (nextIndex == 0) nextIndex = 1;
            else if (nextIndex == 1) nextIndex = 0;
            return (Component) textfields.get(nextIndex);
         }
 
         if (!aComponent.isEnabled()) {
            return getComponentAfter(focusCycleRoot, aComponent);
         }          
 
         return aComponent;
      }
  
      // Returns the Component that should receive the focus before aComponent.
      public Component getComponentBefore(Container focusCycleRoot, Component aComponent) {
         if (leftToRight.isSelected()) {
            int index = textfields.indexOf(aComponent);
            index--;
            if (index < 0) index = textfields.size() - 1;
            return (Component) textfields.get(index);
         }
         else if (topToBottom.isSelected()) {
            int index = textfields.indexOf(aComponent);
            index -= 2;
            if (index < 0) index = textfields.size() - 3 - index;
            //else if (index == 0) index = textfields.size() - 1;
            //else if (index == 1) index = textfields.size() - 2;
            return (Component) textfields.get(index);
         }
 
         return aComponent;
      }
  
      // Returns the default Component to focus.
      public Component getDefaultComponent(Container focusCycleRoot) {
         return (Component) textfields.get(0);
      }
 
      // Returns the first Component in the traversal cycle.
      public Component getFirstComponent(Container focusCycleRoot) {
         return (Component) textfields.get(0);
      }
 
      // Returns the Component that should receive the focus when a Window is made visible for the first time. 
      public Component getInitialComponent(Window window) {
         return leftToRight;
      }
 
      // Returns the last Component in the traversal cycle. 
      public Component getLastComponent(Container focusCycleRoot) {
         return (Component) textfields.get(textfields.size() - 1);
      }
   }
}

Creating a method with a variable number of arguments

JDK1.5 allows methods to have a variable number of arguments. The syntax is to specify the type, three dots and the argument name. The variable number of arguments must be the last argument to the method. Other (normal) arguments may precede the variable argument list. Only one variable argument list may be specified.

Main.java:

public class Main
{
   public static void main(String []args) {
      printStrings("one arg");
      System.out.println("--------------");
      printStrings("an arg", "another arg");
   }
   
   public static void printStrings(String... strings) {
      for (int i=0; i<strings.length; i++) {
         System.out.println(strings[i]);
      }   
   }
}

Get the current process ID in JDK 1.5

The following example is platform-dependent and was only tested with Sun’s JVM 1.5.0 on Windows XP. It first shows you how to get it using the standard management API’s and then using some reflection tricks and the undocumented sun.* classes.

Main.java (Using RuntimeMBean):

import java.lang.management.*;

public class Main
{
   public static void main(String []args) {
      RuntimeMBean mbean = ManagementFactory.getRuntimeMBean();
      String name = mbean.getName();
       
      System.out.println(name);
   }
}

Main.java (Using reflection):

import sun.management.*;
import java.lang.reflect.*;

public class Main
{
   public static void main(String []args) throws Exception {
      int pid = getProcessId();
      System.out.println("Current processID: " + pid);
       
      try {
         Thread.sleep(10000);
      }
      catch(Exception e) { }
   }
    
   public static int getProcessId() throws Exception {
      // next line to trigger loading of library
      ManagementFactory.getThreadMXBean();
       
      Class c = Class.forName("sun.management.VMManagementImpl");
      //VMManagementImpl impl = new VMManagementImpl();
         
      Constructor constructor = c.getDeclaredConstructor(new Class[] { });
      constructor.setAccessible(true);
      Object impl = constructor.newInstance(new Object[] { });
       
      Method m = c.getDeclaredMethod("getProcessId", new Class[] { });
      m.setAccessible(true);
      Object result = m.invoke(impl, new Object[] { });
      
      return (Integer) result;
   }
}

Note that I’ve written a DLL / so before to get the process ID using JNI in all JDK versions.
It can be found here.

Drawing text on top of a BufferedImage

Main.java:

import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame {
   BufferedImage image;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      createImage();
   }
 
   public void createImage() {
      Image backImage = new javax.swing.ImageIcon("mong.jpg").getImage(); 
      int width = backImage.getWidth(this); 
      int height = backImage.getHeight(this); 
      image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
      Graphics2D g2d = image.createGraphics(); 
      g2d.drawImage(backImage, 0, 0, this); 

      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON);
      Font f = new Font("Mistral", Font.BOLD, 56);
      g2d.setFont(f);
      String text = "Philip Elliott";
      FontMetrics fm = getFontMetrics(f);       
      int swidth = fm.stringWidth(text);
      int sheight = fm.getAscent();
 
      GradientPaint gp = new GradientPaint(20, 50, Color.red, 
                                           100, 130, Color.yellow, true); 
      g2d.setPaint(gp);
      g2d.drawString(text, width/2 - swidth/2, height/2 + sheight/2);   
 
      setSize(width, height);
   }
  
   public void paint(Graphics g) { 
      Graphics2D g2d = (Graphics2D) g; 
 
      g2d.drawImage(image, null, 0, 0); 
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setVisible(true);
   }
}

Image used:

Using PipedInputStream and PipedOutputStream

A PipedInputStream and PipedOutputStream are used to communicate between threads. If you connect the two together, whatever you write to the PipedOutputStream, you receive on the PipedInputStream.

Here’s an example:

Main.java:

import java.io.*;
 
public class Main
{
   public static void main(String []args) {
      try {
         PipedOutputStream pos = new PipedOutputStream();
         PipedInputStream pis = new PipedInputStream(pos);
 
         BufferedInputStream bis = new BufferedInputStream(pis);
  
         new DataCollector(pos).start();
  
         // thread has started to produce data, start 
         // reading data through the pipe here
         while (true) {
            byte[] buffer = new byte[64];
            bis.read(buffer);
            System.out.println("Received: " + new String(buffer));
         }
      }
      catch(IOException e) { 
         e.printStackTrace();
      }
   }
}
 
class DataCollector extends Thread
{
   private BufferedOutputStream bos;
 
   public DataCollector(OutputStream out) {
      this.bos = new BufferedOutputStream(out);
   }
  
   public void run() {
      // generate data here
      int count=0;
      while (true) {
         try {
            count++;
            String data = "data [" + count + "]";
            bos.write(data.getBytes());
            // perform a flush here to make the receiver get it right away
            bos.flush();
            sleep(1000);
         }
         catch(Exception e) {
            e.printStackTrace();
         }
      }
   }
}

outputs:

Received: data [1]
Received: data [2]
Received: data [3]
Received: data [4]
Received: data [5]
Received: data [6]
Received: data [7]
Received: data [8]
Received: data [9]
. . .

Redirecting System.out to a file

Instantiate a PrintStream that streams to your file and use the System.setOut method.
The same can be done for the input and error streams (setIn and setErr).

import java.io.*;
 
public class Main
{
   public static void main(String args[]) {
      try {
         BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("log"));
         PrintStream ps = new PrintStream(bos);
         System.setOut(ps);
 
         System.out.println(&quot;Hello world!&quot;);
 
         ps.close();
      }
      catch(FileNotFoundException e) {
         System.out.println(e);
      }
   }
}

List the available system roots in Java

Use the method listRoots in the File class. Notice that this is filesystem dependent. On Unix, there is only one system root: “/”. On Windows, it depends on drives that are mapped.
Here’s an example:

Main.java:

import java.io.*;
   
public class Main {
   public static void main(String[] args) {
      File[] roots = File.listRoots();
      for (int i=0; i<roots.length; i++) {
         System.out.println(roots[i]);
      }
   }
}

outputs on my machine:

A:
C:
D:
E: