# Scrollbalken für ein Menü oder laufendes Dropdown-Menü wie?



## tortelinski (11. Apr 2007)

Wie kann ich einen Scrollbalken oder etwas Ähnliches in ein Menü einbauen?  

Das Menü wird nicht ganz angezeigt auf dem Schirm, da zu viel lang.  

Das steht nirgendswo. Und die herkömmliche Definition eines Scrollbalken funktioniert da nicht!  


```
JMenu menu = new JMenu(); 
JScrollPane sp = new JScrollPane(menu); 
???.add(sp);
```

So, jetzt stimmt es aber, was ist der Container bei einem Menu??? Ein Menu hat keinen Container, was tun???

Zeigt den Balken nicht!


----------



## Ariol (11. Apr 2007)

????

Wie soll denn das funktionieren?
Du setzt das Menü ins ScrollPane und das wiederum ins Menü.

Wird ja eine endlosschliefe draus


----------



## Wildcard (11. Apr 2007)

Das fügt ein Menü in eine ScrollPane ein und die ScrollPane anschließend in das gleiche Menü  :autsch:


----------



## tortelinski (11. Apr 2007)

Okay, sorry, war ein Tippfehler, habe es korrigiert, aber wie es geht könnt ihr mir nicht sagen?


----------



## Wildcard (11. Apr 2007)

Jetzt macht's erst recht keinen Sinn. Was willst du mit einer leeren JScrollPane?


----------



## tortelinski (11. Apr 2007)

Herje, ich bin weiß Gott kein Freak, aber die Antworten bringen mich sowas von Null weiter, es wäre mir einfach damit geholfen, wenn mir einer sagt, wie ich an das gesamte Menu rankomme, weil es einfach zu lang ist für den Bildschirm, ist irgendjemand so schlau, das hier kurz einzutippen??!!


----------



## Wildcard (11. Apr 2007)

was willst du überhaupt scrollen? Die Menus? Die MenuItems? Wo liegt das drin? In einer JMenuBar?


----------



## tortelinski (11. Apr 2007)

Ich habe ein JMenu in dem so ca. 100 JMenuItem gelistet sind, dieses ist dann aber zu lang für den Bildschirm, weil es zu viele Einträge sind, jetzt suche ich nach einer Lösung, wie ich an alle JMenuItem - Einträge rankomme. Sei es via einer Scrollbar oder via einer Lösung die ein laufendes Menü erzeugt, Sun bietet hier keine Lösung an, ich finde da nix!


----------



## Wildcard (11. Apr 2007)

Ich müsste es selbst ausprobieren, aber eigentlich sollte es funktionieren alle JMenuItems in ein JPanel oder eine Box zu packen und diese in eine JScrollPane.
Die JScollPane kommt dann ins JMenu.


----------



## tortelinski (11. Apr 2007)

Danke 

Problem bei der Geschichte, es handelt sich um ein Font-Menu für einen vollwertigen HTML-Editor, den ich bei Sun bezog, und die Schrifarten (JMenuItem) kommen über ne for Schleife ins Menü rein!!

```
// font select (typeface) submenu
        JMenu fontSelectMenu = new JMenu();
            fontSelectMenu.setText(
	        resources.getString("fontSelectMenu.label"));
            fontSelectMenu.setMnemonic(
	        resources.getString("fontSelectMenu.label").charAt(0));
        
            // menu items
            String[] fontNames = 
	        GraphicsEnvironment.
	            getLocalGraphicsEnvironment().
		        getAvailableFontFamilyNames();
            ActionListener fontListener = new FontFamilyActionListener();
            for (i = 0; i < fontNames.length; i++) {
                JMenuItem menuItem = new JMenuItem(fontNames[i]);
                menuItem.addActionListener(fontListener);
                fontSelectMenu.add(menuItem);
            }
```


----------



## Wildcard (11. Apr 2007)

Nimm ein eigenes JMenu (eine davon abgeleitete Klasse) die diesen Schritt kapselt.
Du solltest dir übrigens über eine Fisheye Technik Gedanken machen.
Macht die Sache viel übersichtlicher.


----------



## Ariol (11. Apr 2007)

mal ein bisschen gegooglet und das hier gefunden (1.Link bei Google -> gelesen und auf den Link im Text geklickt):
http://forum.java.sun.com/thread.jspa?forumID=57&threadID=713377

also für dich einfach

```
JMenu Menu = new JMenu("Menü");
menu.getPopupMenu().setLayout(new GridLayout(25,0));
```

die Items dann wie gewohnt über add hinzufügen.
Ist zwar kein Scroll, aber trotzdem schön.

Wenns doch dringend Scroll sein muss:
(2.Link bei Google)
http://forum.java.sun.com/thread.jspa?threadID=283418&messageID=1282082

GOOGLE ist toll 

