Preventing a JInternalFrame from being moved

You can subclass the protected class BorderListener that is defined in BasicInternalFrameUI and provide an empty implementation for mouseDragged. In the following example, it is done so for the Metal look and feel.

Main.java:

import javax.swing.plaf.basic.*;
import javax.swing.plaf.metal.*;
import javax.swing.event.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.net.*;
 
public class Main extends JFrame {
   JDesktopPane desktop;
   int nframes = 0;
 
   JMenu internalFrameMenu;
 
   public Main() {
      desktop = new JDesktopPane(); 
      setContentPane(desktop);
      setJMenuBar(createMenuBar());
      createInternalFrame(); 
   }
 
   protected JMenuBar createMenuBar() {
      JMenuBar menuBar = new JMenuBar();
 
      JMenu createMenu = new JMenu("Create");
      createMenu.setMnemonic(KeyEvent.VK_C);
      JMenuItem newMenuItem = new JMenuItem("New");
      newMenuItem.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            createInternalFrame();
         }
      }); 
      newMenuItem.setMnemonic(KeyEvent.VK_N);
      createMenu.add(newMenuItem);
      menuBar.add(createMenu);
  
      return menuBar;
   }
 
   protected void createInternalFrame() {
      nframes++;
      String title = "JInternalFrame #" + nframes;
      JInternalFrame frame = new JInternalFrame(title,
         true,    // resizable
         true,    // closable
         true,    // maximizable
         true);   // iconifiable
      frame.setVisible(true); 
      desktop.add(frame);
      frame.setSize(200, 200);
      frame.setLocation(30*nframes, 30*nframes);
      try {
         frame.setSelected(true);
      } catch (java.beans.PropertyVetoException e) {}
 
      frame.setUI(new MyMetalInternalFrameUI(frame));
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(500, 300);
      main.setVisible(true);
   }
}
 
class MyMetalInternalFrameUI extends MetalInternalFrameUI {
   public MyMetalInternalFrameUI(JInternalFrame b) { super(b); }
 
   protected MouseInputAdapter createBorderListener(JInternalFrame w) {
      return new MyBorderListener();
   }
 
   protected class MyBorderListener extends BasicInternalFrameUI.BorderListener {
      public void mouseDragged(MouseEvent e) {  }
   }
}

Implementing a mouseover effect with a JButton

Add a MouseListener to your JButton and code the desired behaviour in mouseEntered and mouseExited.
This example makes the JButton’s label red when mouse-moving over it.

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
   
public class Main extends JFrame {
   JList list; 
 
   public Main() {
      getContentPane().setLayout(new FlowLayout());
 
      // following objects are final because they are used
      // in a inner class
      final JButton button = new JButton("OK!");
      button.addMouseListener(new MouseAdapter() {
         Color oldcolor = button.getForeground();
         public void mouseEntered(MouseEvent me) {
            oldcolor = button.getForeground();
            button.setForeground(Color.red); 
         }
         public void mouseExited(MouseEvent me) {
            button.setForeground(oldcolor);
         }
      });
 
      getContentPane().add(button);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      setSize(400, 400);
   }
 
   public static void main(String[] args) {
      (new Main()).show();
   }
}

Creating a JList with images

Create your own CellRenderer and change the default behavior as to show the ImageIcon:

import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
  
public class Main extends JFrame {
 
   public Main() {
      getContentPane().setLayout(new FlowLayout());
 
      Vector v = new Vector();
      v.addElement(new ImageString("first", new ImageIcon("c:\first.gif")));
      v.addElement(new ImageString("second", new ImageIcon("c:\second.gif")));
      v.addElement(new ImageString("third", new ImageIcon("c:\third.gif")));
      v.addElement(new ImageString("fourth", new ImageIcon("c:\fourth.gif")));
      v.addElement(new ImageString("fifth", new ImageIcon("c:\fifth.gif")));
 
      final JList list = new JList(v);
      list.setCellRenderer(new ImageStringCellRenderer());
      getContentPane().add(new JScrollPane(list));
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      setSize(200, 300);
   }
   
   public static void main(String[] args) {
      (new Main()).show();
   }
}
 
class ImageStringCellRenderer extends DefaultListCellRenderer implements ListCellRenderer {
   public Component getListCellRendererComponent(
      JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)    
   {
      ImageString is = (ImageString) value;
      setText(is.getString());
      setIcon(is.getIcon());
      if (isSelected) {
         setBackground(list.getSelectionBackground());
         setForeground(list.getSelectionForeground());
      }
      else {
         setBackground(list.getBackground());
         setForeground(list.getForeground());
      }
      setEnabled(list.isEnabled());
      setFont(list.getFont());
 
      return this;
   }
}
 
