PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Java] JPopupMenu: wie nachher auf Menüeinträge zugreifen??


Alex2001
2004-06-09, 15:26:08
Hab mal ein PopupMenu definiert:

....
mi = new JMenuItem("Neu");
mi.addActionListener(this);
mi.setActionCommand("insert");
popup.add(mi);
popup.addSeparator();

mi = new JMenuItem("Kopieren");
mi.addActionListener(this);
mi.setActionCommand("copy");
popup.add(mi);
....



Wie kann ich dann nach der Erzeugung auf die Menüeinträge zugreifen? "Einfügen" soll z.B. am Ende des Listeners "Kopieren" aktiviert werden.

ethrandil
2004-06-09, 15:36:01
Was genau möchtest du denn?

Sehe ich das richtig, dass es einen ActionListener gibt, der das Einfügen übernimmt, und du diesen aufrufen willst?

ich such mal solange in der api..

EDIT:
in Container (von dem JPopupMenu erbt) gibt es die Methode
Component getComponent(int n)
damit solltest du auf alle JMenuItems zugreifen können.

- Eth

Alex2001
2004-06-09, 16:19:19
Original geschrieben von ethrandil
Was genau möchtest du denn?

Sehe ich das richtig, dass es einen ActionListener gibt, der das Einfügen übernimmt, und du diesen aufrufen willst?

ich such mal solange in der api..

EDIT:
in Container (von dem JPopupMenu erbt) gibt es die Methode
Component getComponent(int n)
damit solltest du auf alle JMenuItems zugreifen können.

- Eth

Es geht nur um die Kontextmenüeinträge. Bevor der Benutzer nicht "Kopieren" ausgewählt hat, soll Einfügen nicht anwählbar, d.h. disabled sein.

Mit folgendem Code gehts nicht. Hab ich schon ausprobiert:

JMenuItem mi2 = (JMenuItem)popup.getComponent(1);
mi2.setEnabled(false);

EDIT:Scheint jetzt doch zu funktionieren mit der Zeile: (popup.getComponent(1)).setEnabled(false)

EDIT 2: Ok, das funktioniert jetzt für die Hauptebene des PopupMenüs. Gibt es eine Möglichkeit die Einträge in kaskadierenden Menüs (z.B. hab ich "Einfügen", und darunter 2 Einträge) einzeln zu deaktivieren?

ethrandil
2004-06-09, 16:42:19
bei mir gehts, so:

public class MenuKontextTest extends JFrame implements ActionListener{

private JPopupMenu popup = new JPopupMenu();
private JMenuItem insertItem;

/**
*
*/
public MenuKontextTest() {
super("test");

(... zeugs fürs Anzeigen des popups etc ...)

insertItem = new JMenuItem("Einfügen");
insertItem.addActionListener(this);
insertItem.setActionCommand("insert");
insertItem.setEnabled(false);

popup.add(insertItem);
popup.addSeparator();

JMenuItem mi;

mi = new JMenuItem("Kopieren");
mi.addActionListener(this);
mi.setActionCommand("copy");
popup.add(mi);

}

public void actionPerformed(ActionEvent e) {
if(e.getActionCommand() == "copy" && !insertItem.isEnabled()){
insertItem.setEnabled(true);
}
}
}

Alex2001
2004-06-09, 17:24:31
Original geschrieben von Alex2001
EDIT 2: Ok, das funktioniert jetzt für die Hauptebene des PopupMenüs. Gibt es eine Möglichkeit die Einträge in kaskadierenden Menüs (z.B. hab ich "Einfügen", und darunter 2 Einträge) einzeln zu deaktivieren?*Schieb*

HellHorse
2004-06-09, 18:18:53
Original geschrieben von Alex2001
*Schieb*
Du kannst doch einfach jedes JMenuItem mit setEnabled(bool) (de)aktivieren.

Alex2001
2004-06-09, 18:26:50
Original geschrieben von HellHorse
Du kannst doch einfach jedes JMenuItem mit setEnabled(bool) (de)aktivieren. Ja schon, nur steht der Zeiger nicht mehr auf den Elementen, da ja der ganze Aufbau der GUI in der init Methode erfolgt und demzufolge die Zeiger nur in dieser Methode vorhanden sind. Im Listener dann nicht mehr (popup liegt auf der Hauptebene -> interessanterweise sind da ganz normal die Elemente drin, siehe **)

Mit (popup.getComponent(1)).setEnabled(false) kann ich ja auf die Elemente der 1. Ebene des Popup Menüs zugreifen. Jetzt müßte ich nur noch wissen, wie ich auf die 2. Ebene zugreifen kann.


**Da es nur 2 kaskadierende Menüs sind, hab ich versucht die zwei Variablen dafür m1 und m2 aus der Methode herauszuziehen und auf die Hauptebene zu legen.
Leider krieg ich dann immer die Meldung, das es keine Komponenten bei m1 und m2 gibt, obwohl in init welche reingetan werden, z.B. durch m1.add(mi) (m1 ist ein JMenu, mi ist ein JMenuItem), dann wird popup.add(m1) ausgeführt.

