# JComboBox ausklappen



## nieselfriem (16. Dez 2009)

Hallo!
Gibt es eine Möglichkeit, die JComboBox aus zuklappen. So das schon eine Liste mit x Elementen angezeigt wird, ohne sie erst anklicken zu müssen

Gruß niesel


----------



## javimka (16. Dez 2009)

setPopupVisible(true);
Aber willst du stattdessen nicht gleich eine JList verwenden?


----------



## nieselfriem (16. Dez 2009)

da kommt nur die Fehlermeldung

```
JComboBox combo = new JComboBox(colors);
	combo.setEditable(true);
    combo.setPopupVisible(true);
```
"component must be showing on the screen to determine its location"

Gruß niesel


----------



## icarus2 (16. Dez 2009)

Heisst, du musst zuerst mit add(...) die JCheckBox hinzufügen. Zusätzlich muss sie visible sein.


----------



## nieselfriem (16. Dez 2009)

```
String[] colors={"rot","grün","gelb","blau","schwarz"};
	JComboBox combo = new JComboBox(colors);
	add(combo);
        combo.setEditable(true);
	combo.setVisible(true);
	combo.setPopupVisible(true);
```
trotzdem kommt die Fehlermeldung 

gruß niesel


----------



## noobadix (16. Dez 2009)

Die Fehlermeldung erschien bei mir nicht, wenn ich den Befehl setPopupVisible() aufgerufen habe, nachdem auf dem beinhaltenden Frame setVisible(true) aufgerufen worden ist. Allerdings war keine JComboBox aufgeklappt.

Gruß
N.


----------



## icarus2 (16. Dez 2009)

Schon mal das hier versucht: combo.showPopup()?

Ich weiss allerdings nicht genau, was der Unterschied ist zwischen den beiden, kannst es ja aber mal versuchen.


----------



## noobadix (16. Dez 2009)

Hat bislang beides nicht funktioniert, habe aber gelesen, dass, wenn der Focus auf das Fenster gesetzt wird, alle beinhalteten popups geschlossen werden, man könnte also versuchen, dieses Verhalten abzuändern, aber ich habe keine Vorstellung, wie das gehen soll.


----------



## icarus2 (16. Dez 2009)

Vielleicht hilft dir das etwas:
How to Use the Focus Subsystem


----------



## nieselfriem (16. Dez 2009)

Ich gebe euch mal das gesamte Script:

```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GridList
extends JFrame
{
  public static void main(String[] args)
  {
	  GridList wnd = new GridList();
    wnd.setVisible(true);
  }
 
  public GridList()
  {

	super("Test GridBagLayout");
	JLabel suchelabel = new JLabel("Suchbegriff");
	
	String[] colors={"rot","grün","gelb","blau","schwarz"};
	JComboBox combo = new JComboBox(colors);
	add(suchelabel);
	add(combo);
	combo.setEditable(true);
	combo.setVisible(true);
	combo.showPopup();
	
	setBackground(Color.lightGray);
    addWindowListener(new WindowClosingAdapter(true));
    //Layout setzen und Komponenten hinzuf�gen
    setLayout(new GridLayout(3,1,0,2));
    pack();
    
  }
}
```

gruß niesel


----------



## javimka (16. Dez 2009)

```
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class PopupDemo {

	public static void main(String[] args) {

		JFrame frame = new JFrame("PopupDemo");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		final JComboBox cbx = new JComboBox(new String[] {"sjkdfh", "sjk f", "asdkjh"});
		frame.add(cbx);
		
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
		
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				cbx.setPopupVisible(true);
			}
		});
	}
}
```


----------



## icarus2 (16. Dez 2009)

[Java]
import java.awt.Container;
import java.awt.GridLayout;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;


public class GridList extends JFrame {

	private Container c;
	private JComboBox combo;

