JComboBox/JMenu problem

My app lists files in a directory and then adds these files into a combo box model. The combo box itself is placed inside a JMenu.

There are also two other items in the menu, 1) To add a file, 2) To remove a file. Both of these uses JFileChooser抯 and both update the combo box, via the model.

The app seems to work fine. No exception is thrown running under 1.6, but under 1.4, the following is displayed:

java.lang.NullPointerException

at javax.swing.plaf.basic.BasicPopupMenuUI$MouseGrabber.grabContainer(BasicPopupMenuUI.java:383)

at javax.swing.plaf.basic.BasicPopupMenuUI$MouseGrabber.requestAddGrab(BasicPopupMenuUI.java:267)

at javax.swing.plaf.basic.BasicPopupMenuUI$MouseGrabber.stateChanged(BasicPopupMenuUI.java:323)

at javax.swing.MenuSelectionManager.fireStateChanged(MenuSelectionManager.java:161)

at javax.swing.MenuSelectionManager.setSelectedPath(MenuSelectionManager.java:87)

at javax.swing.JPopupMenu.setVisible(JPopupMenu.java:751)

at javax.swing.JPopupMenu.show(JPopupMenu.java:927)

at javax.swing.plaf.basic.BasicComboPopup.show(BasicComboPopup.java:177)

at javax.swing.plaf.basic.BasicComboPopup.togglePopup(BasicComboPopup.java:982)

at javax.swing.plaf.basic.BasicComboPopup$InvocationMouseHandler.mousePressed(BasicComboPopup.java:632)

at java.awt.Component.processMouseEvent(Component.java:5097)

at java.awt.Component.processEvent(Component.java:4897)

at java.awt.Container.processEvent(Container.java:1569)

at java.awt.Component.dispatchEventImpl(Component.java:3615)

at java.awt.Container.dispatchEventImpl(Container.java:1627)

at java.awt.Component.dispatchEvent(Component.java:3477)

at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3483)

at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3195)

at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3128)

at java.awt.Container.dispatchEventImpl(Container.java:1613)

at java.awt.Window.dispatchEventImpl(Window.java:1606)

at java.awt.Component.dispatchEvent(Component.java:3477)

at java.awt.EventQueue.dispatchEvent(EventQueue.java:456)

at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:201)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:145)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:137)

at java.awt.EventDispatchThread.run(EventDispatchThread.java:100)

I don抰 know if this will help, 1.4 is not used anymore, still the problem remains.

When the combo box is clicked, it should write to the console:

fav.addActionListener(new AbstractAction(){

public void actionPerformed(ActionEvent e)

{

System.out.println("Combo action");

/*// Copy to pl

((TrackList)favMod.getSelectedItem()).copyTo(plTrList);

// Make the pl outer

player.setOuterList(plTrList);

// Player from outer

player.setFromPlayer(false);

// Play

player.play();*/

}

});

Were 慺av?is the JComboBox.

But the action isn抰 called. Nor does the drop down list appear when the little arrow clicked. I have tried this app on 2 computers, and they both have the same problem.

Any help will be grand.

Luke

[3457 byte] By [dfgstga] at [2007-11-26 14:28:33]
# 1

