Preventing the user from renaming files/directories in a JFileChooser

This is a hard task. I sat 3 hours to solve the problem for Jbuzzer. I do not know, if I solved the problem in a good way but it works.

Problem

The problem is, that deep inside of the UI of the JFileChooser – at the level of concrete implementation of the Look & Feel – the internal javax.swing.JList is instantiated without even keeping a member handle to it. It is done within a method that instantiates it, configures it (e.g.: with mouse listeners), adds it in a JPanel and returns that one.

The java jdk source code (1.4)

public class MetalFileChooserUI extends BasicFileChooserUI{
   private JPanel listViewPanel;
 
   public void installComponents(JFileChooser fc) {
      ...
      listViewPanel = createList(fc);
      ...
   }
 
   // A big don't: Hardcoded listeners 
   // in the UI implementation.
   protected JPanel createList(JFileChooser fc) {
      list = new JList() { <anonymous initialisation >};
      ...
      <b>list.addMouseListener(createSingleClickListener(fc,list));</b>
      ...
   }

   private MouseListener reateSingleClickListener(JFileChooser fc, JList list) 
   {
      return new SingleClickListener(list);
   }
 
   protected class SingleClickListener extends MouseAdapter {
      JList list;
      public void mouseClicked(MouseEvent e) {
         if (SwingUtilities.isLeftMouseButton(e)) {
            if (e.getClickCount() == 1) {
               JFileChooser fc = getFileChooser();
               int index = list.locationToIndex(e.getPoint());
               if ((!fc.isMultiSelectionEnabled() 
                   || fc.getSelectedFiles().length <= 1)
                   && index >= 0 
                   && list.isSelectedIndex(index)
                   && getEditIndex() == index 
                   && editFile == null) {
                      editFileName(index);
                   } 
               else {
                   ...
               }
            }

Solution

  1. Create your JFileChooser.

  • Run a search for it’s Component child of type JList.
  • Get the MouseListener of this JList whose class name contains “SingleClick” (I did not search other plaf packages: they might do the same bad thing but add the MouseListener for editing the JList in another way. This bugfix will only work for javax.swing.plaf.metal).
  • Remove that MouseListener from the retrieved JList.

    Code

    import javax.swing.JList;
    import java.awt.Component;
    import java.awt.Container;
    import javax.swing.JFileChooser;
    import java.awt.event.MouseListener;
     
    public class somename {
       ...
       /**
       * <p>
       * Hack to get the {@link List} of the {@link JFileChooser} 
       * instance used for loading sounds: 
       * We have to remove the "Single Click" listener 
       * that allows renaming files.
       * </p>
       */
       private JList searchJList(Container fileChooser)
       {
          JList ret = null;
          // First check, wether i am a JList:
          if (fileChooser instanceof JList){
              ret = (JList)fileChooser;
          }
          // Ok, me not: let's ask the children.
          else {
             Component[] children = fileChooser.getComponents();
             for(int i=children.length-1;i>=0;i--) {
                if (children[i] instanceof Container) {
                   ret = searchJList((Container)children[i]);
                   if(ret != null) {
                      break;
                   }
                }
             }
          }
    
          return ret;
       }
     
       // Just demo code! 
       public static void main(String[]args){
          JFileChooser load = new JFileChooser("/home/user/...");
          JList list = searchJList(this.openDialog);
          if (list!=null) {
             String listenerClassName;
             MouseListener[] listeners = list.getMouseListeners();
             for (int i=0;i< listeners.length;i++) {
                listenerCName = listeners[i].getClass().getName();
                if(listenerCName.indexOf("SingleClick")!= -1) {      
                   list.removeMouseListener(mouseListeners[i]);
                   break;
                }
             }
          }
          // Show the file chooser.
       }
    }
    

    Further examinations of other L&F packages could require changes. This has only be tested with javax.swing.plaf.metal.

    See the working example in Jbuzzer, a small fun-application for mapping sounds to keystrokes: http://sourceforge.net/projects/jbuzzer/.

  • Creating a JTable with fixed rows

    Courtesy of Nobuo Tamemasa (http://www2.gol.com/users/tame/swing/examples/JTableExamples6.html)



    FixedRowExample.java:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
    import javax.swing.event.*;
    
    /**
     * @version 1.0 03/05/99
     */
    public class FixedRowExample extends JFrame {
      Object[][] data;
      Object[] column;
      JTable fixedTable,table;
      private int FIXED_NUM = 2;
    
      public FixedRowExample() {
        super( "Fixed Row Example" );
        
        data =  new Object[][]{
            {      "a","","","","",""},
            {      "","b","","","",""},
            {      "","","c","","",""},
            {      "","","","d","",""},
            {      "","","","","e",""},
            {      "","","","","","f"},
            {"fixed1","","","","","","",""},
            {"fixed2","","","","","","",""}};
        column = new Object[]{"A","B","C","D","E","F"};
            
        AbstractTableModel    model = new AbstractTableModel() {
          public int getColumnCount() { return column.length; }
          public int getRowCount() { return data.length - FIXED_NUM; }
          public String getColumnName(int col) {
           return (String)column[col]; 
          }
          public Object getValueAt(int row, int col) { 
            return data[row][col]; 
          }
          public void setValueAt(Object obj, int row, int col) { 
            data[row][col] = obj; 
          }
          public boolean CellEditable(int row, int col) { 
            return true; 
          }
        };
        
        AbstractTableModel fixedModel = new AbstractTableModel() {      
          public int getColumnCount() { return column.length; }
          public int getRowCount() { return FIXED_NUM; }
          public Object getValueAt(int row, int col) { 
            return data[row + (data.length - FIXED_NUM)][col]; 
          }
        };
        
        table = new JTable( model );
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        
        fixedTable = new JTable( fixedModel );
        fixedTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        fixedTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        
        JScrollPane scroll      = new JScrollPane( table );
        scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    
        
        JScrollPane fixedScroll = new JScrollPane( fixedTable ) {
          public void setColumnHeaderView(Component view) {} // work around
        };                                                   //
                                                 // fixedScroll.setColumnHeader(null); 
        
        fixedScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        JScrollBar bar = fixedScroll.getVerticalScrollBar();
        JScrollBar dummyBar = new JScrollBar() {
          public void paint(Graphics g) {}
        };
        dummyBar.setPreferredSize(bar.getPreferredSize());
        fixedScroll.setVerticalScrollBar(dummyBar);
        
        final JScrollBar bar1 = scroll.getHorizontalScrollBar();
        JScrollBar bar2 = fixedScroll.getHorizontalScrollBar();
        bar2.addAdjustmentListener(new AdjustmentListener() {
          public void adjustmentValueChanged(AdjustmentEvent e) {
            bar1.setValue(e.getValue());
          }
        });
        
        
        scroll.setPreferredSize(new Dimension(400, 100));
        fixedScroll.setPreferredSize(new Dimension(400, 52));  // Hmm...
        getContentPane().add(     scroll, BorderLayout.CENTER);
        getContentPane().add(fixedScroll, BorderLayout.SOUTH);    
      }
    
      public static void main(String[] args) {
        FixedRowExample frame = new FixedRowExample();
        frame.addWindowListener( new WindowAdapter() {
          public void windowClosing( WindowEvent e ) {
            System.exit(0);
          }
        });
        frame.pack();
        frame.setVisible(true);
      }
    }
    

    Have a JButton cell in a JTable

    Courtesy of Nobuo Tamemasa (http://www2.gol.com/users/tame/swing/examples/JTableExamples1.html)



    JButtonTableExample.java:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
     
    /**
     * @version 1.0 11/09/98
     */
    public class JButtonTableExample extends JFrame {
     
      public JButtonTableExample(){
        super( "JButtonTable Example" );
        
        DefaultTableModel dm = new DefaultTableModel();
        dm.setDataVector(new Object[][]{{"button 1","foo"},
                                        {"button 2","bar"}},
                         new Object[]{"Button","String"});
                         
        JTable table = new JTable(dm);
        table.getColumn("Button").setCellRenderer(new ButtonRenderer());
        table.getColumn("Button").setCellEditor(new ButtonEditor(new JCheckBox()));
        JScrollPane scroll = new JScrollPane(table);
        getContentPane().add( scroll );
        setSize( 400, 100 );
        setVisible(true);
      }
     
      public static void main(String[] args) {
        JButtonTableExample frame = new JButtonTableExample();
        frame.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });
      }
    }
    

    ButtonRenderer.java:

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.table.*;
     
    /**
     * @version 1.0 11/09/98
     */
    public class ButtonRenderer extends JButton implements TableCellRenderer {
     
      public ButtonRenderer() {
        setOpaque(true);
      }
      
      public Component getTableCellRendererComponent(JTable table, Object value,
                       boolean isSelected, boolean hasFocus, int row, int column) {
        if (isSelected) {
          setForeground(table.getSelectionForeground());
          setBackground(table.getSelectionBackground());
        } else{
          setForeground(table.getForeground());
          setBackground(UIManager.getColor("Button.background"));
        }
        setText( (value ==null) ? "" : value.toString() );
        return this;
      }
    }
    

    ButtonEditor.java:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
     
    /**
     * @version 1.0 11/09/98
     */
    public class ButtonEditor extends DefaultCellEditor {
      protected JButton button;
      private String    label;
      private boolean   isPushed;
     
      public ButtonEditor(JCheckBox checkBox) {
        super(checkBox);
        button = new JButton();
        button.setOpaque(true);
        button.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            fireEditingStopped();
          }
        });
      }
     
