Zugriff auf Objekt einer anderen Klasse

Hallo,

ich bin absoluter Anfänger und habe schon ein Problem mit meinem ersten Programm.
Folgendes Problem:
Ich habe 2 Klassen. In Klasse 1 habe ich ein Textfeld mit dem Inhalt “hallo”, welches sich in einem Dialog befindet. Diesen Inhalt möchte ich über einen Button (btn7) in Klasse 2 auslesen. Das funktioniert auch soweit. Anschließend soll der Wert des Textfeldes neu gesetzt werden - auf “8”. Auch das funktioniert. Wie schaffe ich es aber nun, dass das Textfeld in Klasse 1 aktualisiert wird? Nachdem der Button betätigt wurde, soll sich der Wert im Textfeld von “hallo” auf “8” ändern. Ich möchte es nicht nur in der Konsole ausgeben, sondern es direkt im Dialog sehen. Geht das irgendwie?
Über Hilfe wäre ich sehr dankbar!

Klasse 1

   
    private JTextField txtPersnr = new JTextField("hallo");
       
    public void setTxtPersnr(JTextField neu1){
        txtPersnr = neu1;}
   
    public JTextField getTxtPersnr(){
        return txtPersnr;}
 
    public void actionPerformed(ActionEvent eingabeoeffnen) {
   
    GridLayout gdl = new GridLayout(0,2);  
    JPanel pnlEingabe = new JPanel();
        pnlEingabe.setBackground(Color.WHITE);
        pnlEingabe.setLayout(gdl);
        dlgEingabe.setTitle("Erfassung");
        dlgEingabe.add(pnlEingabe);
        dlgEingabe.setSize(800,800);
       
    JTextField beschriftungDatum = new JTextField("Erfassungsdatum");
        beschriftungDatum.setEditable(false);
        beschriftungDatum.setBackground(Color.WHITE);
        beschriftungDatum.setFont(new Font("Titel",10,15));  
       
    Date zeit = new Date();
        SimpleDateFormat aktuell = new SimpleDateFormat("dd.MM.yyyy");
        JFormattedTextField txtDatum = new JFormattedTextField();
            txtDatum.setText(aktuell.format(zeit));
            txtDatum.addMouseListener(new Kalender());

    JTextField tlPersnr = new JTextField("Personalnummer");
        tlPersnr.setEditable(false);
        tlPersnr.setBackground(Color.WHITE);
        tlPersnr.setFont(new Font("Titel",10,15));          
       
        txtPersnr.addMouseListener(new Nummernblock());
   
    JTextField beschriftungProdDatum = new JTextField("Produktionsdatum");
        beschriftungDatum.setEditable(false);
        beschriftungDatum.setBackground(Color.WHITE);
        beschriftungDatum.setFont(new Font("Titel",10,15));  
       
    JTextField prodDatum = new JTextField();
        prodDatum.setBackground(Color.WHITE);
        prodDatum.addMouseListener(new Kalender());
       
    JTextField beschriftungAnlage = new JTextField("ANlage");
        beschriftungAnlage.setEditable(false);
        beschriftungAnlage.setBackground(Color.WHITE);
        beschriftungAnlage.setFont(new Font("Titel",10,15));  
       
    pnlEingabe.add(beschriftungDatum);
    pnlEingabe.add(txtDatum);
    pnlEingabe.add(tlPersnr);
    pnlEingabe.add(txtPersnr);
    pnlEingabe.add(new JTextField ("Artikelnummer"));
    pnlEingabe.add(new JTextField (" "));
    pnlEingabe.add(new JTextField ("Arbeitsauftrag"));
    pnlEingabe.add(new JTextField (" "));
    pnlEingabe.add(beschriftungProdDatum);
    pnlEingabe.add(prodDatum);
        dlgEingabe.setVisible(true);
 
    }  
       
}```

Klasse 2

```public class Nummernblock extends Eingabe_oeffnen implements MouseListener  {
   
    Eingabe_oeffnen nummerObjekt = new Eingabe_oeffnen();  
   
    public void mouseClicked(MouseEvent a) {
               
    JPanel pnlZahlenblock = new JPanel();
    pnlZahlenblock.setBackground(Color.WHITE);
    pnlZahlenblock.setLayout(null);

    JButton btn7 = new JButton("7");
    pnlZahlenblock.add(btn7);
    btn7.setBounds(50,50,60,60);
    btn7.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
           
            if(e.getSource () == btn7){
               
                System.out.println("aktueller Wert im TextFeld:" +nummerObjekt.getTxtPersnr().getText());
                nummerObjekt.setTxtPersnr(new JTextField("8"));
                System.out.println("neuer Wert im TextFeld:"+nummerObjekt.getTxtPersnr().getText());

    JDialog dlgNummer = new JDialog();
    dlgNummer.add(pnlZahlenblock);
    dlgNummer.setTitle("Nummernblock");
    dlgNummer.setSize(380,400);
    dlgNummer.setResizable(false);
       
    dlgNummer.setVisible(true);
   
       
    }
   

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub
       
    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub
       
    }

    @Override
    public void mousePressed(MouseEvent e) {
        // TODO Auto-generated method stub
       
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub
       
    }

}```

Moin,
mit

nummerObjekt.setTxtPersnr(new JTextField(„8“));
übergibst Du ja keinen Text sondern ein TextFeld-Objekt, was natürlich Quark ist … es wird ja nirgendwo hinzugefügt !!
Ändere mal Deine „setTxtPersnr“-Methode dahingehend, da hier nur ein String übergeben wird und dieser dann mit .setText auf Dein Textfeld!
Gruß Klaus

Hallo Klaus,
danke für deine schnelle Antwort.

Mit der Übergabe eines Strings hatte ich es schon versucht aber ebenfalls nicht sehr erfolgreich.

In Klasse 1 habe ich nun folgende Get/Set Methoden eingefügt:


public String test = "hallo";
	
public void setTest(String neu){
test = neu;}
	
public String getTest() {
      return test;}

Klasse 2 habe ich wie folgt erweitert:


nummerObjekt.setTest("8888");
String tmp = nummerObjekt.getTest();
nummerObjekt.txtPersnr.setText(tmp);

In der Konsole wird der Wert von tmp korrekt ausgegeben, jedoch ändert sich nichts im Textfeld der Klasse 1. Es steht weiterhin “hallo” da.

Nummernblock erbt von Eingabe_oeffnen, ist also selber ein Eingabe_oeffnen,
und hat noch ein Attribut nummerObjekt vom Typ Eingabe_oeffnen,

es gibt also zwei Eingabe_oeffnen-Objekte, das ist immer schlecht

ach, es gibt sogar noch mehr, Eingabe_oeffnen erzeugt ja noch ein Nummernblock,


also, da gibt es zunächst ein Objekt A Eingabe_oeffnen, das wird anscheinend auch irgendwann zum angezeigten Dialog verwendet,

dabei wird Objekt B Nummernblock erstellt, welches auch sofort einen Dialog öffnet,
Objekt B erstellt sich intern ein Object C Eingabe_oeffnen, welches keinen darstellten Dialog hat

beim Listener in B wäre es nun falsch, in B selber die geerbten Textfelder zu setzen, genauso falsch im sinnlosen Objekt C etwas zu setzen,
du brauchst Zugriff auf das angezeigte Objekt A


Lösung:

  • Nummernblock besser nicht von Eingabe_oeffnen erben lassen, versuche es mal zu entfernen, wenn es Fehler gibt dann evtl. noch nötig, aber schauen was genau gebraucht wird,
    Vererbung zwischen GUI-Objekten/ sonstigen besser nur einmal instanziierten Klassen ist ein Karinalfehler, merken

  • Nummernblock darf auf keinen Fall ein eigenes Eingabe_oeffnen-Objekt anlegen,
    irgendwo eigene Instanzen von GUI-Objekten/ sonstigen besser nur einmal instanziierten Klassen ist ein Karinalfehler, merken
    (eine Stelle muss freilich Eingabe_oeffnen anlegen, eine wichtige Stelle, aber nicht die kleinen sonstigen Klassen)

  • bei Erstellung des Nummernblocks B von A aus muss A sich selber mit übergeben: new Nummernblock(this),
    damit kann B sich A merken, den Parameter im Konstruktor durchaus in der Variablen ablegen, die bisher für C gedacht war,
    damit später auf A zugreifen

Ohje, du erstellt in actionPerformed() ein neues / mehrere neue JTextField jtf; selbst, wenn du der Variable txtPersNr ein neues Objekt zuweist (das passiert hier nicht), ändert das überhaupt nix an dem bei JPanel pnlEingabe hinterlegtem jtf.

Stattdessen erstellt du etwas, ich möchte es mal Schattenkopie nennen.

Ok, du bist Anfänger, dann will ich dir mal verzeihen.

8888 kannst du eintragen, wenn du einfach nur .setText() auf der Variable jtf (im / nach EDT) aufrufst.

freundliche Grüße

Gut, dass Du noch ganz am Anfang bist, da können wir gleich ein paar grundsätzliche Dinge richtig stellen, bevor Du sie Dir falsch angewöhnst:

  1. Namenskonventionen:
    In Java wenden alle Bezeichner ohne Unterstriche gebildet (es gibt Ausnahmen, aber mit automatisierten Tests will ich Dich noch nicht stressen)

  2. *Listener -Interfaces
    Die sollten nur als anonyme Klassen verwendet werden. (es sei denn der Listener ist so komplex dass eine eigen Klasse die Lesbarkeit verbessert. dann darf aber auch nichts anderes drin stehen…)

  3. Vererbung
    war ja schon angesprochen: Verebung bedeutet “ist ein”. Wenn Diese Beziehung nicht funktioniert sollte auch keine Vererbung statt finden.
    Im Allgemenen erbt man viel seltener als man meint…

  4. GUI mit MVC
    Wenn Du gleich mit Oberflächen anfängst solltest Du auch gleich eine Trennung von Model und View/Controller durchziehen.
    Konkret bedeitet das, dass den Textfeld als reines “View”-Object dem Button (der dummer Weise sowohl “View” wie auch Controller ist) unbekannt bleibt.

Ich gehe mal davon aus, dass Du mit Java8 arbeitest. Dann solltest Du auch gleich mit dem Binding-Interface arbeiten, dass genau Dein Problem löst.
https://docs.oracle.com/javase/8/javafx/properties-binding-tutorial/binding.htm

bye
TT

Danke erstmal.

Aber so richtig komme ich noch nicht weiter. Die Vererbung und das Objekt habe ich entfernt. Nur komme ich mit der this. Referenz nicht voran. Wie kann ich B nun klar machen, dass das Textfeld sich in A befindet und er dieses ändern soll?

A übergibt this an B,
B braucht dafür natürlich einen Konstruktor mit einem Parameter vom passenden Typ,
Konstruktor und Parameter bekannt?

dann das übergebene A in einem Attribut merken zur späteren Verwendung

Zum Thema gibts im Wiki/FAQ einen passenden Artikel: Zugriff: von einem Objekt zum Anderen – Byte-Welt Wiki