Implementing a dynamic Scrollable JPopupMenu

Hi,

I wanna make a scrollable JPopupMenu. What I am looking for is I am making a custom popup Menu which extends JPopupMenu. I would be overriding the add method.

I dont want to add a list or a combo box to my JPopupMenu. I want to change the layout itself .. i.e. there is a function in the Container.class which gets called when we try to add a menuitem dynamically to the JPopupMenu

Function Name:

protectedvoid addImpl(Component comp, Object constraints,int index)

Snippet which i am looking in the function

if (layoutMgrinstanceof LayoutManager2){

((LayoutManager2)layoutMgr).addLayoutComponent(comp, constraints);

}

Is there a way while addiing menu items dynamically that I can set the layout to scrollable and hence the menuitems when added are in a scrollpane automatically.. Hence I what i get also is a Scrollable JPopupMenu

[1117 byte] By [hemanthjavaa] at [2007-11-26 16:10:30]
# 1

well, this is implementation of PopupMenu with scroll

import java.awt.Component;

import java.awt.Dimension;

import java.awt.GraphicsConfiguration;

import java.awt.GridLayout;

import javax.swing.JButton;

import javax.swing.JPanel;

import javax.swing.JPopupMenu;

import javax.swing.JScrollPane;

import javax.swing.JSeparator;

public class ScrollPopupMenu extends JPopupMenu {

private static final long serialVersionUID = 1;

private JPanel panelMenus = null;

private JScrollPane scroll = null;

public ScrollPopupMenu(GraphicsConfiguration gc) {

super();

scroll = new JScrollPane();

panelMenus = new JPanel();

panelMenus.setLayout(new GridLayout(0,1));

scroll.setViewportView(panelMenus);

scroll.setBorder(null);

scroll.setMaximumSize(new Dimension(scroll.getMaximumSize().width,

this.getToolkit().getScreenSize().height -

this.getToolkit().getScreenInsets(gc).top -

this.getToolkit().getScreenInsets(gc).bottom - 4));

super.add(scroll);

}

public void show(Component invoker, int x, int y) {

this.pack();

panelMenus.validate();

int maxsize = scroll.getMaximumSize().height;

int realsize = panelMenus.getPreferredSize().height;

int sizescroll = 0;

if (maxsize < realsize) {

sizescroll = scroll.getVerticalScrollBar().getPreferredSize().width;

}

scroll.setPreferredSize(new Dimension(

scroll.getPreferredSize().width + sizescroll,

scroll.getPreferredSize().height));

super.show(invoker, x, y);

}

public void add(JButton menuItem) {

panelMenus.add(menuItem);

}

public void addSeparator() {

panelMenus.add(new JSeparator());

}

}

It is very basic, but this to help you, If you want to test, you compile this class:

import javax.swing.SwingUtilities;

import javax.swing.JPanel;

import javax.swing.JFrame;

import java.awt.FlowLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JTextField;

import javax.swing.JLabel;

public class FramePopupMenu extends JFrame {

private static final long serialVersionUID = 1;

private JPanel jContentPane = null;

private JButton btnPopup = null;

private JTextField txtNumElem = null;

private JLabel lblNumElem = null;

private JButton getBtnPopup() {

if (btnPopup == null) {

btnPopup = new JButton();

btnPopup.setText("Ver men?popup");

btnPopup.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

ScrollPopupMenu mnu = new ScrollPopupMenu(FramePopupMenu.this.getGraphicsConfiguration());

int n = Integer.parseInt(getTxtNumElem().getText());

for (int i=0;i<n;i++)

mnu.add(new JButton("Men?" + (i+1)));

mnu.show(btnPopup, btnPopup.getWidth(), 0);

}

});

}

return btnPopup;

}

private JTextField getTxtNumElem() {

if (txtNumElem == null) {

txtNumElem = new JTextField();

txtNumElem.setColumns(3);

txtNumElem.setText("60");

}

return txtNumElem;

}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

FramePopupMenu thisClass = new FramePopupMenu();

thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

thisClass.setVisible(true);

}

});

}

public FramePopupMenu() {

super();

initialize();

}

private void initialize() {

this.setSize(274, 109);

this.setContentPane(getJContentPane());

this.setTitle("Scroll en un men?popup");

}

private JPanel getJContentPane() {

if (jContentPane == null) {

lblNumElem = new JLabel();

lblNumElem.setText("N鷐ero de elementos del Men?);

FlowLayout flowLayout = new FlowLayout();

flowLayout.setHgap(8);

flowLayout.setVgap(8);

jContentPane = new JPanel();

jContentPane.setLayout(flowLayout);

jContentPane.add(getBtnPopup(), null);

jContentPane.add(lblNumElem, null);

jContentPane.add(getTxtNumElem(), null);

}

return jContentPane;

}

}

>

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

Thanks for the Solution. This was great. But indeeed I tried this code as shown by you above and It does not work when i try to add JMenuItems.

I have added

public JMenuItem add(JMenuItem menuItem) {

panelMenus.add(menuItem);

return menuItem;

}

When I run the program, The popup menu appears with the JMenuItems, but when i move the mouse the popup menu dissapers. How do i solve the dissapearing Popupmenu probelm.

Message was edited by:

hemanthjava

hemanthjavaa at 2007-7-8 22:32:55 > top of Java-index,Desktop,Core GUI APIs...
# 3
The complete Scrollable JPopupMenu program is present in:[url] http://www.beginner-java-tutorial.com/scrollable-jpopupmenu.html[/url]
hemanthjavaa at 2007-7-8 22:32:55 > top of Java-index,Desktop,Core GUI APIs...