_EDIt. Ich hab übrigens keine kryptischen Google-tags benutzt sonder nur "Jmenu mit scrollbar" in "Das WEB" gesucht_


----------



## tortelinski (11. Apr 2007)

Vor dem JMenu hockt noch ein JMenu und drüber die JMenubar....

Nun ja, Dein Panel-Modell führt zu einem Scrollbalken im ersten Untermenu an der Stelle wo der Verzweig zu den Schrifarten () ist! es entsteht ledier Müll! Das war es nicht...


----------



## tortelinski (11. Apr 2007)

@Ariol! Lösung1:  Das ist eine Lösung, die füllt aber den kompletten Bildschirm mit Menüeinträgen, da wird es dann fast schon horizontal eng! Vielen Dank!


----------



## Ariol (11. Apr 2007)

Naja, du musst das GridLayout anpassen.

Hast du dir mal den 2. Link angesehen?


----------



## L-ectron-X (11. Apr 2007)

Vielleicht kannst du auch einfach eine JComboBox benutzen, die kann man von Hause aus so einstellen, dass die nur eine bestimmte Anzahl an Einträgen anzeigt. Der Rest kann gescrollt werden.


----------



## tortelinski (11. Apr 2007)

Ich bin gerade dabei, den 2. Link zu verstehen, wird nicht leicht, mal sehen, Danke! Ich hab den ganzen Tag in Google nach - - Java Scrollbar Menu - - gesucht und nix gefunden!


----------



## Ariol (11. Apr 2007)

```
JMenuBar menuBar = new JMenuBar();
		this.setJMenuBar(menuBar);
		JMenu menu = new JMenu("Menu");

		Vector<String> vektor = new Vector<String>();
		
		for (int i = 0; i < 100; i++)
		{
			vektor.add("MenuItem" + i);
		}
		
		JList list = new JList(vektor);
		JScrollPane scrollPane = new JScrollPane(list);
		scrollPane.setPreferredSize(new Dimension(200,200));
		
		menu.add(scrollPane);
		menuBar.add(menu);
```

So gehts


----------



## Ariol (11. Apr 2007)

Noch eins:


```
JMenuBar menuBar = new JMenuBar();
		this.setJMenuBar(menuBar);
		
		JMenu menu = new JMenu("Menu");
		menuBar.add(menu);
		
		JPanel panel = new JPanel();
		panel.setLayout(new GridLayout(100, 1));
		
		JScrollPane scrollPane = new JScrollPane(panel);
		menu.add(scrollPane);
		
		for (int i = 0; i < 100; i++)
		{
			JButton button = new JButton("MenuItem" + i);
			button.setContentAreaFilled(false);
			button.setSize(130, 20);
			panel.add(button);
		}
		
		scrollPane.setPreferredSize(new Dimension(130,200));
```


----------



## Wildcard (11. Apr 2007)

Ich sag doch das es so funktionieren müsste


----------



## tortelinski (11. Apr 2007)

Schade! Die 2. Methode und die 2 letzten Tipps funktionieren nicht, jedenfalls hab ich keine Ahnung, wie ich die in dieses Konstrukt einbetten kann, das ist das Problem, so sieht das Menu aus:


```
int i = 0;
JMenuBar menuBar = new JMenuBar();
	
// font menu
JMenu fontMenu = new JMenu();
    fontMenu.setText(
    resources.getString("fontMenu.label"));
    fontMenu.setMnemonic(
    resources.getString("fontMenu.mnemonic").charAt(0));    
  
// font select (typeface) submenu
JMenu fontSelectMenu = new JMenu();
    fontSelectMenu.setText(
    resources.getString("fontSelectMenu.label"));
    fontSelectMenu.setMnemonic(
    resources.getString("fontSelectMenu.label").charAt(0));

    String[] fontNames = 
    GraphicsEnvironment.
    getLocalGraphicsEnvironment().
    getAvailableFontFamilyNames();
    ActionListener fontListener = new FontFamilyActionListener();
    for (i = 0; i < fontNames.length; i++) {
    JMenuItem menuItem = new JMenuItem(fontNames[i]);
    menuItem.addActionListener(fontListener);
    fontSelectMenu.add(menuItem);
    }
    fontMenu.add(fontSelectMenu);

menuBar.add(fontMenu);
```


----------



## Ariol (11. Apr 2007)

Geht doch problemlos. Musst nur noch ein bisschen die Größen und den ActionListener und das Aussehen der Buttons ändern.

