/*http://forum.java.sun.com/thread.jsp?forum=57&thread=123183
Re: scrollable JMenu?
Author: frankm29
In Reply To: scrollable JMenu? Apr 30, 2002 6:35 PM Reply 4 of 5
Here's a cl*** I made to make JMenu scrollable, use it if it can help you...Frank
*/import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;// This cl*** implements a scrollable JMenu
// This cl*** was hacked out in a couple of hours, and is meant to be used
// such that you create an instance, add all the items you want, and then throw it away and
// create a new one if you want the menu items to change (there is no remove/insertAt functionality)
// Use "addScrollableItems(JMenuItem j)" to add all of the items
// You can change MAX_ITEMS_TO_DISPLAY to whatever you want, I used 10 because it seems to always fit on screen
// I have NOT tested this cl*** very much to see if it loses items, etc, ***USE AT YOUR OWN RISK***
// Feel free to use and modify. I'll probably add a thread on the up & down scrollers to make them scroll automatically (as long as mouse-over),
// let me know if you want it via email ([email protected]).
//
// This cl*** should only be used until SUN makes a real scrollable JMenupublic cl*** ScrollableJMenu extends JMenu implements MouseListener{
ScrollUpOrDownButtonItem scrollUp, scrollDown;
Vector vtrScrollableMenuItems;
static final int MAX_ITEMS_TO_DISPLAY = 10;
int beginIndexIntoVector;public ScrollableJMenu(String strMenuTitle){
setText(strMenuTitle);scrollUp = new ScrollUpOrDownButtonItem("up");
add(scrollUp);
removeAllMouseListeners(scrollUp);
scrollUp.addMouseListener(this);
scrollUp.addMouseListener(scrollUp);scrollDown = new ScrollUpOrDownButtonItem("down");
add(scrollDown);
removeAllMouseListeners(scrollDown);
scrollDown.addMouseListener(this);
scrollDown.addMouseListener(scrollDown);vtrScrollableMenuItems = new Vector();
beginIndexIntoVector = 0;
}public void addScrollableItem(JMenuItem jmiMenuItemToAdd){
vtrScrollableMenuItems.addElement(jmiMenuItemToAdd);
if ( vtrScrollableMenuItems.size() <= MAX_ITEMS_TO_DISPLAY){
insert(jmiMenuItemToAdd, vtrScrollableMenuItems.size());
}
else{
scrollDown.enableScroll(true);
}
}public void removeAllMouseListeners(AbstractButton b){
MouseListener[] allMouseListeners = b.getMouseListeners();
for (int i = 0; i < allMouseListeners.length; i++){
b.removeMouseListener(allMouseListeners);
}
}public void scrollUpClicked(){
if ( (vtrScrollableMenuItems.size() <= MAX_ITEMS_TO_DISPLAY) || (beginIndexIntoVector == 0) ){ // no need to scroll
return;
}
remove(MAX_ITEMS_TO_DISPLAY);
insert((JMenuItem)(vtrScrollableMenuItems.elementAt(--beginIndexIntoVector)), 1);
getPopupMenu().validate();
getPopupMenu().pack();scrollDown.enableScroll(true);
if (beginIndexIntoVector == 0){
scrollUp.enableScroll(false);
}
}public void scrollDownClicked(){
if ( (vtrScrollableMenuItems.size() <= MAX_ITEMS_TO_DISPLAY) ||
(beginIndexIntoVector + MAX_ITEMS_TO_DISPLAY == vtrScrollableMenuItems.size()) ) { // no need to scroll
return;
}
remove(1);
insert((JMenuItem)(vtrScrollableMenuItems.elementAt(beginIndexIntoVector + MAX_ITEMS_TO_DISPLAY)), MAX_ITEMS_TO_DISPLAY);
beginIndexIntoVector++;
getPopupMenu().validate();
getPopupMenu().pack();scrollUp.enableScroll(true);
if ( (beginIndexIntoVector + MAX_ITEMS_TO_DISPLAY == vtrScrollableMenuItems.size())){
scrollDown.enableScroll(false);
}
}public void mouseClicked(MouseEvent me){
Object eventSource = me.getSource();
if (eventSource == scrollUp){
scrollUpClicked();
}
else if (eventSource == scrollDown){
scrollDownClicked();
}
}
public void mousePressed(MouseEvent me){}
public void mouseReleased(MouseEvent me){}
public void mouseEntered(MouseEvent me){}
public void mouseExited(MouseEvent me){}cl*** ScrollUpOrDownButtonItem extends JMenuItem implements MouseListener{
String strDirection;
Polygon directionIndicator;
boolean blnMouseOver;
boolean blnEnableScroll;
public ScrollUpOrDownButtonItem(String strDirection){ // direction can be "up" or "down"
this.strDirection = strDirection;
directionIndicator = new Polygon();
blnMouseOver = false;
setPreferredSize(new Dimension(10, 15));
blnEnableScroll = false;
//addMouseListener(this); // can't do it here because i'm dumping the JRE's mouse listeners (above) and it would get this one too
}public void enableScroll(boolean blnEnableScroll){
this.blnEnableScroll = blnEnableScroll;
repaint();
}public void paintComponent(Graphics g){
super.paintComponent(g);
if (blnMouseOver){
g.setColor(Color.blue);
}
if (! blnEnableScroll){
g.setColor(Color.gray);
}
directionIndicator.reset();
if (strDirection.equals("up")){
directionIndicator.addPoint((int)(getSize().width/2.0 - 7.0 + 0.5), (int)(getSize().height/2.0 + 5.0 + 0.5));
directionIndicator.addPoint((int)(getSize().width/2.0 + 7.0 + 0.5), (int)(getSize().height/2.0 + 5.0 + 0.5));
directionIndicator.addPoint((int)(getSize().width/2.0 + 0.5), (int)(getSize().height/2.0 - 5.0 + 0.5));
}
else{
directionIndicator.addPoint((int)(getSize().width/2.0 - 7.0 + 0.5), (int)(getSize().height/2.0 - 5.0 + 0.5));
directionIndicator.addPoint((int)(getSize().width/2.0 + 7.0 + 0.5), (int)(getSize().height/2.0 - 5.0 + 0.5));
directionIndicator.addPoint((int)(getSize().width/2.0 + 0.5), (int)(getSize().height/2.0 + 5.0 + 0.5));
}
g.fillPolygon(directionIndicator);
}public void mouseEntered(MouseEvent me){
blnMouseOver = true;
repaint();
}
public void mouseExited(MouseEvent me){
blnMouseOver = false;
repaint();
}
public void mousePressed(MouseEvent me){}
public void mouseReleased(MouseEvent me){}
public void mouseClicked(MouseEvent me){}}}
Re: scrollable JMenu?
Author: frankm29
In Reply To: scrollable JMenu? Apr 30, 2002 6:35 PM Reply 4 of 5
Here's a cl*** I made to make JMenu scrollable, use it if it can help you...Frank
*/import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;// This cl*** implements a scrollable JMenu
// This cl*** was hacked out in a couple of hours, and is meant to be used
// such that you create an instance, add all the items you want, and then throw it away and
// create a new one if you want the menu items to change (there is no remove/insertAt functionality)
// Use "addScrollableItems(JMenuItem j)" to add all of the items
// You can change MAX_ITEMS_TO_DISPLAY to whatever you want, I used 10 because it seems to always fit on screen
// I have NOT tested this cl*** very much to see if it loses items, etc, ***USE AT YOUR OWN RISK***
// Feel free to use and modify. I'll probably add a thread on the up & down scrollers to make them scroll automatically (as long as mouse-over),
// let me know if you want it via email ([email protected]).
//
// This cl*** should only be used until SUN makes a real scrollable JMenupublic cl*** ScrollableJMenu extends JMenu implements MouseListener{
ScrollUpOrDownButtonItem scrollUp, scrollDown;
Vector vtrScrollableMenuItems;
static final int MAX_ITEMS_TO_DISPLAY = 10;
int beginIndexIntoVector;public ScrollableJMenu(String strMenuTitle){
setText(strMenuTitle);scrollUp = new ScrollUpOrDownButtonItem("up");
add(scrollUp);
removeAllMouseListeners(scrollUp);
scrollUp.addMouseListener(this);
scrollUp.addMouseListener(scrollUp);scrollDown = new ScrollUpOrDownButtonItem("down");
add(scrollDown);
removeAllMouseListeners(scrollDown);
scrollDown.addMouseListener(this);
scrollDown.addMouseListener(scrollDown);vtrScrollableMenuItems = new Vector();
beginIndexIntoVector = 0;
}public void addScrollableItem(JMenuItem jmiMenuItemToAdd){
vtrScrollableMenuItems.addElement(jmiMenuItemToAdd);
if ( vtrScrollableMenuItems.size() <= MAX_ITEMS_TO_DISPLAY){
insert(jmiMenuItemToAdd, vtrScrollableMenuItems.size());
}
else{
scrollDown.enableScroll(true);
}
}public void removeAllMouseListeners(AbstractButton b){
MouseListener[] allMouseListeners = b.getMouseListeners();
for (int i = 0; i < allMouseListeners.length; i++){
b.removeMouseListener(allMouseListeners);
}
}public void scrollUpClicked(){
if ( (vtrScrollableMenuItems.size() <= MAX_ITEMS_TO_DISPLAY) || (beginIndexIntoVector == 0) ){ // no need to scroll
return;
}
remove(MAX_ITEMS_TO_DISPLAY);
insert((JMenuItem)(vtrScrollableMenuItems.elementAt(--beginIndexIntoVector)), 1);
getPopupMenu().validate();
getPopupMenu().pack();scrollDown.enableScroll(true);
if (beginIndexIntoVector == 0){
scrollUp.enableScroll(false);
}
}public void scrollDownClicked(){
if ( (vtrScrollableMenuItems.size() <= MAX_ITEMS_TO_DISPLAY) ||
(beginIndexIntoVector + MAX_ITEMS_TO_DISPLAY == vtrScrollableMenuItems.size()) ) { // no need to scroll
return;
}
remove(1);
insert((JMenuItem)(vtrScrollableMenuItems.elementAt(beginIndexIntoVector + MAX_ITEMS_TO_DISPLAY)), MAX_ITEMS_TO_DISPLAY);
beginIndexIntoVector++;
getPopupMenu().validate();
getPopupMenu().pack();scrollUp.enableScroll(true);
if ( (beginIndexIntoVector + MAX_ITEMS_TO_DISPLAY == vtrScrollableMenuItems.size())){
scrollDown.enableScroll(false);
}
}public void mouseClicked(MouseEvent me){
Object eventSource = me.getSource();
if (eventSource == scrollUp){
scrollUpClicked();
}
else if (eventSource == scrollDown){
scrollDownClicked();
}
}
public void mousePressed(MouseEvent me){}
public void mouseReleased(MouseEvent me){}
public void mouseEntered(MouseEvent me){}
public void mouseExited(MouseEvent me){}cl*** ScrollUpOrDownButtonItem extends JMenuItem implements MouseListener{
String strDirection;
Polygon directionIndicator;
boolean blnMouseOver;
boolean blnEnableScroll;
public ScrollUpOrDownButtonItem(String strDirection){ // direction can be "up" or "down"
this.strDirection = strDirection;
directionIndicator = new Polygon();
blnMouseOver = false;
setPreferredSize(new Dimension(10, 15));
blnEnableScroll = false;
//addMouseListener(this); // can't do it here because i'm dumping the JRE's mouse listeners (above) and it would get this one too
}public void enableScroll(boolean blnEnableScroll){
this.blnEnableScroll = blnEnableScroll;
repaint();
}public void paintComponent(Graphics g){
super.paintComponent(g);
if (blnMouseOver){
g.setColor(Color.blue);
}
if (! blnEnableScroll){
g.setColor(Color.gray);
}
directionIndicator.reset();
if (strDirection.equals("up")){
directionIndicator.addPoint((int)(getSize().width/2.0 - 7.0 + 0.5), (int)(getSize().height/2.0 + 5.0 + 0.5));
directionIndicator.addPoint((int)(getSize().width/2.0 + 7.0 + 0.5), (int)(getSize().height/2.0 + 5.0 + 0.5));
directionIndicator.addPoint((int)(getSize().width/2.0 + 0.5), (int)(getSize().height/2.0 - 5.0 + 0.5));
}
else{
directionIndicator.addPoint((int)(getSize().width/2.0 - 7.0 + 0.5), (int)(getSize().height/2.0 - 5.0 + 0.5));
directionIndicator.addPoint((int)(getSize().width/2.0 + 7.0 + 0.5), (int)(getSize().height/2.0 - 5.0 + 0.5));
directionIndicator.addPoint((int)(getSize().width/2.0 + 0.5), (int)(getSize().height/2.0 + 5.0 + 0.5));
}
g.fillPolygon(directionIndicator);
}public void mouseEntered(MouseEvent me){
blnMouseOver = true;
repaint();
}
public void mouseExited(MouseEvent me){
blnMouseOver = false;
repaint();
}
public void mousePressed(MouseEvent me){}
public void mouseReleased(MouseEvent me){}
public void mouseClicked(MouseEvent me){}}}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*; public class PopTest extends JFrame
implements ListSelectionListener, MenuListener, AdjustmentListener
{
public PopTest()
{
addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
JMenuBar mbar = new JMenuBar();
list = new JList(items);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.addListSelectionListener(this);
scroll = new JScrollPane(list);
scroll.getVerticalScrollBar().addAdjustmentListener(this);
fruit = new ZMenu("Fruit");
fruit.addMenuListener(this);
fruit.add(scroll);
mbar.add(fruit);
setJMenuBar(mbar);
l = new JLabel("<none>");
getContentPane().setLayout(new FlowLayout());
getContentPane().add(l);
}public void valueChanged(ListSelectionEvent e)
{
int selectedIndex = list.getMaxSelectionIndex();
selection = (String)(list.getModel().getElementAt(selectedIndex));
l.setText(selection);
scrolling = false;
fruit.fireMenuDeselected();}public void menuCanceled(MenuEvent e){}
public void menuDeselected(MenuEvent e)
{
if(!scrolling)
{
fruit.setPopupMenuVisible(false);
scrolling = false;
}
else
{
fruit.setPopupMenuVisible(true);
scrolling = false;
}
} public void menuSelected(MenuEvent e)
{
fruit.setPopupMenuVisible(true);
} public void adjustmentValueChanged(AdjustmentEvent e)
{
scrolling = true;}public static void main(String[] args)
{
PopTest p = new PopTest();
p.setSize(320, 240);
p.show();
}JLabel l;
JList list;
JScrollPane scroll;
ZMenu fruit;
boolean scrolling =false;
String selection;
String[] items = {"Apple", "Cherry", "Strawberry", "Peach", "Banana",
"Plum", "Orange", "Grape", "Mango", "Raspberry", "Tangerine",
"Pear", "Blueberry", "Papaya"};
}
class ZMenu extends JMenu
{
public ZMenu(String s){super(s);}
public void fireMenuDeselected()
{super.fireMenuDeselected();}
}
import javax.swing.JMenuItem;
import javax.swing.JMenu;
/**http://forum.java.sun.com/thread.jsp?forum=257&thread=118940
* Recursive JMenu, displays itself in multi menus when its size
is larger than the 'max' value.
* author Vincent Dupont
* version 1.0
* To do : compliance with other 'add()' methods form JMenu
(add(Action), add(JMenuItem), etc)
*/
public class ExtendedJMenu extends JMenu{ private int max=12;
private int current=0;
private ExtendedJMenu more =null; /**Simple constructor*/
public ExtendedJMenu(String s){
super(s);
}
/**Core method*/
public JMenuItem add(String s){
current++;
if (current>max){
return getChildMenu().add(s);
}//if (current>max){
else {
return super.add(s);
} } /**Returns the child menu if any. Creates and add the new one if
none previously set*/
public ExtendedJMenu getChildMenu(){
if (more==null) {
more = new ExtendedJMenu("More...");
add(more);
}
return more; }
}