Action Listener

  • Themenstarter Themenstarter Alerion
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
A

Alerion

Gast
Hallo,

Ich habe bei meinem Programm eine Menüleiste und möchte natürlich, dass das Programm reagiert, wenn ich auf einen der Menüeinträge klicke. Irgendwie funktioniert das aber nicht so, wie ich mir das vorstelle.

Code:
public class SimpleTableFrame extends JFrame implements ActionListener
{ 

    //Path variable
    private static final String path = "PATH/";
    //JTable table 
    private JTable m_simpleTable; 
    //JTable model 
    private SimpleTableModel m_simpleTableModel; 

[...]

    public static void main(String[] arg) 
    { 
        SimpleTableFrame m = new SimpleTableFrame(); 
         
        m.setVisible(true); 
        m.setSize(new Dimension(600, 300)); 
        m.validate(); 
        
        // Menübalken einfügen
        JMenuBar jMenuBar1 = new JMenuBar();
		m.setJMenuBar(jMenuBar1);
		{
			JMenu jMenu1 = new JMenu();
			jMenuBar1.add(jMenu1);
			jMenu1.setText("Menü");
			{
				JMenuItem MenNewFile = new JMenuItem("Neue Einkaufsliste");		
				JMenuItem MenOpenFile = new JMenuItem("Öffne Einkaufliste");
				JMenuItem MenSaveFile = new JMenuItem("Einkaufsliste speichern");
				JSeparator MenSep = new JSeparator();
				JMenuItem MenExit = new JMenuItem("Beenden");
				
				jMenu1.add(MenNewFile);
				jMenu1.add(MenOpenFile);			
				jMenu1.add(MenSaveFile);
				jMenu1.add(MenSep);	
				jMenu1.add(MenExit);
				
				MenOpenFile.addActionListener(m);
				MenNewFile.addActionListener(m);
				MenSaveFile.addActionListener(m);
				MenExit.addActionListener(m);
			}

		}
		
    }

    public void actionPerformed(ActionEvent evt)
    {
    
    	System.out.println("Menüeintrag" + evt.getSource()+ "gewählt");
    	// Code
    		
    }

In actionPerformed geht der anscheinend gar nicht rein. Kann mir jemand erklären, was ich da verdreht habe und wie ich es in Ordnung bringe?

Gruß
Alerion
 
Hab den Code mal etwas aufgeräumt:
Code:
import java.awt.Dimension;
import java.awt.event.*;

import javax.swing.*;

public class SimpleTableFrame extends JFrame implements ActionListener
{
    //Path variable
    private static final String path = "PATH/";
    //JTable table
    private JTable simpleTable;
    //JTable model
    
    public SimpleTableFrame()
    {
            JMenuBar jMenuBar1 = new JMenuBar();
            setJMenuBar(jMenuBar1);
            JMenu jMenu1 = new JMenu();
            jMenuBar1.add(jMenu1);
            jMenu1.setText("Menü");
            JMenuItem MenNewFile = new JMenuItem("Neue Einkaufsliste");      
            JMenuItem MenOpenFile = new JMenuItem("Öffne Einkaufliste");
            JMenuItem MenSaveFile = new JMenuItem("Einkaufsliste speichern");
            JSeparator MenSep = new JSeparator();
            JMenuItem MenExit = new JMenuItem("Beenden");
            
            jMenu1.add(MenNewFile);
            jMenu1.add(MenOpenFile);         
            jMenu1.add(MenSaveFile);
            jMenu1.add(MenSep);   
            jMenu1.add(MenExit);
            
            MenOpenFile.addActionListener(this);
            MenNewFile.addActionListener(this);
            MenSaveFile.addActionListener(this);
            MenExit.addActionListener(this);
            
            setSize(new Dimension(600, 300));
            setVisible(true);
            
    }
    
    

    public void actionPerformed(ActionEvent evt)
    {
       System.out.println("Menüeintrag" + evt.getSource()+ "gewählt");
       // Code
    }
    
