Detecting what version of Swing is installed

One way to find out is to look at the UIDefaults key/value pairs to see what new keys have been introduced in what version.

Here’s an example, test it thouroughly. If anyone knows a better way, comment it here!

GetSwingVersion.java:

import java.lang.reflect.*;
import java.util.*;
 
public class GetSwingVersion
{
   public static void main(String []args) {
      boolean found = false;
 
      try {
         Class.forName("javax.swing.JButton");
 
         Class manager = Class.forName("javax.swing.UIManager");
         try {
            Method m = manager.getDeclaredMethod("getDefaults", new Class[] { });
            Object defaults = m.invoke(null, new Object[] { });
 
            Method qd = defaults.getClass().getMethod("getString", new Class[] { Object.class });
            Object str = qd.invoke(defaults, new Object[] { "FormattedTextFieldUI" });
            if (str != null) {
               System.out.println("Swing version 1.1.1 JDK1.4 found!");
            }
            else {
               Object str2 = qd.invoke(defaults, new Object[] { "RootPaneUI" });
               if (str2 != null) {
                  System.out.println("Swing version 1.1.1 JDK1.3 found!");
               }
               else {
                  System.out.println("Swing version 1.1.1 JDK1.2.2 found!");
               }
            }
         }
         catch(NoSuchMethodException e) {
         }
         catch(IllegalAccessException e) {
         }
         catch(InvocationTargetException e) {
         }
  
         found = true;
      }
      catch(NoClassDefFoundError e) {
      }
      catch(ClassNotFoundException e) {
      }
 
      if (!found) {  
         try {
            Class.forName("com.sun.java.swing.JButton");
            System.out.println("Swing v1.0.3 found!");
            found = true;
         } 
         catch(NoClassDefFoundError e) {
         }
         catch(ClassNotFoundException e) {
         }
      }   
 
      if (!found) {
         System.out.println("no version of Swing found!");
      }
 
      System.exit(1);
   }
}

Setting the top-left icon in a JFrame

setIconImage (inherited method from java.awt.Frame) does the job!

 
import javax.swing.*;
import java.awt.*;
   
public class IconFrame extends JFrame {
 
   public IconFrame() {
      setSize(100, 100);

      setIconImage(new ImageIcon("test.gif").getImage());
   }
 
   public static void main(String args[]) {
      new IconFrame().setVisible(true);     
   }
}

Making the scrolling in JScrollPane faster

A new feature has been implemented in Swing 1.1.1 that makes scrolling faster in most cases. The idea is to only update the exposed viewport (the visible region) when scrolling. To enable this, set the property EnableWindowBlit to true.

   scrollpane.getViewport().putClientProperty("EnableWindowBlit", Boolean.TRUE);

Placing an image in a tab of a JTabbedPane

Look at the addTab possibilities in the Javadoc documentation!

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.net.*;
 
public class Main extends JFrame implements ActionListener {
   JTabbedPane tabbedPane;
   int ntabs = 0;
 
   public Main() {
      getContentPane().setLayout(new BorderLayout());
      tabbedPane = new JTabbedPane();
      createTab("TrafficGreen.gif");
      createTab("TrafficRed.gif");
 
      getContentPane().add(BorderLayout.CENTER, tabbedPane);
      setJMenuBar(createMenuBar());
  
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
   
      setTitle("JTabbedPane Orientation Demonstration");
      setSize(new Dimension(400, 400));
   }
 
   protected JMenuBar createMenuBar() {
      JMenuBar menuBar = new JMenuBar();
 
      JMenu menu1 = new JMenu("Change orientation");
      JMenuItem menuItem1 = new JMenuItem("TOP");
      menuItem1.addActionListener(this);
      menu1.add(menuItem1);
      JMenuItem menuItem2 = new JMenuItem("BOTTOM");
      menuItem2.addActionListener(this);
      menu1.add(menuItem2);
      JMenuItem menuItem3 = new JMenuItem("LEFT");
      menuItem3.addActionListener(this);
      menu1.add(menuItem3);
      JMenuItem menuItem4 = new JMenuItem("RIGHT");
      menuItem4.addActionListener(this);
      menu1.add(menuItem4);
      menuBar.add(menu1);
 
      return menuBar;
   }
  