	protected GridList(){
		super("Test GridBagLayout");

		c = getContentPane();
		c.setLayout(new GridLayout(3, 1, 0, 2));

		JLabel sucheLabel = new JLabel("Suchbegriff");
	    String[] colors={"rot","grün","gelb","blau","schwarz"};
	    combo = new JComboBox(colors);

		add(sucheLabel);
		add(combo);
		combo.setEditable(true);


		setSize(600, 400);
		setLocationRelativeTo(null);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		SwingUtilities.invokeLater(new Runnable(){
			@Override
			public void run(){
				combo.setPopupVisible(true);
			}
		});

	}

	public static void main(String[] args) {

		SwingUtilities.invokeLater(new Runnable(){
			@Override
			public void run(){
				new GridList();
			}
		});

	}

}
[/Java]

*Edit
Wups, javamika war wohl schneller ^^

Das wichtigste ist wohl in dem Code einfach, dass du das setPopupVisible(...) über die SwingUtilities aufrufst, egal welche von beiden Varianten du nimmst.
(Auch wenn ich meine persönlich schöner finde, was jedoch natürlich reine Geschmackssache ist).


----------



## noobadix (16. Dez 2009)

ihr habt ja sooo Recht...


----------



## Ebenius (17. Dez 2009)

icarus2 hat gesagt.:


> Heisst, du musst zuerst mit add(...) die JCheckBox hinzufügen. Zusätzlich muss sie visible sein.


Um das mal zu korrigieren: Das heißt nicht, dass die Komponente nur hinzugefügt sein muss und visible sein muss, sie muss zum Zeitpunkt des Aufrufs angezeigt werden. Das heißt, sie muss in irgendeinem sichtbaren Fenster existieren.

[c]SwingUtilities.invokeLater()[/c] funktioniert hier, weil in dem Fall das Fenster bereits angezeigt wird, bevor der [c]setPopupVisible(true)[/c] ausgeführt wird.

Ebenius


----------



## icarus2 (17. Dez 2009)

Jo, ist auch so ein meinen Code-Beispiel. Hab das vergessen hinzzuschreben, thx für die Ergänzung.

Nur so als Frage... warum muss ich die Methode setPopupVisible(...) zusätzlich in einer neuen invokeLater(...) aufrufen, damit es funktioniert? Ich weiss, dass es so sein muss, weiss aber nicht wiso ^^


----------



## Ebenius (17. Dez 2009)

icarus2 hat gesagt.:


> Nur so als Frage... warum muss ich die Methode setPopupVisible(...) zusätzlich in einer neuen invokeLater(...) aufrufen, damit es funktioniert? Ich weiss, dass es so sein muss, weiss aber nicht wiso ^^


Weil das Sichtbarmachen des Fensters ein [c]AncestorEvent::ancestorAdded[/c] an seine Kinder verschickt. Dieses Event wird über die EventQueue (natürlich FIFO) später abgearbeitet. Das bedeutet die Kinder erhalten die Nachricht erst verzögert. Die JComboBox schließt bei Erhalt eines  [c]AncestorEvent::ancestorAdded[/c] sein Popup. Also muss man dafür sorgen, dass das gewünschte Öffnen des Popups erst ausgeführt wird, nachdem die JComboBox das [c]AncestorEvent::ancestorAdded[/c] abgearbeitet hat. Und das tut man, indem man mit [c]invokeLater()[/c] die Ausführung verzögert; genauer gesagt, indem man mittels [c]invokeLater()[/c] wiederum ein Ereignis ans Ende der EventQueue stellt, welches die Abarbeitung des übergebenen [c]Runnable[/c] anordnet. Dies passiert dann zwangsweise (da FIFO) nach dem Abarbeiten des AncestorEvents. Verständlich?

Ebenius


----------



## icarus2 (17. Dez 2009)

Achso, ja vielen Dank. Das erscheint für mich logisch. Ich kenne zwar ein par Begriffe nicht, doch denke ich habe ich das Prinzip verstanden, worum es geht.

EventQueue ist verdammt kompliziert wenn mans wirklich verstehen will :-/

Danke für die Erklärung =)


----------