class ImageString
{
   private String s;
   private Icon icon;
 
   public ImageString(String s, Icon icon) {
      this.s = s;
      this.icon = icon;
   }
 
   public void setString(String s) {
      this.s = s;
   }
 
   public String getString() {
      return s;
   }
 
   public void setIcon(Icon icon) {
      this.icon = icon;
   }
 
   public Icon getIcon() {
      return icon;
   }
  
   public String toString() {
      return s;
   }
}

Selecting a JList item by double-clicking or pressing Enter

For detecting double-clicking, add a MouseListener and catch the MouseEvents where clickCount is equal to 2.
For detecting the enter key, add a KeyListener and check whether the KeyCode is KeyEvent.VK_ENTER.

Here’s an example:

import javax.swing.event.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
  
public class Main extends JFrame {
 
   public Main() {
      getContentPane().setLayout(new FlowLayout());
 
      Vector v = new Vector();
      for (int i=0; i<50; i++) {
         v.addElement("Item #" + i);
      }
      getContentPane().add(new JLabel("Double-clicked on: "));
      final JTextField dblTextField = new JTextField(15);
      getContentPane().add(dblTextField);
      getContentPane().add(new JLabel("Enter key on: "));
      final JTextField entTextField = new JTextField(15);
      getContentPane().add(entTextField);
      final JList list = new JList(v);
 
      // catch double-click events
      list.addMouseListener(new MouseAdapter() {
         public void mouseClicked(MouseEvent me) {
            if (me.getClickCount() == 2) {
               dblTextField.setText(""+list.getSelectedValue()); 
            }
         }
      });
 
      // catch enter-key events
      list.addKeyListener(new KeyAdapter() { 
         public void keyReleased(KeyEvent ke) { 
            if (ke.getKeyCode() == KeyEvent.VK_ENTER) { 
               entTextField.setText(""+list.getSelectedValue());
            }
         }
      });
 
      getContentPane().add(new JScrollPane(list));    
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      setSize(200, 300);
   }
   
   public static void main(String[] args) {
      (new Main()).show();
   }
}

Using a JSpinner to walk through numbers

Use the SpinnerNumberModel.

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);
         }
      });
 
      getContentPane().setLayout(new FlowLayout(FlowLayout.LEFT));
      final SpinnerNumberModel spinnerModel = 
                   new SpinnerNumberModel(10.0, -500.0, 500.0, .5);
      JSpinner spinner = new JSpinner(spinnerModel);
 
      final JTextField textfield = new JTextField(25);
      JButton button = new JButton("Get number");
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) { 
            textfield.setText(""+spinnerModel.getNumber().doubleValue());
         }
      });
 
      getContentPane().add(spinner);
      getContentPane().add(button);
      getContentPane().add(textfield);
   }
  
   public static void main(String args[])
   {
      Main main = new Main();
      main.setSize(300, 150);
      main.setVisible(true);
   }
}

Drawing an image in a JLabel

Very simple: look at the constructors of JLabel and you’ll see that some of them accept images. A JLabel can contain either text, an image or both. If you have both images and text, you can set the horizontal and vertical text position using the methods:

      setVerticalTextPosition
      setHorizontalTextPosition

Here’s a complete example:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame
{
   JLabel label;
 
   public Main() {
      label = new JLabel("The Logo", new ImageIcon("d:\ESUSLOGO.gif"), 

SwingConstants.CENTER);
      label.setVerticalTextPosition(SwingConstants.BOTTOM);
      label.setHorizontalTextPosition(SwingConstants.CENTER);
      getContentPane().add(BorderLayout.CENTER, label);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
 
      setSize(300, 200);
   }
  
   public static void main(String []args) {
      Main main = new Main();
      main.setVisible(true);
   }
}

Adding a JProgressBar inside a JTable cell

A JTable registers default renderers for a Number, Date, ImageIcon, Boolean and Object. If you want to render another component, you have to create a custom class that implements TableCellRenderer and register it with the method setDefaultRenderer on the JTable object.

The following example creates a JTable where every row displays data from a Download object. A download object is a thread that mimics the behavior of downloading a file by increasing the number of downloaded bytes (progress) with a random value. Using the Observable-Observer pattern, the download object notifies the table model whenever the progress of downloading has changed.

Main.java:

import javax.swing.table.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
 
public class Main extends JFrame {
   public Main() {
      super(&quot;TableModel JProgressBar Demonstration&quot;);
 
      // create our own custom TableModel
      DownloadTableModel downloadModel = new DownloadTableModel();
      JTable table = new JTable(downloadModel);
 
      // add rows to our TableModel, each row is represented as a Download object
      downloadModel.addDownload(new Download(&quot;linuxmandrake.zip&quot;, 1234567));
      downloadModel.addDownload(new Download(&quot;flash5.exe&quot;, 56450000));
      downloadModel.addDownload(new Download(&quot;jdk1.2.2-007.zip&quot;, 20000000));
 
      // render the columns with class JProgressBar as such
      ProgressBarRenderer pbr = new ProgressBarRenderer(0, 100);
      pbr.setStringPainted(true);
      table.setDefaultRenderer(JProgressBar.class, pbr);
   
      // increase the height of the rows a bit
      table.setRowHeight((int) pbr.getPreferredSize().getHeight());
 
      // create the scroll pane and add the table to it. 
      JScrollPane scrollPane = new JScrollPane(table);
 
      // add the scroll pane to this window.
      getContentPane().add(scrollPane, BorderLayout.CENTER);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
   }
 
   public static void main(String[] args) {
      Main main = new Main();
      main.pack();
      main.setVisible(true);
   }
}
 
// a simple object that holds data about a particular download
// it starts a thread and increases the progress of &quot;downloading&quot;
// in a random manner
class Download extends Observable implements Runnable {
   private Thread  thisThread;
 
   private String  filename;
   private int     filesize;
   private float   progress;
 
   public Download(String filename, int filesize) {
      this.filename = filename;
      this.filesize = filesize;
      progress = 0.0f;
      thisThread = new Thread(this);
      thisThread.start();
   }
 
   public String getFilename() { return filename; }
   public int    getFilesize() { return filesize; }
   public float  getProgress() { return progress; }
 
   public String toString() { 
      return &quot;[&quot; + filename + &quot;, &quot; + filesize + &quot;, &quot; + progress + &quot;]&quot;; }

   public void run() {
      Random r = new Random();
      int count = 0;
      while (count &lt; filesize) {
         int random = Math.abs(r.nextInt() % 100000);
         count += random;
         if (count &gt; filesize) count = filesize; 
         progress = ((float) count / filesize) * 100;
 
         // notify table model (and all other observers)
         setChanged();
         notifyObservers(this);       
 
         try { thisThread.sleep(500); } catch(InterruptedException e) { }
      }
   }
}
 
class DownloadTableModel extends AbstractTableModel implements Observer {
   // holds the strings to be displayed in the column headers of our table
   final String[] columnNames = {&quot;Filename&quot;, &quot;Filesize&quot;, &quot;Progress&quot;};
 
   // holds the data types for all our columns
   final Class[] columnClasses = {String.class, Integer.class, JProgressBar.class};
 
   // holds our data
   final Vector data = new Vector();
  
   // adds a row
   public void addDownload(Download d) {
      data.addElement(d);
   
      // the table model is interested in changes of the rows
      d.addObserver(this);
      fireTableRowsInserted(data.size()-1, data.size()-1);
   }
 
   // is called by a download object when its state changes
   public void update(Observable observable, Object o) {
      int index = data.indexOf(o);
      if (index != -1) 
         fireTableRowsUpdated(index, index);
   }
 
   public int getColumnCount() {
      return columnNames.length;
   }
         
   public int getRowCount() {
      return data.size();
   }
 
   public String getColumnName(int col) {
      return columnNames[col];
   }
 
   public Class getColumnClass(int c) {
      return columnClasses1;
   }
 
   public Object getValueAt(int row, int col) {
      Download download = (Download) data.elementAt(row);
      if (col == 0)      return download.getFilename();
      else if (col == 1) return new Integer(download.getFilesize());
      else if (col == 2) return new Float(download.getProgress());
      else return null;
   }
 
   public boolean isCellEditable(int row, int col) {
      return false;
   }
}
 
// a table cell renderer that displays a JProgressBar
class ProgressBarRenderer extends JProgressBar implements TableCellRenderer {
   public ProgressBarRenderer() {
      super();
   }
 
   public ProgressBarRenderer(BoundedRangeModel newModel) {
      super(newModel);
   }
 
   public ProgressBarRenderer(int orient) {
      super(orient);
   } 
 
   public ProgressBarRenderer(int min, int max) {
      super(min, max);
   }
 
   public ProgressBarRenderer(int orient, int min, int max) {
      super(orient, min, max);
   }
 