    public static void main(String[] arg)
    {
        new SimpleTableFrame();
    }
}
 
Hm, warum finde ich das dann bei mir nirgendwo? Ich benutze Eclipse, müsste ich das dann nicht auf der Console finden?

@foobar

Danke für's Aufräumen, werde das bei mir auch gleich mal machen. 🙂
 
Jo, eigentlich schon. Versuch mal die Console ganz zu schließen und starte dann deine Anwendung aus Eclipse heraus nochmal.
 
Ok... Anscheinend war ich einfach zu doof, jetzt steht es bei mir plötzlich auch da.

Kann mir jemand einen Tipp geben, wie ich am besten feststelle, auf welchen Menüeintrag geklickt wurde? Ich möchte bei "öffnen" gern einen FileChooser öffnen. Ich mach sowas zum ersten Mal und bin ein bisschen am Schwimmen.
 
Da gibt es mehrere Möglichkeiten:
- für jeden Menüeintrag einen anonymen ActionListener implementieren:

Code:
mniFoo = new JMenuItem("Foo");
mniFoo.addActionListener(new ActionListener()
{
   public void actionPerformed(ActionEvent e)
  {
     // do something
  }
}

- du hast einen globalen ActionListener, so wie du das auch gemacht hast. Dann mußt du jedem MenuITem einen ActionCommend geben und in der actionPerformed-Methode überprüfen welcher ActionCommand übergeben wurde.

Ich finde die Variante mit den anonymen Klassen am überscihtlichsten, aber das ist Geschmacksache.
 
Vielen Dank für die Hilfe. Ich denke, ich versuche es mal mit dem anonymen ActionListener, der scheint mir für den Moment auch übersichtlicher.
 
Also ich mach das immer mit einem ActionListener, der entweder eine anonyme oder eine innere Klasse ist. Man kann sich auch eine Action bauen, aber das find ich persönlich übertrieben. Also zum Beispiel sähe das mit dem Datein öffnen so aus:
Code:
public Menubar extends JMenubar {

    private JMenuItem open;

    public Menubar() {
        open= new JMenuItem("Öffnen");
        open.addActionListener(new OpenAction());
        add(open);
    }

    class OpenAction implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            JFileChooser fc = new JFileChooser();
            if (chooser.showOpenDialog(mainFrame)!=JFileChooser.APPROVE_OPTION) {
		return false;
            }
            // machste was...
        }
    }
}

Die innere Klasse kannst du natürlich auch als anonyme modellieren, wenn nicht ganz so viel drinn steht.
 
*jetzt doch mal registriert*

Also ich habe das jetzt so geschrieben:

Code:
MenOpenFile.addActionListener(new ActionListener(){
					public void actionPerformed(ActionEvent e) 
					  { 
						System.out.println("Anonym: Menüeintrag: " + e.getSource()+ "gewählt");
						JFileChooser FileChooser = new JFileChooser(path);
						int returnVal = FileChooser.showOpenDialog(null);
						if (returnVal == JFileChooser.APPROVE_OPTION)
						{
							//do whatever
						}
						// do something 
					  }
				});

Was ist da besser?
 
Ah, jetzt ja! 🙂

Naja, der meiste Code liegt ja wahrscheinlich im APPROVE-Zweig, während wenn der Benutzer abbricht, kaum etwas passieren sollte. Deshalb hab breche ich ab, wenn der Benutzer Abbruch drückt, damit ich nicht so viel eingerückten Code habe (die heilige 80 Zeichen Grenze!) 😉

Derselbe Grund liegt auch bei der Bevorzugung der inneren Klasse zu Grunde. Außerdem kannst du den Listener auch nochmal für z.B. einen Toolbar-Button wiederverwenden.

Das mit dem Zwischenspeichern des Rückgabewerts ist natürlich auch noch sinnvoll, da hab ich einfach mal ein bissel geschludert, aber damit kann man natürlich auch die 80 Zeichen einhalten ohne hässliche Zeilenumbrüche.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben