Ciao a tutti mi è venuta la voglia di implementare una serie di bottoni con popup allora ho esteso la classe JToggleButton
codice:
public class ButtonPopup extends JToggleButton{
private JPopupMenu PopupMenu;
private boolean show = false;
public ButtonPopup(String Text){
this(Text,null,null);
}
public ButtonPopup(String Text, String Tooltip, Icon ico){
super();
setBorderPainted(false);
setFocusable(false);
if(ico!=null) this.setIcon(ico);
if(Tooltip!=null && !Tooltip.equals("")) this.setToolTipText(Tooltip);
if(Text!=null && !Text.equals("")) this.setText(Text);
PopupMenu = new JPopupMenu();
this.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent ie) {
if(show){
if(ie.getStateChange()==ItemEvent.SELECTED){
JToggleButton B = (JToggleButton)ie.getSource();
Rectangle a = B.getBounds();
PopupMenu.show(B,0,a.height);
}
else
PopupMenu.setVisible(false);
}
};
});
PopupMenu.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
deselect();
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
deselect();
}
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
}
});
}
private void deselect() {
this.setSelected(false);
}
public void addItemMenu(Component a){
PopupMenu.add(a);
show = true;
}
public void deleteItemMenu(int i){
PopupMenu.remove(i);
if(PopupMenu.getComponentCount()==0)
show = false;
}
}
e ho scritto il mio codice personalizzato che va più che bene
codice:
private void populateToolbar(){
ButtonPopup Views = new ButtonPopup("", "Views", new ImageIcon("icons\\decks\\views.png"));
JMenuItem Views_top = new JMenuItem("Top"); Views.addItemMenu(Views_top);
JMenuItem Views_front = new JMenuItem("Front"); Views.addItemMenu(Views_front);
JMenuItem Views_left = new JMenuItem("Left"); Views.addItemMenu(Views_left);
ButtonPopup Decks = new ButtonPopup("", "Decks", new ImageIcon("icons\\decks\\decks.png"));
JMenuItem Decks_add = new JMenuItem("Add"); Decks.addItemMenu(Decks_add);
Decks_add.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
s.setAction(s.ADD_DECK);
}
});
JMenuItem Decks_delete = new JMenuItem("Delete"); Decks.addItemMenu(Decks_delete);
ButtonPopup Bulkheads = new ButtonPopup("", "Decks", new ImageIcon("icons\\decks\\bulkheads.png"));
JMenuItem Bulkheads_add = new JMenuItem("Add"); Bulkheads.addItemMenu(Bulkheads_add);
JMenuItem Bulkheads_delete = new JMenuItem("Delete"); Bulkheads.addItemMenu(Bulkheads_delete);
ToolBar.add(Views);
ToolBar.add(Decks);
ToolBar.add(Bulkheads);
}
Ma ci sono due problemi: intanto quando clicco su un'altro bottone ed un popup è aperto il click serve per chiuderlo e solo con un'altro click si può aprire il menu (poco grave)
Il secondo è che quando clicco su una voce di menu mi ritrovo la seguente eccezione
codice:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.JPopupMenu.setVisible(JPopupMenu.java:737)
at javax.swing.JPopupMenu.menuSelectionChanged(JPopupMenu.java:1421)
at javax.swing.MenuSelectionManager.setSelectedPath(MenuSelectionManager.java:94)
at javax.swing.MenuSelectionManager.clearSelectedPath(MenuSelectionManager.java:126)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:808)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:850)
at java.awt.Component.processMouseEvent(Component.java:6290)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6055)
at java.awt.Container.processEvent(Container.java:2039)
at java.awt.Component.dispatchEventImpl(Component.java:4653)
at java.awt.Container.dispatchEventImpl(Container.java:2097)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4575)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4236)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4166)
at java.awt.Container.dispatchEventImpl(Container.java:2083)
at java.awt.Window.dispatchEventImpl(Window.java:2482)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:648)
at java.awt.EventQueue.access$000(EventQueue.java:84)
at java.awt.EventQueue$1.run(EventQueue.java:607)
at java.awt.EventQueue$1.run(EventQueue.java:605)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:621)
at java.awt.EventQueue$2.run(EventQueue.java:619)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:618)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Come risolvere?