Superclass und Subclass

Status
Nicht offen für weitere Antworten.

clou

Mitglied
Hallo,
ich habe eine Prüfungsaufgabe bekommen, bei der ich nicht mehr weiter weiß. Keine Sorge, ich will nicht, dass die mir jemand löst. Da aber der Java-Kurs auf Schwedisch ist habe ich wohl einige fundamentäre Regeln nicht ganz begriffen, finde aber auch im Internet nicht die richtige Lösung, obwohl ich seit 5 (!!!) Tagen suche und Prüfungsabgabe ist Freitag :-(
Deshalb der letzte Versuch über das Forum hier.

Aufgabe ist eine Benutzerschnittstelle zu entwerfen, die zwei Menüs hat mit insgesamt 3 Menü Items (Beenden, Text hinzufügen und Text löschen). Dann noch weitere Aufgaben, die für meine Frage hier aber nicht relevant sind.

Es sollen zwei Dateien erstellt werden. Die erste Datei mit dem Menü und die zweite Datei mit dem Rest. Die Benutzerschnittstelle mit den Menüs hab ich schon mal. Auch das Beenden-Menü funktioniert.

Meine Superclass ist der Rahmen mit den Menüs.
Meine Subclass ist der Rest mit Textfeld, Textarea und Buttons.

Jetzt ist es so, dass ich die Funktion für das Beenden in meiner Superclass habe. Ich will sie aber in meiner Subclass haben. Der Grund ist der, dass, wenn dieses Problem gelöst ist, dass ich mich dann erst an die anderen Menü Items wagen kann, weil ich hierzu die Variabeln aus der Subclass brauche. Und wenn ich weiß, wie ich die Beenden-Funktion in meiner Subclass anwende, dann krieg ich vielleicht auch noch den Rest der Aufgabe hin.

Der Code für die Superclass:

Code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Ramen extends JFrame
{
    private JTextField tx1;
    private String text1;
    private JMenuBar mbar;
    private JMenu meny1, meny2;
  	private JMenuItem item1, item2, item3;


  public Ramen()
  {

	  JPanel panel1 = new JPanel();
	  JPanel panel2 = new JPanel();
	  JMenuBar mbar = new JMenuBar();
	  JMenu meny1 = new JMenu("Arkiv");
	  JMenu meny2 = new JMenu("Info");
	  JMenuItem item1 = new JMenuItem("Avsluta");
	  JMenuItem item2 = new JMenuItem("Lägg till text");
	  JMenuItem item3 = new JMenuItem("Radera text");

      setJMenuBar(mbar);
      mbar.add(meny1);
      mbar.add(meny2);

      meny1.add(item1); meny2.add(item2); meny2.add(item3);

       Container c = getContentPane();
       c.setLayout(new GridBagLayout());

       c.setBackground(Color.WHITE);
       setDefaultCloseOperation(EXIT_ON_CLOSE);
       setVisible(true);
       pack();

//---------------------------
//das hier will ich in meiner Subclass unterbringen:
  item1.addActionListener
        (
            new ActionListener()
            {
                public void actionPerformed( ActionEvent event )
                {
                    System.exit( 0 );
                }
            }
        );
//---------------------------

   }





   public static void main(String [] args)
   {
       Ramen ram = new Ramen();
   }
}

Der Code für die Subclass:

Code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;



public class Projekt extends Ramen
{
    private JTextField tx1;
    private String text1;
    private JMenuBar mbar;
    private JMenu meny1, meny2;
  	private JMenuItem item1, item2, item3;

void buildConstraints(GridBagConstraints gbc, int gx, int gy,
        int gw, int gh, int wx, int wy) {

        gbc.gridx = gx;
        gbc.gridy = gy;
        gbc.gridwidth = gw;
        gbc.gridheight = gh;
        gbc.weightx = wx;
        gbc.weighty = wy;
    }


  public Projekt()
  {

	//JTextField textfält;
	//JTextArea textarea;
	//JButton knapp1, knapp2, knapp3;
	JScrollPane scrollyta;
	JLabel lbl1, lbl2, lbl3;
	ImageIcon bild1, bild2;
	text1=("test");

setSize(500, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints constraints = new GridBagConstraints();
        JPanel pane = new JPanel();
        pane.setLayout(gridbag);

        // textfield
        buildConstraints(constraints, 0, 0, 5, 1, 100, 0);
        constraints.fill = GridBagConstraints.HORIZONTAL;
        JTextField textfält = new JTextField();
        gridbag.setConstraints(textfält, constraints);
        pane.add(textfält);

        // tomt platshåller
        buildConstraints(constraints, 0, 1, 1, 1, 0, 0);
        constraints.fill = GridBagConstraints.NONE;
        constraints.anchor = GridBagConstraints.EAST;
        JLabel label1 = new JLabel("                    ", JLabel.LEFT);
        gridbag.setConstraints(label1, constraints);
        pane.add(label1);

		// knapp1
        buildConstraints(constraints, 1, 1, 1, 1, 0, 0);
        constraints.fill = GridBagConstraints.NONE;
        constraints.anchor = GridBagConstraints.CENTER;
        JButton knapp1 = new JButton("Bild 1");
        gridbag.setConstraints(knapp1, constraints);
        pane.add(knapp1);

		// knapp2
        buildConstraints(constraints, 2, 1, 1, 1, 0, 0);
        constraints.fill = GridBagConstraints.NONE;
        constraints.anchor = GridBagConstraints.CENTER;
        JButton knapp2 = new JButton("Bild 2");
        gridbag.setConstraints(knapp2, constraints);
        pane.add(knapp2);

        // knapp3
		buildConstraints(constraints, 3, 1, 1, 1, 0, 0);
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.CENTER;
		JButton knapp3 = new JButton("Text area");
		gridbag.setConstraints(knapp3, constraints);
        pane.add(knapp3);

        // textarea
        buildConstraints(constraints, 0, 2, 5, 10, 100, 100);
		constraints.fill = GridBagConstraints.BOTH;
		JTextArea textarea = new JTextArea();
		gridbag.setConstraints(textarea, constraints);
        pane.add(textarea);


        // Content Pane
        setContentPane(pane);
        setVisible(true);

//---------------------------
//hier habe ich versucht den Code reinzusetzen
item1.addActionListener
        (
            new ActionListener()
            {
                public void actionPerformed( ActionEvent event )
                {
                    System.exit( 0 );
                }
            }
        );
//---------------------------

      textarea.setText( text1 );

   }

   public static void main(String [] args)
   {
       Projekt test = new Projekt();
   }
}

Kompiliert wird das Ganze ohne Fehlermeldung, funktioniert aber nicht, sobald ich diesen Code aus meiner Superclass entferne. Wo liegt mein Denkfehler? Was mache ich falsch? Es wäre echt klasse, wenn mir jemand weiterhelfen könnte und ich verneige mich demütig. Danke schon mal.

Liebe Grüße
Clou
 

oldshoe

Bekanntes Mitglied
So...bei mir geht das jetzt...
erstmal entferne die mainmethode aus der ramen-klasse...es wird schließlich nur die in der projektklasse aufgerufen...das löst aber dein problem nicht ;)

dann in der ramen klasse
public JMenuItem item1, item2, item3;
weil auf private nicht zugegriffen werden kann, von der erbenden klasse...

dann entferne
private JMenuItem item1, item2, item3;
aus der erbenden projekt-klasse, denn damit überdefinierst du die variablen aus der superklasse

achja und schließlich den addactionlistener-kram aus der superklasse noch raus

sollte funktionieren
 

clou

Mitglied
Hallo oldshoe,
vielen Dank für deine Tipps. Das klingt alles logisch und ich habe die Änderungen vorgenommen, wie von dir vorgeschlagen. Dennoch beendet sich das Programm nicht wenn ich auf den Menüeintrag "Avsluta" klicke. Hast du vielleicht irgend etwas in der Beschreibung vergessen? Oder habe ich etwas falsch gemacht?

Hier nochmal die Codes, nach der Änderung:

Superclass:
Code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Ramen extends JFrame
{
    public JTextField tx1;
    public String text1;
    public JMenuBar mbar;
    public JMenu meny1, meny2;
  	public JMenuItem item1, item2, item3;


  public Ramen()
  {

	  JPanel panel1 = new JPanel();
	  JPanel panel2 = new JPanel();
	  JMenuBar mbar = new JMenuBar();
	  JMenu meny1 = new JMenu("Arkiv");
	  JMenu meny2 = new JMenu("Info");
	  JMenuItem item1 = new JMenuItem("Avsluta");
	  JMenuItem item2 = new JMenuItem("Lägg till text");
	  JMenuItem item3 = new JMenuItem("Radera text");

      setJMenuBar(mbar);
      mbar.add(meny1);
      mbar.add(meny2);

      meny1.add(item1); meny2.add(item2); meny2.add(item3);

       Container c = getContentPane();
       c.setLayout(new GridBagLayout());

       c.setBackground(Color.WHITE);
       setDefaultCloseOperation(EXIT_ON_CLOSE);
       setVisible(true);
       pack();
   }

}

Subclass:
Code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;



public class Projekt extends Ramen
{

void buildConstraints(GridBagConstraints gbc, int gx, int gy,
        int gw, int gh, int wx, int wy) {

        gbc.gridx = gx;
        gbc.gridy = gy;
        gbc.gridwidth = gw;
        gbc.gridheight = gh;
        gbc.weightx = wx;
        gbc.weighty = wy;
    }

  public Projekt()
  {
	//JTextField textfält;
	//JTextArea textarea;
	//JButton knapp1, knapp2, knapp3;
	JScrollPane scrollyta;
	JLabel lbl1, lbl2, lbl3;
	ImageIcon bild1, bild2;
	text1=("test");

setSize(500, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints constraints = new GridBagConstraints();
        JPanel pane = new JPanel();
        pane.setLayout(gridbag);

        // textfield
        buildConstraints(constraints, 0, 0, 5, 1, 100, 0);
        constraints.fill = GridBagConstraints.HORIZONTAL;
        JTextField textfält = new JTextField();
        gridbag.setConstraints(textfält, constraints);
        pane.add(textfält);

        // tomt platshåller
        buildConstraints(constraints, 0, 1, 1, 1, 0, 0);
        constraints.fill = GridBagConstraints.NONE;
        constraints.anchor = GridBagConstraints.EAST;
        JLabel label1 = new JLabel("                    ", JLabel.LEFT);
        gridbag.setConstraints(label1, constraints);
        pane.add(label1);

	// knapp1
        buildConstraints(constraints, 1, 1, 1, 1, 0, 0);
        constraints.fill = GridBagConstraints.NONE;
        constraints.anchor = GridBagConstraints.CENTER;
        JButton knapp1 = new JButton("Bild 1");
        gridbag.setConstraints(knapp1, constraints);
        pane.add(knapp1);

	// knapp2
        buildConstraints(constraints, 2, 1, 1, 1, 0, 0);
        constraints.fill = GridBagConstraints.NONE;
        constraints.anchor = GridBagConstraints.CENTER;
        JButton knapp2 = new JButton("Bild 2");
        gridbag.setConstraints(knapp2, constraints);
        pane.add(knapp2);

        // knapp3
	buildConstraints(constraints, 3, 1, 1, 1, 0, 0);
	constraints.fill = GridBagConstraints.NONE;
	constraints.anchor = GridBagConstraints.CENTER;
	JButton knapp3 = new JButton("Text area");
	gridbag.setConstraints(knapp3, constraints);
        pane.add(knapp3);

        // textarea
        buildConstraints(constraints, 0, 2, 5, 10, 100, 100);
	constraints.fill = GridBagConstraints.BOTH;
	JTextArea textarea = new JTextArea();
	gridbag.setConstraints(textarea, constraints);
        pane.add(textarea);

        // Content Pane
        setContentPane(pane);
        setVisible(true);

item1.addActionListener
        (
            new ActionListener()
            {
                public void actionPerformed( ActionEvent event )
                {
                    System.exit( 0 );
                }
            }
        );

      textarea.setText( text1 );

   }

   public static void main(String [] args)
   {
       Projekt test = new Projekt();
   }
}

Wäre echt super, wenn du mir nochmal helfen könntest. Vielen Dank nochmal für deine Mühe, die ich sehr zu schätzen weiß.
LG
Clou
 

Verjigorm

Top Contributor
Falsch:
Code:
JMenuItem item1 = new JMenuItem("Avsluta");
Richtig:
Code:
item1 = new JMenuItem("Avsluta");
Weil du hast ja bereits eine Variable item1 deklariert,
die du dann LOKAL neu definierst.
Dein item1 ist also in deiner Subklasse nicht initialisiert und es kommt eine NullpointerException

PS: Ist bei vielen deiner Variablen so
PPS: Variablen in der Superclass, die in der Subclass benutzt werden sollen, haben normalerweise das Schlüsselwort protected, nicht public
Oder ohne, dann ist es package-private.
 
Zuletzt bearbeitet:

clou

Mitglied
Hallo Verjigorm,

vielen lieben Dank. Es funktioniert. Jetzt hab ich aber dennoch eine Frage. Ist zwar kein Problem aber für mein Verständnis.

Warum funktioniert diese Version nicht?
Code:
public class Ramen extends JFrame
{

    public JTextField tx1;
    public String text1;
    public JMenuBar mbar;
    public JMenu meny1, meny2;

// ===============um diese Zeile geht es, hier habe ich item1 weggelassen:
    public JMenuItem item2, item3;


  public Ramen()
  {

	  JPanel panel1 = new JPanel();
	  JPanel panel2 = new JPanel();
	  JMenuBar mbar = new JMenuBar();
	  JMenu meny1 = new JMenu("Arkiv");
	  JMenu meny2 = new JMenu("Info");

// ===============und um diese:
	  JMenuItem item1 = new JMenuItem("Avsluta");
	  JMenuItem item2 = new JMenuItem("Lägg till text");
	  JMenuItem item3 = new JMenuItem("Radera text");

In diesem Fall habe ich ja NICHT item1 vorher schon deklariert. Müsste doch also auch gehen.

Wie gesagt, ist nicht überlebenswichtig. Also, wenn du Lust hast zu antworten ist das super, wenn nicht, danke dennoch für deine vorige Hilfe.

LG
Clou
 

Verjigorm

Top Contributor
item1 legst du LOKAL im Konstruktor an, wenn der Konstruktor fertig ist, dann ist item1 für dich "quasi" verloren, du kannst nichtmehr drauf zugreifen.

Die Subklasse kann zudem NICHT auf LOKALE Variablen zugreifen.
Zum Thema Klassenvariablen und lokale Variablen solltest du dich (noch)mal einlesen
 

HannsW

Bekanntes Mitglied
Code:
public class Ramen extends JFrame
{

    /* sollen die folgenden Variablen auch extern sichtbar sein?
      * dann solltest DU getter Und Setter benutzen.
      * also machen wir aus public -> privat 
      * die var sind dann == null
    **/
    private JTextField tx1;
    //oder initialisieren
    private String text1 = "";
    private JMenuBar mbar;
    private JMenu meny1, meny2;

   // ===============um diese Zeile geht es, hier habe 
   /* da Du item1 später benötigst, muss es hier deklariert werden */
   private JMenuItem item1,item2, item3;


  public Ramen()
  {
      /* die beiden Panel Zeilen gehören auch in den Klassen-body*/
      JPanel panel1 = new JPanel();
      JPanel panel2 = new JPanel();

      /* das nächste mbar ist ein anderes als das oben erklärte,
        und ist am Ende des Konstruktors nicht mehr existent */
      //falsch
      JMenuBar mbar = new JMenuBar();
      //richtig 
      mbar = new JMenuBar();
   
       /* gleiches für die Menus */
      JMenu meny1 = new JMenu("Arkiv");
      JMenu meny2 = new JMenu("Info");

// ===============und um diese:
       /* sollte jetze klar sein ? */
      JMenuItem item1 = new JMenuItem("Avsluta");
      JMenuItem item2 = new JMenuItem("Lägg till text");
      JMenuItem item3 = new JMenuItem("Radera text");

Erläuterungen im Qeulltext /*..*/
HTH Hanns
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben