Creating a JList with icons and text

Main.java:

import java.awt.image.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
  
public class Main 
{
   public static void main(String args[]) {
      JFrame frame = new JFrame("JList ImageIcon Demonstration");
 
      DefaultListModel dlm = new DefaultListModel();
      dlm.addElement(new ListEntry("Audio", new ImageIcon("audio.gif")));
      dlm.addElement(new ListEntry("Control Panel", new ImageIcon("controlpanel.gif")));
      dlm.addElement(new ListEntry("Folder", new ImageIcon("folder.gif")));
      dlm.addElement(new ListEntry("Local Disk (C:)", new ImageIcon("mycomp.gif")));
      dlm.addElement(new ListEntry("doc on '192.168.0.1' (Z:)", new ImageIcon("network.gif")));
 
      JList list = new JList(dlm);
      list.setCellRenderer(new ListEntryCellRenderer());
         
      frame.getContentPane().add(BorderLayout.CENTER, new JScrollPane(list)); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setVisible(true);
   }
}
 
class ListEntry 
{
   private String value;
   private ImageIcon icon;
 
   public ListEntry(String value, ImageIcon icon) {
      this.value = value;
      this.icon = icon;
   }
 
   public String getValue() {
      return value;
   }
 
   public ImageIcon getIcon() {
      return icon;
   }
 
   public String toString() {
      return value;
   }
}
 
class ListEntryCellRenderer
 extends JLabel implements ListCellRenderer
{
   private JLabel label;
 
   public Component getListCellRendererComponent(JList list, Object value,
                                                 int index, boolean isSelected,
                                                 boolean cellHasFocus) {
      ListEntry entry = (ListEntry) value;
 
      setText(value.toString());
      setIcon(entry.getIcon());
  
      if (isSelected) {
         setBackground(list.getSelectionBackground());
         setForeground(list.getSelectionForeground());
      }
      else {
         setBackground(list.getBackground());
         setForeground(list.getForeground());
      } 
 
      setEnabled(list.isEnabled());
      setFont(list.getFont());
      setOpaque(true);
 
      return this;
   }
}

Putting a JCheckbox in a JComboBox

Here’s a working example:

Main.java:

import javax.swing.*;
import java.awt.*;
import java.util.*;
 
public class Main extends JFrame
{
   public Main() {
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
      getContentPane().setLayout(new FlowLayout());
       
      Vector v = new Vector();
      v.add("Europe");
      v.add(new JCheckBox("Brussels", false));
      v.add(new JCheckBox("Paris", false));
      v.add(new JCheckBox("London", false));
      v.add("United States");
      v.add(new JCheckBox("New York", false));
      v.add(new JCheckBox("Detroit", false));
      v.add(new JCheckBox("San Francisco", false));
 
      getContentPane().add(new JComboCheckBox(v));
   }
    
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   }
}

JComboCheckBox.java:

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
 
public class JComboCheckBox extends JComboBox 
{
   public JComboCheckBox() { 
      init(); 
   }
   
   public JComboCheckBox(JCheckBox[] items) { 
      super(items); 
      init(); 
   }
   
   public JComboCheckBox(Vector items) { 
      super(items); 
      init(); 
   }
   
   public JComboCheckBox(ComboBoxModel aModel) { 
      super(aModel); 
      init(); 
   }
   
   private void init() {
      setRenderer(new ComboBoxRenderer());
      addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) { 
            itemSelected(); 
         }
      });
   }
 
   private void itemSelected() {
      if (getSelectedItem() instanceof JCheckBox) {
         JCheckBox jcb = (JCheckBox)getSelectedItem();
         jcb.setSelected(!jcb.isSelected());
      }
   }
 
   class ComboBoxRenderer implements ListCellRenderer {
      private JLabel label;
      
      public ComboBoxRenderer() { 
         setOpaque(true); 
      }
      
      public Component getListCellRendererComponent(JList list, Object value, int index, 
                                                    boolean isSelected, boolean cellHasFocus) {
         if (value instanceof Component) {
            Component c = (Component)value;
            if (isSelected) {
               c.setBackground(list.getSelectionBackground());
               c.setForeground(list.getSelectionForeground());
            } else {
               c.setBackground(list.getBackground());
               c.setForeground(list.getForeground());
            }
             
            return c;
         } else {
            if (label ==null) {
               label = new JLabel(value.toString());
            }
            else {
               label.setText(value.toString());
            }
               
            return label;
         }
      }
   }
}

Using a ConcurrentLinkedQueue

A ConcurrentLinkedQueue is an unbounded non-blocking FIFO queue. Although there is already a thread-safe implementation of a linked list:

   List list = Collections.synchronizedList(new LinkedList(...));

the ConcurrentLinkedQueue offers better concurrent performance and scalability.

Main.java:

import java.util.concurrent.*;
import java.util.*;
 
public class Main
{
   public static void main(String []args) {
      Queue<Message> queue = new ConcurrentLinkedQueue<Message>();
 
      Producer p = new Producer(queue);
      new Thread(p).start();
 
      // wait a bit before consuming to allow the queue to fill up
      // and force a blocking wait
      try { Thread.sleep(1000); } catch(InterruptedException e) { }
      Consumer c = new Consumer(queue);
      new Thread(c).start();
   }
}
 
class Producer implements Runnable
{
   private Queue<Message> queue;
 
   public Producer(Queue<Message> queue) {
      this.queue = queue;
   }
 
   public void run() {
      for (int i=0; i<1000; i++) {
         Message<String> m = new Message<String>("message contents #" + i);
         System.out.println("Producing '" + m + "'");
         queue.offer(m);
      }
   }
}
 
class Consumer implements Runnable
{
   private Queue<Message> queue;
    
   public Consumer(Queue<Message> queue) {
      this.queue= queue;
   }
    
   public void run() {
      while (true) {
         Message m = queue.poll();
         if (m != null) {
            System.out.println("tConsuming '" + m + "'");
         }
         else {
            System.out.println("All elements consumed.");
            break;
         }
      }
   }
}
 
class Message<T> {
   private T contents;
    
   public Message(T contents) {
      this.contents = contents;
   }
    
   public T getContents() {
      return contents;
   }
    
   public String toString() {
      return ""+contents;
   }
}

Drawing a filled arc in Swing

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame {
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
   }
 
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
 
      g2d.setColor(Color.green); 
      g2d.fillArc(10, 50, getSize().width-20, getSize().height-50, 90, 45);
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(100, 100);
      main.setVisible(true);
   }
}

Performance gain of a BufferedInputStream over an InputStream

IO happens a lot faster if you wrap your original InputStream using BufferedInputStream. Internally, it uses a default buffer size of 2048 bytes. For example, wrapping a FileInputStream in a BufferedInputStream will result in a significant performance gain.

Main.java:

import java.io.*;
  
public class Main {
   public static void main(String args[]) {
      if (args.length != 1) {
         System.err.println("Usage: java Main <file.txt>");
         System.exit(1);
      }
 
      long start1 = System.currentTimeMillis();
      readFileIS(args[0]);
      long end1 = System.currentTimeMillis();
      System.out.println("Reading using FileInputStream: " + (end1 - start1) + " ms.");
  
      long start2 = System.currentTimeMillis();
      readFileBIS(args[0]);
      long end2 = System.currentTimeMillis();
      System.out.println("Reading using BufferedInputStream: " + (end2 - start2) + " ms.");
   }  
 
   public static void readFileIS(String filename) {
      try {
         FileInputStream fis = new FileInputStream(filename);
         while (fis.read() > 0) ;
      }
      catch(Exception e) {
         System.err.println(e);
         System.exit(1);
      }
   }
 
   public static void readFileBIS(String filename) {
      try {
         BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filename));
         while (bis.read() > 0) ;
      }
      catch(Exception e) {
         System.err.println(e);
         System.exit(1);
      }
   }
}

Writing a text file using FileWriter

Main.java:

import java.io.*;
 
public class Main
{
   public static void main(String []args) {
      String lineSeparator = System.getProperty("line.separator");
      StringBuffer sb = new StringBuffer();
      sb.append("Hello");
      sb.append(lineSeparator);
      sb.append("World!");
      sb.append(lineSeparator);
 
      try {
         BufferedWriter bw = new BufferedWriter(new FileWriter("textfile.txt"));
         bw.write(sb.toString());
         bw.close();
      } 
      catch(IOException e) {
         e.printStackTrace();
      }
   }
} 

How do I read a file that contains numbers?

The following code reads Numbers as well as String from a File.

import java.io.*;
 
public class readNumbers  {
 
   public static void main(String arg[])  {
      BufferedReader bis=null;
      StreamTokenizer st=null;
 
      try  {
         bis = new BufferedReader(new FileReader
                                ("numberFile.txt"));
	 st = new StreamTokenizer(bis);
      }
      catch(FileNotFoundException e)  {
         System.out.println("File Not Found");
      }
 
      try  {
	 while (st.nextToken() != StreamTokenizer.TT_EOF)  {
	    if (st.ttype == StreamTokenizer.TT_WORD)  {
	       System.out.println("String: " +  st.sval);
	    }
            else if (st.ttype == StreamTokenizer.TT_NUMBER)  {
	       System.out.println("Number: " + st.nval);
	    }
         }
      }
      catch(IOException e)  {
	 e.printStackTrace();
      }
   }
}

Eg., File(numberFile.txt) contents:

20432   34343  Testing String
23432  3343

Output:

Number: 20432.0 
Number: 34343.0 
String: Testing 
String: String 
Number: 23432.0 
Number: 3343.0

Converting RTF to ASCII text using RTFEditorKit

Main.java:

import javax.swing.text.rtf.*;
import javax.swing.text.*;
import java.io.*;
 
public class Main 
{
   public static void main(String []args) throws Exception {
      RTFEditorKit rtf = new RTFEditorKit();
      Document doc = rtf.createDefaultDocument();
 
      FileInputStream fis = new FileInputStream("c:\richtext.rtf");
      rtf.read(fis,doc,0);
      System.out.println(doc.getText(0,doc.getLength()));
   }
}

You can find the file richtext.rtf here.

Output:

 
This is rich text
 
This is RICH TEXT
 
THIS IS RICH TEXT
 
and if you don't believe it
 
I'll tell ya another fun story

Of course, you can also call an external program to do the conversion for you, eg. http://www.a2001.com/english/down/rtf.html

Convert a char to an int

eg.

char c = ‘A’;
int value = (char) c;

Following code demonstrates this. It prints out the ascii values of each letter
in a sentence:

public class Main
{
   public static void main(String args[]) {
      String s = "A woman doesn't have a banana";
 
      for (int i=0; i<s.length(); i++) {
         char c    = s.charAt(i);
         int value = (int) c;
 
         System.out.println(c + ": " + value);
      }
   }
}

prints out:

W: 87
o: 111
m: 109
e: 101
n: 110
 : 32
d: 100
o: 111
n: 110
': 39
t: 116
 : 32
h: 104
a: 97
v: 118
e: 101
 : 32
a: 97
 : 32
b: 98
a: 97
n: 110
a: 97
n: 110
a: 97