   public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected, boolean hasFocus,
      int row, int column) {
           
      setValue((int) ((Float) value).floatValue());
 
      return this;
   }
}

Adding a JTable background image that does not scroll

Make sure all your internal JTable components have the opaqueness property set to false. Setting the JTable opaque property to false won’t work as the table is added to a JScrollPane. Extend the JScrollPane class and override the paint method to paint the image every time an event occurs where a repainting is necessary.

Main.java:

import javax.swing.table.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame
{
   public Main() {
      JTable table = new JTable(100, 5) {
         public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
            Component c = super.prepareRenderer(renderer, row, column);
            if (c instanceof JComponent) {
                ((JComponent) c).setOpaque(false);
            }
            return c;
         }
      };
 
      ImageJScrollPane isp = new ImageJScrollPane(table);
 
      isp.setBackgroundImage(new ImageIcon("c:\mong.jpg"));
 
      getContentPane().add(isp);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
   }
 
   public static void main(String [] args) {
      Main main = new Main();
      main.setSize(400, 400);
      main.setVisible(true);
   } 
} 
 
class ImageJScrollPane extends JScrollPane 
{
   private ImageIcon image = null;
 
   public ImageJScrollPane() {
      this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
   }
 
   public ImageJScrollPane(Component view) {
      this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
   }
   
   public ImageJScrollPane(Component view, int vsbPolicy, int hsbPolicy) {
      super(view, vsbPolicy, hsbPolicy);
      if (view instanceof JComponent) {
         ((JComponent) view).setOpaque(false);
      }
   }
 
   public ImageJScrollPane(int vsbPolicy, int hsbPolicy) {
      this(null, vsbPolicy, hsbPolicy);
   }
 
   public void setBackgroundImage(ImageIcon image) {
      this.image = image;
   }
 
   public void paint(Graphics g) {
      // Do not use cached image for scrolling
      getViewport().setBackingStoreEnabled(false);
 
      if (image != null) {
         Rectangle rect = getViewport().getViewRect();
         for (int x=0; x<rect.width; x+=image.getIconWidth()) {
            for (int y=0; y<rect.height; y+=image.getIconHeight()) {
               g.drawImage(image.getImage(), x, y, null, null); 
            }
         }
 
         super.paint(g);
      }
   }
}

Here’s the image I used:

Creating a JTable with a different background color per column

The trick is to contrive a custom DefaultTableCellRenderer and apply it to individual columns provided by the table’s backing column model. The following snippet demonstrates rendering the first column of the table so it displays with grey background and blue foreground highlighting:

Main.java:

import javax.swing.table.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame
{
   public Main() {
      JTable table = new JTable(100, 5);
 
      TableColumn tm = table.getColumnModel().getColumn(0);
      tm.setCellRenderer(new ColorColumnRenderer(Color.lightGray, Color.blue));
 
      getContentPane().add(new JScrollPane(table));
  
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
   }
 
   public static void main(String [] args) {
      Main main = new Main();
      main.setSize(400, 400);
      main.setVisible(true);
   } 
} 
 
/**
* Applied background and foreground color to single column of a JTable
* in order to distinguish it apart from other columns.
*/ 
class ColorColumnRenderer extends DefaultTableCellRenderer 
{
   Color bkgndColor, fgndColor;
 	
   public ColorColumnRenderer(Color bkgnd, Color foregnd) {
      super(); 
      bkgndColor = bkgnd;
      fgndColor = foregnd;
   }
  	
   public Component getTableCellRendererComponent
	    (JTable table, Object value, boolean isSelected,
	     boolean hasFocus, int row, int column) 
   {
      Component cell = super.getTableCellRendererComponent
         (table, value, isSelected, hasFocus, row, column);
 
      cell.setBackground( bkgndColor );
      cell.setForeground( fgndColor );
     
      return cell;
   }
}

Changing the margins between JTable grid lines and cell data

You can do so with the JTable method setIntercellSpacing.

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame 
{
   public Main() {
      super("Table example, Wines from Bordeaux");
 
      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" },
      };
 
      String columnheaders[] = { "Wine", "Vintage", "Price" };
 
      JTable table = new JTable(tabledata, columnheaders);
      table.setPreferredScrollableViewportSize(new Dimension(500, 70));
      JScrollPane scrollPane = new JScrollPane(table);
 
      table.setIntercellSpacing(new Dimension (10,20));
  
      getContentPane().add(scrollPane);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
 
      pack();
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.show();
   }
}