   public void actionPerformed(ActionEvent e) {
      if (e.getActionCommand().equals("TOP")) {
         tabbedPane.setTabPlacement(JTabbedPane.TOP);
      }
      else if (e.getActionCommand().equals("BOTTOM")) {
         tabbedPane.setTabPlacement(JTabbedPane.BOTTOM);
      }
      else if (e.getActionCommand().equals("LEFT")) {
         tabbedPane.setTabPlacement(JTabbedPane.LEFT);
      }
      else if (e.getActionCommand().equals("RIGHT")) {
         tabbedPane.setTabPlacement(JTabbedPane.RIGHT);
      }
   }
 
   protected void createTab(String imagefile) {
      ntabs++;
      tabbedPane.addTab("Tab #" + ntabs, new ImageIcon(imagefile), new JLabel("Tab #" + ntabs));
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.show();
   }
}

Images used:

More than one JToolBar

Main.java:

import javax.swing.border.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame
{
   public Main()
   {
      JToolBar toolBar1 = new JToolBar();
      JButton gifButton = new JButton("GIF");
      JButton jpgButton = new JButton("JPG");
      JButton tiffButton = new JButton("TIFF");
      toolBar1.add(gifButton);
      toolBar1.add(jpgButton);
      toolBar1.add(tiffButton);
 
      JToolBar toolBar2 = new JToolBar();
      JButton openButton = new JButton("Open");
      JButton saveButton = new JButton("Save");
      JButton exitButton = new JButton("Exit");
      toolBar2.add(openButton);
      toolBar2.add(saveButton);
      toolBar2.add(exitButton);
 
      getContentPane().setLayout(new BorderLayout());
      toolBar1.setBorder(new CompoundBorder(new LineBorder(Color.black),
                                            new EmptyBorder(10, 10, 10, 10)));
      toolBar2.setBorder(new CompoundBorder(new LineBorder(Color.black),
                                            new EmptyBorder(10, 10, 10, 10)));
 
      JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER));
      panel.add(toolBar1);
      panel.add(toolBar2);
 
      getContentPane().add(BorderLayout.NORTH, panel);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
   }
      
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   }
}

Programmatically maximizing a JInternalFrame

Call setMaximum(true) on your JInternalFrame instance. Or call the method maximizeFrame of the DestopManager providing it with the instance of the JInternalFrame to be maximized. Here’s an example:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.net.*;
 
public class Main extends JFrame implements ActionListener {
   JDesktopPane desktop;
   JInternalFrame frame;
 
   public Main() {
      setTitle("JInternalFrame Actions");
      desktop = new JDesktopPane(); 
      createInternalFrame(); 
      setContentPane(desktop);
      setJMenuBar(createMenuBar());
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
 
      setSize(500, 400);
   }
 
   protected JMenuBar createMenuBar() {
      JMenuBar menuBar = new JMenuBar();
 
      JMenu menu = new JMenu("JInternalFrame Actions");
      JMenuItem menuItem = new JMenuItem("Maximize");
      menuItem.addActionListener(this);
      menu.add(menuItem);
      menuBar.add(menu);
 
      return menuBar;
   }
 
   public void actionPerformed(ActionEvent ae) {
      if (ae.getActionCommand().equals("Maximize")) {
 
         desktop.getDesktopManager().maximizeFrame(frame);
 
         /* OR:
 
         try {
            frame.setMaximum(true);
         } 
         catch(java.beans.PropertyVetoException e) {
         }
 
         */
         
      }
   }
 
   protected void createInternalFrame() {
      frame = new JInternalFrame("InternalFrame", 
         true,    // resizable
         true,    // closable
         true,    // maximizable
         true);   // iconifiable
      frame.setVisible(true); 
      desktop.add(frame);
      frame.setSize(200, 200);
      frame.setLocation(30, 30);
      try {
         frame.setSelected(true);
      } catch (java.beans.PropertyVetoException e) {}
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setVisible(true);
   }
}

Changing the setMnemonic behavior of JButton so that it responds to CTRL instead of ALT

Try this workaround!

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
   
public class Main extends JFrame {
   JList list; 
 
   public Main() {
      getContentPane().setLayout(new FlowLayout());
 
      final JButton button = new JButton("Click-Me!");
 
      ActionListener al = new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            System.out.println("Button was clicked!");
         }
      };
      button.addActionListener(al);
  
      // don't use button.setMnemonic('C') if you want only the CTRL mask to work,
      // use button.getModel() instead. 
      button.getModel().setMnemonic('C');
      KeyStroke keyStroke = KeyStroke.getKeyStroke('C', Event.CTRL_MASK, false); 
      button.registerKeyboardAction(al, keyStroke, JComponent.WHEN_FOCUSED); 
      
      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();
   }
}