If you need further help then you need to create a [url http://homepage1.nifty.com/algafield/sscce.html]Short, Self Contained, Compilable and Executable, Example Program[/url] (SSCCE) that demonstrates the incorrect behaviour, because I can't guess exactly what you are doing based on the information provided.

And don't forget to use the [url http://forum.java.sun.com/help.jspa?sec=formatting]Code Formatting Tags[/url] so the code retains its original formatting.

camickra at 2007-7-8 2:22:41 > top of Java-index,Desktop,Core GUI APIs...
# 2

package hmc.it.model.table.filter.view;

import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JComboBox;

import javax.swing.JFrame;

import javax.swing.JPopupMenu;

/**

* This example demonstrates a NullPointer exception that occurs

* when a JComboBox is added as a Component to a JPopupMenu and

* then the combo box gets expanded to select another item.

*

* To see it in action, just compile and run this class. It is self-

* contained.

*

* Once it is started, click on the button to bring up the popup,

* then try to open the combo box. You'll get the following stack

* trace:

*

* java.lang.NullPointerException

* at javax.swing.plaf.basic.BasicPopupMenuUI$MouseGrabber.grabContainer(BasicPopupMenuUI.java:383)

* ....

*

* @author Vadim Yarovoy (vyarovoy@veripath.us)

* @date Jan, 10, 2007

*/

public class JComboBoxInJPopupMenuNullPointerExample {

/**

* @param args

*/

public static void main( String[] args ) {

//create frame

JFrame f = new JFrame();

f.setSize( 100, 100 );

f.setLocation( 500, 300 );

f.setTitle( "NullPointer example" );

//create button

JButton b = new JButton( "Click me" );

b.addActionListener( new ActionListener() {

public void actionPerformed( ActionEvent ev ) {

//create popup

JPopupMenu pm = new JPopupMenu();

//create the combo

JComboBox cb = new JComboBox(

new Object[] { "Open me", "Item 1", "Item 2", "Item 3" } );

//add cb to pm

pm.add( cb );

pm.show( (JButton)ev.getSource(), 10, 10 );

}

});

//add button to the frame

f.getContentPane().add( b, BorderLayout.CENTER );

f.show();

}

}

vyarovoya at 2007-7-8 2:22:41 > top of Java-index,Desktop,Core GUI APIs...
# 3

Well, I'm guessing its because when you click on the combo box another popup menu appears and the original popup is closed which is causing the problem. I don't know the solution.

However, I would suggest that instead of adding a combo box to the popup you could just add a menu item and multiple sub menu items. The code is already in place to support this type of multiple popup.

Other than that you will need to build your own popup, as follows:

JComboBox cb = new JComboBox(new Object[] { "Open me", "Item 1", "Item 2", "Item 3" } );

PopupFactory factory = PopupFactory.getSharedInstance();

Popup popup = factory.getPopup(this, cb, getLocation().x, getLocation().y);

popup.show();

Window window = SwingUtilities.windowForComponent(cb);

if (window != null)

{

window.setFocusableWindowState(true);

}

KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent(cb);

But now you are resonsible for closing the popup when it loses focus or an item has been selected.

camickra at 2007-7-8 2:22:41 > top of Java-index,Desktop,Core GUI APIs...
# 4

Thanks for that, to tell you the truth I didn抰 really have any idea what the problem was. But now I see how two popup menus on top of each other could be a problem.

The reason I thought about using combo boxes was that I wanted he menu items to change dynamically.

I have found a way to use menu items and a HashMap to perform the same sort of behaviour.

Thanks again, and please feel free to play about with my little tester app.

import java.util.*;

import java.awt.event.*;

import javax.swing.*;

public class MenuBarTester extends JFrame

{

// The model to link the buttons on the favourites with there data object

private HashMap favMod = new HashMap();

// All the data objects to add at the start

private String[] data = new String[]{

"The","Cat","Sat","On","The","Mat"

};

// The menus

private JMenu menFav = new JMenu("Favourites");

private JMenuBar menuBar = new JMenuBar();

// Main

public static void main(String[] args)

{ new MenuBarTester(); }

public MenuBarTester()

{

// Set all the favourites in the fav menu

setFavs(data);

// Add

menuBar.add(menFav);

// Show frame

try

{

// Set look and feel to systems, might as well

UIManager.setLookAndFeel(

UIManager.getSystemLookAndFeelClassName());

} catch (Exception ex) {}

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.setSize(100,100);

this.setJMenuBar(menuBar);

this.setVisible(true);

}

public void setFavs(Object[] inFavs)

{

// Remove all

favMod.clear();

for (int i=0;i<inFavs.length;i++)

{

System.out.println(i+" is "+inFavs[i]);

// Make a new button

JMenuItem favItem = new JMenuItem(inFavs[i].toString());

// This button now links to the TrackList in pos i

favMod.put(favItem,inFavs[i]);

// Add the action adapter

favItem.addActionListener(new FavItemActionAdapter());

// Add it to the menu

menFav.add(favItem);

}

}

private class FavItemActionAdapter implements ActionListener

{

public void actionPerformed(ActionEvent e)

{

// Get the source

Object bottom=e.getSource();

System.out.println("This button is linked to "+

favMod.get(bottom));

}

}

}

>

dfgstga at 2007-7-8 2:22:41 > top of Java-index,Desktop,Core GUI APIs...