HellHorse
2004-06-09, 20:35:29
Original geschrieben von Alex2001
Ja schon, nur steht der Zeiger nicht mehr auf den Elementen, da ja der ganze Aufbau der GUI in der init Methode erfolgt und demzufolge die Zeiger nur in dieser Methode vorhanden sind. Im Listener dann nicht mehr (popup liegt auf der Hauptebene -> interessanterweise sind da ganz normal die Elemente drin, siehe **)

Schon mal daran gedacht eine Instanzvariable zu machen, die das entsprechende JMenuItem referenziert?
Original geschrieben von Alex2001
Mit (popup.getComponent(1)).setEnabled(false) kann ich ja auf die Elemente der 1. Ebene des Popup Menüs zugreifen. Jetzt müßte ich nur noch wissen, wie ich auf die 2. Ebene zugreifen kann.

Falls du den richtigen Index erwischst, ist es ein JMenu.
-> nach Component casten und wieder mit getComponent darüber.

Alex2001
2004-06-09, 22:58:04
Original geschrieben von HellHorse
Falls du den richtigen Index erwischst, ist es ein JMenu.
-> nach Component casten und wieder mit getComponent darüber. Ja, das ist ein JMenu wenns kaskadierend ist.

Kannst du mir deinen Tip mit einem Codebsp. erläutern? Weiß jetzt nicht genau, was du mit dem meinst. Weil wenn ichs nach Component caste, gibts ja die Funktion .getComponent(int i) nicht mehr.

Hab mal ((JMenu)(popup.getComponent(3))).getComponent(0).setEnabled(false); probiert, kompiliert zwar ohne Fehler, hat jedoch keinen Effekt.

Alex2001
2004-06-13, 19:32:59
Weiß jemand noch was dazu?

HellHorse
2004-06-13, 20:13:41
Ooops verschrieben, sollte natürlich Container und nicht Component heissen.

AHF
2004-06-13, 23:01:15
Original geschrieben von Alex2001
Hab mal ((JMenu)(popup.getComponent(3))).getComponent(0).setEnabled(false); probiert, kompiliert zwar ohne Fehler, hat jedoch keinen Effekt.
neues JMenu als platzhalter definieren:


JMenu tempmenu = new JMenu();
if (((popup.getComponent(3)).getComponent(0))instanceof(JMenu)) {
tempmenu = (JMenu)(((popup.getComponent(3)).getComponent(0));
tempmenu.setEnabled(false);
}


ps: zähl die klammern lieber nochmal nach ;)

HellHorse
2004-06-14, 21:13:01
Aus der fehleden Rückmeldung schliesse ich jetzt mal, dass das Problem noch nicht gelöst ist.
Bei mir klappte es auf Anhieb auch nicht.
Ich hoffe das hilft:

public class MenuDemo {
public static Window getMenuFrame() {
JFrame frame = new JFrame("Menu Demo");

JPopupMenu fileMenu = new JPopupMenu("File");
JMenu newMenu = new JMenu("New");
newMenu.add("Life");
newMenu.add("Chance");
newMenu.add("Haircut");
fileMenu.add(newMenu);
fileMenu.add("Open");
fileMenu.add("Save");
fileMenu.addSeparator();
fileMenu.add("Exit");


// das Save JMenuItem holen
AbstractButton menuItem = (AbstractButton) fileMenu.getComponent(2);
menuItem.setEnabled(false);

// das new menu holen
JMenu newMenuFromFileMenu = (JMenu) fileMenu.getComponent(0);
// das Life JMenuItem holen
menuItem = (AbstractButton) newMenuFromFileMenu.getPopupMenu().getComponent(0);
menuItem.setEnabled(false);

frame.getContentPane().addMouseListener(new PopupListener(fileMenu));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(200, 100);
return frame;
}

private static class PopupListener extends MouseAdapter {
private JPopupMenu popupMenu;

public PopupListener(JPopupMenu popupMenu) {
this.popupMenu = popupMenu;
}

public void mousePressed(MouseEvent e) {
this.maybeShowPopup(e);
}

public void mouseReleased(MouseEvent e) {
this.maybeShowPopup(e);
}

private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
this.popupMenu.show(e.getComponent(),
e.getX(), e.getY());
}
}
}

public static void main(String[] args) {
Window menuWindow = getMenuFrame();
menuWindow.setVisible(true);
}
}

Der tricky Teil ist fett und schwarz. getComponet(int) funktioniert bei einem JMenu nicht. Du muss das auf das interne JPopupMenu ausführen.

Alex2001
2004-06-15, 17:46:23
Besten Dank für die Tips. Werde es mal probieren.