      public Component getTableCellEditorComponent(JTable table, Object value,
                       boolean isSelected, int row, int column) {
        if (isSelected) {
          button.setForeground(table.getSelectionForeground());
          button.setBackground(table.getSelectionBackground());
        } else{
          button.setForeground(table.getForeground());
          button.setBackground(table.getBackground());
        }
        label = (value ==null) ? "" : value.toString();
        button.setText( label );
        isPushed = true;
        return button;
      }
     
      public Object getCellEditorValue() {
        if (isPushed)  {
          // 
          // 
          JOptionPane.showMessageDialog(button ,label + ": Ouch!");
          // System.out.println(label + ": Ouch!");
        }
        isPushed = false;
        return new String( label ) ;
      }
       
      public boolean stopCellEditing() {
        isPushed = false;
        return super.stopCellEditing();
      }
     
      protected void fireEditingStopped() {
        super.fireEditingStopped();
      }
    }
    

    Change the row height of a JTable that resides in a JFrame automatically when that frame is resized

    Maybe this code gives you some ideas.

    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" },
                { "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" };
     
          final JTable table = new JTable(tabledata, columnheaders);
          table.setPreferredScrollableViewportSize(new Dimension(500, 70));
          JScrollPane scrollPane = new JScrollPane(table);
     