Defining the size of a JComboBox

If you want to change the size of the JComboBox component itself, use:

   combobox.setPreferredSize(new Dimension(x, y));

If you want to have control over the popupwidth and popupheight, extend JComboBox and add the necessary functionality to a custom ComboBoxUI:
Main.java:

import javax.swing.plaf.metal.*;
import javax.swing.plaf.basic.*;
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<20; i++)
         v.addElement("ComboBox Item #" + i);
      SizedJComboBox combobox = new SizedJComboBox(v);
 
      combobox.setPopupWidth(190);
      combobox.setPopupHeight(30);
 
      getContentPane().add(combobox);
  
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });      
   
      setSize(new Dimension(200, 200));
   } 
 
   public static void main(String[] args) throws Exception {
      Main main = new Main();
      main.setVisible(true);
   }
}
 
class SizedJComboBox extends JComboBox {
   protected int popupWidth;
   protected int popupHeight;
 
   public SizedJComboBox(ComboBoxModel aModel) {
      super(aModel);
      setUI(new SizedComboBoxUI());
   }
 
   public SizedJComboBox(final Object[] items) { 
      super(items); 
      setUI(new SizedComboBoxUI());
   } 
 
   public SizedJComboBox(Vector items) { 
      super(items); 
      setUI(new SizedComboBoxUI()); 
   } 
 
   public void setPopupWidth(int width) { 
      popupWidth = width; 
   }
 
   public void setPopupHeight(int height) {
      popupHeight = height;
   } 
 
   public Dimension getPopupSize() { 
      Dimension size = getSize(); 
      if (popupWidth < 1) popupWidth = size.width; 
      return new Dimension(popupWidth, popupHeight); 
   } 
}
 
class SizedComboBoxUI extends MetalComboBoxUI {
   protected ComboPopup createPopup() { 
      BasicComboPopup popup = new BasicComboPopup(comboBox) { 
         public void show() { 
            Dimension popupSize = ((SizedJComboBox) comboBox).getPopupSize(); 
            popupSize.setSize(popupSize.width, popupSize.height < 1 ? getPopupHeightForRowCount(comboBox.getMaximumRowCount()) : popupSize.height); 
            Rectangle popupBounds = computePopupBounds( 0, 
                  comboBox.getBounds().height, popupSize.width, popupSize.height); 
            scroller.setMaximumSize(popupBounds.getSize()); 
            scroller.setPreferredSize(popupBounds.getSize()); 
            scroller.setMinimumSize(popupBounds.getSize()); 
            list.invalidate(); 
            int selectedIndex = comboBox.getSelectedIndex(); 
            if (selectedIndex == -1) { 
               list.clearSelection(); 
            } else { 
               list.setSelectedIndex( selectedIndex ); 
            } 
            list.ensureIndexIsVisible( list.getSelectedIndex() ); 
            setLightWeightPopupEnabled(comboBox.isLightWeightPopupEnabled()); 
 
            show(comboBox, popupBounds.x, popupBounds.y); 
         } 
      }; 
 
      popup.getAccessibleContext().setAccessibleParent(comboBox); 
      return popup; 
   } 
} 

Detecting a double-click on an element in a JList

For detecting double-clicking, add a MouseListener and catch the MouseEvents where clickCount is equal to 2.

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);
      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()); 
            }
         }
      });
 
      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();
   }
}

Changing the font of a JMenuItem

You can either embed HTML in the JMenuItem’s text, or you can call the method setFont.

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
   
public class Main extends JFrame {
   public Main() {
      getContentPane().setLayout(new FlowLayout());
 
      JMenuBar menuBar = new JMenuBar();
      JMenu menu = new JMenu("Sex");
      JMenuItem menuItem1 = new JMenuItem("<html><font size=-1>male</font></html>");
      JMenuItem menuItem2 = new JMenuItem("<html><font size=+1>female</font></html>");
      JMenuItem menuItem3 = new JMenuItem("androgyne");
      menuItem3.setFont(new Font("Monospaced", Font.ITALIC, 36));
 
      // add the MenuItems to the Menu 
      menu.add(menuItem1);
      menu.add(menuItem2);
      menu.add(menuItem3);
 
      menuBar.add(menu);
 
      this.setJMenuBar(menuBar); 
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      setSize(400, 400);
   }
 
   public static void main(String[] args) {
      (new Main()).show();
   }
}