```
int i = 0;
JMenuBar menuBar = new JMenuBar();
	
// font menu
JMenu fontMenu = new JMenu();
    fontMenu.setText(
    resources.getString("fontMenu.label"));
    fontMenu.setMnemonic(
    resources.getString("fontMenu.mnemonic").charAt(0));    
  
// font select (typeface) submenu
JMenu fontSelectMenu = new JMenu();
    fontSelectMenu.setText(
    resources.getString("fontSelectMenu.label"));
    fontSelectMenu.setMnemonic(
    resources.getString("fontSelectMenu.label").charAt(0));

    String[] fontNames = 
    GraphicsEnvironment.
    getLocalGraphicsEnvironment().
    getAvailableFontFamilyNames();
    ActionListener fontListener = new FontFamilyActionListener();

    JPanel itemPanel = new JPanel();
    itemPanel.setLayout(new BoxLayout(itemPanel, BoxLayout.Y_AXIS));

    for (i = 0; i < fontNames.length; i++) {
    JButton menuItem = new JButton(fontNames[i]);
    menuItem.addActionListener(fontListener);
    itemPanel.add(menuItem);
    }

    JScrollPane scrollPane = new JScrollPane(itemPanel);
    scrollPane.setPreferredSize(new Dimension(200,200));
    fontSelectMenu.add(scrollPane);
    fontMenu.add(fontSelectMenu);

menuBar.add(fontMenu);
```

EDIT: Das Menü schließt glaube ich nicht automatisch - muss man vermutlich auch noch einbauen


----------



## tortelinski (11. Apr 2007)

Das funktioniert rein optisch gesehen hervorragend, leider kommt dann, wenn ich einen Font-Button anklicke, diese Fehlermeldung, sprich die eigentliche Funktionalität, dass eine Schriftart ausgewählt wird geht flöten, schade!


Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JButton cannot be cast to javax.swing.JMenuItem
	at samples.StyledTextEditor$FontFamilyActionListener.actionPerformed(StyledTextEditor.java:597)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)


----------



## Ariol (11. Apr 2007)

du musst deinen ActionListener anpassen!


----------



## tortelinski (11. Apr 2007)

Prima! Habe ich gemacht, jetzt passiert Folgendes (ist das spannend!): Wenn ich einen Button klicke, bleibt das Menu offen, die Schriftart wird schon korrekt ausgewählt, das dumme Menü geht aber nicht mehr zu!!!

Was nun nun? (Schönen Dank für die kompetente Hilfe!)


----------



## tortelinski (11. Apr 2007)

Doch es geht zu! Wenn man danebenklickt, ok danke, damit ist dieser Thread geschlossen! Große Leistung!


----------



## Ariol (12. Apr 2007)

Mit "JMenu.setPopupMenuVisible(false);" kannst du die das ganze wenigstens ausblenden, dann ists leichter auf den Frame zu klicken.

Einfach aufs TopLevel-JMenu setzen (im ActionListener)

Es solle auch möglich sein mit requestFocus ein anderes Element zu aktivieren (ob dann das Menü zuklappt weiss ich leider nicht)


----------



## tortelinski (12. Apr 2007)

JMenu.setPopupMenuVisible(false);

Wo muss das dann denn rein? In den ActionListener?


----------



## Ariol (12. Apr 2007)

Ja, du musst das TopLevel-Menü (in deinem Fall fontMenu) direkt in der Klasse anlegen und im FontFamilyActionListener bei deiner Action folgendes einfügen:


```
fontMenu.setPopupMenuVisible(false);
```


----------



## tortelinski (12. Apr 2007)

fontMenu.setPopupMenuVisible(false); 
das Top-Level-Menü existiert ja, es ist das fontMenu, allerdings bringt er dann, wenn ich die Zeile in die Action am Ende reinpacke: fontMenu cannot be resolved, merkwürdig, dass es da nicht mehr gilt...


----------



## tortelinski (12. Apr 2007)

jetzt, direkt in der Klasse! Ich habs kapiert!


----------



## Ariol (12. Apr 2007)

poste mal bitte den code


----------



## tortelinski (12. Apr 2007)

Okay, funktioniert! Aber es passiert folgendes: Das Menu verschwindet, es bleibt aber das unterste Untermenü mit den Schriftarten auf dem Schirm stehen. Also: Menü klappt zu, aber Problem beim Alten: Untermenü steht noch wie ein Fels!


----------



## Ariol (12. Apr 2007)

hmm, bei mir hats geklappt
vielleicht das setPopupMenuVisible(false) auch aufs untermenü.

Bei ich hatte beim testen kein untermenü.

bei mir war nur noch der menübutton selbst aktiviert - was dem ganzen aber eigentlich keinen abbruch tut


----------



## tortelinski (12. Apr 2007)

Na ja, ist ja ned so wichtig, ich gehe dann ins Bett, morgen geht es weiter: Thema dann: Pop-Up-Menu, Cut, Copy and Paste, aber noch ohne Funktionalität, Cut Copy and Paste funktioniert nur über Strg-X -C -P, Funktionalität fürs Pop-Up Menü frisch zu implementieren, und zwar so, dass die Schriftartenformatierung erhalten bleibt, aber dann mach ich nen neuen Thread auf! Grüße


----------