          // initial height
          table.setRowHeight(20);
     
          getContentPane().setLayout(new BorderLayout());
          getContentPane().add(scrollPane);
     
          addComponentListener(new ComponentAdapter() {
             int oldHeight;
     
             public void componentResized(ComponentEvent e) {
                if (oldHeight > 0) {
                   int newRowHeight = ( table.getRowHeight() * getHeight() ) / oldHeight;
                   table.setRowHeight(newRowHeight);
                }
      
                oldHeight = getHeight();
             }
          });
     
          addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent we) {
                System.exit(0);
             }
          });
     
          pack();
       }
     
       public static void main(String []args) {
          Main main = new Main();
          main.show();
       }
    }

    Have dotted lines in a JTree

    That appends on your Look & Feel – you can use three lineStyle’s:

    // show hierarchy-lines
    JTree#putClientProperty(“JTree.lineStyle”, “Angled”);

    // show horizontal lines
    JTree#putClientProperty( “JTree.lineStyle”, “Horitontal” );

    // do not show any lines
    JTree#putClientProperty(“JTree.lineStyle”, “None”);

    Underlining a cell in a JTable

    The easiest way is to use HTML in your text, check How do I create a JLabel with the text underlined?

    But here’s a code sample that does not make use of the HTML feature. It underlines all Integers in the JTable whose values are between 1970 and 1980.

    Main.java:

    import javax.swing.table.*;
    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));
     
          UnderlineTableCellRenderer renderer = new UnderlineTableCellRenderer();
          table.setDefaultRenderer(Object.class, renderer);
          table.setRowHeight(30);
     
          JScrollPane scrollPane = new JScrollPane(table);
          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();
       }
    }
     
    class UnderlineTableCellRenderer extends DefaultTableCellRenderer 
    {
       public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                                                      boolean hasFocus, int row, int column) {
          if (value instanceof Integer) {
             Integer amount = (Integer) value;
             if (amount.intValue() > 1970 && amount.intValue() < 1980) {
                return new UnderlinedJLabel("" + amount.intValue());
             }
          }
     
          return super.getTableCellRendererComponent
                          (table, value, isSelected, hasFocus, row, column);
       }
    }
     
    class UnderlinedJLabel extends JLabel
    {
       public UnderlinedJLabel() {
       }
     
       public UnderlinedJLabel(Icon image) {
          super(image);
       }
     
       public UnderlinedJLabel(Icon image, int horizontalAlignment) {
          super(image, horizontalAlignment);
       }
     
       public UnderlinedJLabel(String text) {
          super(text);
       }
     
       public UnderlinedJLabel(String text, Icon icon, int horizontalAlignment) {
          super(text, icon, horizontalAlignment);
       }
     
       public UnderlinedJLabel(String text, int horizontalAlignment) {
          super(text, horizontalAlignment);
       }
     
       public void paint(Graphics g) {
          super.paint(g);
          underline(g);
       }
     
       protected void underline(Graphics g) {
          Insets insets = getInsets();
          FontMetrics fm = g.getFontMetrics();
          Rectangle textR = new Rectangle();
          Rectangle viewR = new Rectangle(
                                      insets.left, 
                                      insets.top, 
                                      getWidth() - (insets.right + insets.left), 
                                      getHeight() - (insets.bottom + insets.top));
      
          // compute and return location of the icons origin,
          // the location of the text baseline, and a possibly clipped
          // version of the compound label string.  Locations are computed 
          // relative to the viewR rectangle.
          String text = SwingUtilities.layoutCompoundLabel(
                             this,                        // this JLabel
                             fm,                          // current FontMetrics
                             getText(),                   // text
                             getIcon(),                   // icon
                             getVerticalAlignment(),      
                             getHorizontalAlignment(),
                             getVerticalTextPosition(),
                             getHorizontalTextPosition(), 
                             viewR,                       
                             new Rectangle(),             // don't care about icon rectangle
                             textR,                       // resulting text locations
                             getText() == null ? 0 : ((Integer)UIManager.get("Button.textIconGap")).intValue());
     
          // draw line
          int textShiftOffset = ((Integer) UIManager.get("Button.textShiftOffset")).intValue();
          g.fillRect(textR.x +
                     textShiftOffset - 4,
                     textR.y + fm.getAscent() + textShiftOffset + 2,
                     textR.width, 
                     1);
       }
    }
    

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

    Adding a menu bar to a JSplitPane

    Main.java:

     
    import javax.swing.plaf.basic.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.beans.*;
    import java.awt.*;
     
    public class Main extends JFrame
    {
       JSplitPane splitPane;
      
       public Main() {
          addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent we) {
                System.exit(0);
             }
          });
     
          splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, 
                                     new JPanel(), new JPanel());
          splitPane.setDividerSize(20);
      
          splitPane.setUI(new MenuDividerUI(getMainMenuBar()));
     
          getContentPane().add(splitPane);
     
          addComponentListener(new ComponentAdapter() {
             public void componentShown(ComponentEvent event) {
                splitPane.setDividerLocation(0.5);  
                    
                removeComponentListener(this);
             }
          });
       }
     
       public JMenuBar getMainMenuBar() {
          JMenuBar mainBar = new JMenuBar();
          JMenu menu = new JMenu("JSplitPane");
          JMenuItem item1 = new JMenuItem("HORIZONTAL_SPLIT");
          JMenuItem item2 = new JMenuItem("VERTICAL_SPLIT");
          menu.add(item1);
          menu.add(item2);
          mainBar.add(menu);
      
          item1.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent ae) {
                splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
             }
          });
     
          item2.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent ae) {
                splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
             }
          });
     
          return mainBar;
       }
     
       public static void main(String []args) {
          Main main = new Main();
          main.setSize(300, 300);
          main.setVisible(true);
       }
    }
     
    class MenuDividerUI extends BasicSplitPaneUI
    {
       protected JMenuBar menuBar;
     
       public MenuDividerUI(JMenuBar menuBar) {
          this.menuBar = menuBar;
       }
     
       public BasicSplitPaneDivider createDefaultDivider() {
          BasicSplitPaneDivider divider = new BasicSplitPaneDivider(this) {
             public int getDividerSize() { return menuBar.getPreferredSize().height; }
          };
          divider.setLayout(new BorderLayout());
          divider.add(BorderLayout.NORTH, menuBar);
     
          return divider;
       }
    }
    

    Programmatically closing a JInternalFrame

    Use this:

       frame.getDesktopPane().getDesktopManager().closeFrame(frame);
    

    Main.java:

    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;
       Action closeAction = new CloseAction();
     
       public Main() {
          desktop = new JDesktopPane(); 
          setContentPane(desktop);
          setJMenuBar(createMenuBar());
          createInternalFrame(); 
          addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent we) {
                System.exit(0);
             }
          });
       }
     
       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);
     
          internalFrameMenu = new JMenu("Close");
          internalFrameMenu.setMnemonic(KeyEvent.VK_C);
      
          menuBar.add(internalFrameMenu);     
     
          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) {}
     
          JMenuItem menuItem = new JMenuItem(title);
          internalFrameMenu.add(menuItem);
          menuItem.addActionListener(closeAction);
          frames.put(title, frame);
       }
     
       public static void main(String []args) {
          Main main = new Main();
          main.setSize(500, 300);
          main.setVisible(true);
       }
     
       public class CloseAction extends AbstractAction
       {
          public CloseAction() {
             super("Close Action");
          }
     
          public void actionPerformed(ActionEvent ae) {
             JMenuItem menuItem = ((JMenuItem) ae.getSource());
             JInternalFrame frame = (JInternalFrame) frames.get(menuItem.getText());
             // close the frame
             frame.getDesktopPane().getDesktopManager().closeFrame(frame);
             // remove JMenuItem from JMenu
             JMenu parent = (JMenu) ((JPopupMenu) menuItem.getParent()).getInvoker();
             parent.remove(menuItem);
          }
       }
    }
    

    Putting a JButton inside a JComboBox

    Here’s an example:

    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());
          
          final JButton buttonOk = new JButton("OK");
          buttonOk.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent ae) {
                System.out.println(ae.getActionCommand() + " clicked!");
             }
          });
          final JButton buttonCancel = new JButton("Cancel");
          buttonCancel.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent ae) {
                System.out.println(ae.getActionCommand() + " clicked!");
             }
          });
     
          final JComboBox combobox = 
             new JComboBox(new Object[] {
                   "Item 1",
                   "Item 2",
                   "Item 3",
                   buttonOk,
                   "Item 4",
                   "Item 5",
                   buttonCancel
                }
             );
     
          getContentPane().add(combobox);
          combobox.setRenderer(new ButtonComboBoxRenderer());
          combobox.addActionListener(new ButtonComboBoxListener(this, 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 ButtonComboBoxRenderer extends BasicComboBoxRenderer implements ListCellRenderer
    {
       public ButtonComboBoxRenderer() {
          super();
       }
       
       public Component getListCellRendererComponent( JList list, 
               Object value, int index, boolean isSelected, boolean cellHasFocus) {
          if (isSelected) {
              setBackground(list.getSelectionBackground());
              setForeground(list.getSelectionForeground());
          }
          else {
              setBackground(list.getBackground());
              setForeground(list.getForeground());
          }
     
          setFont(list.getFont());
          if (value instanceof Icon) {
             setIcon((Icon)value);
          }
          if (value instanceof JButton) {
             return (Component) value;
          }
          else {
             setText((value == null) ? "" : value.toString());
          }
     
          return this;
      }  
    }
     
    class ButtonComboBoxListener implements ActionListener {
       JComboBox combobox;
       JFrame frame;
     
       ButtonComboBoxListener(JFrame frame, JComboBox combobox) {
          this.frame = frame;
          this.combobox = combobox;
          combobox.setSelectedIndex(0);
       }
         
       public void actionPerformed(ActionEvent e) {
          Object selectedItem = combobox.getSelectedItem();
          if (selectedItem instanceof JButton) {
             ((JButton) selectedItem).doClick();
          }
       }
    }