Avatar billede c88 Nybegynder
11. februar 2003 - 09:26 Der er 19 kommentarer

Kommunikation mellem objekter

Jeg har forsøgt at lave et GUI på en så objektorrienteret som muligt. Men når et obejekt laver objeter som igen laver objekter, hvordan snakker de nederste objekter med det øverste og omvendt?

I den nedestående kode skal opdaterTabel() kaldes fra et underobjekt hvorefter opdaterTabel() skal ind og læse værdier i et andet underobjekt. Hvordan gør jeg dette?

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class GUISager extends JFrame {

    private JPanel pane;
    private String sql;
   
    public GUISager() {   
       
        // Sætter indstillinger for vinduet
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) { }
       
        setTitle("Sagsarkiv");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Tilføjer "hoved"-panelet til vinduet
        pane = new pane();
        getContentPane().add(pane);
     
        // Afslutter opsætningen af vinduet og viser det
        pack();
        setVisible(true);
       
    }
   
   
    private void opdaterTabel() {
       
        System.out.println("Opdatere tabel");
        // Tjekker hvad indholdet i feltVej, feltPostNr og feltBy er ved brugt af feltVej.getText()
    }
   
    public static void main(String[] args) {
        GUISager gui = new GUISager();
    }
}


//----------------------------------------------------------------------
// pane : "hoved"-panelet hvorpå alle de andre paneler ligger
//----------------------------------------------------------------------

class pane extends JPanel {

    JPanel panelTop,panelEjendom;
    JTable tabel;
    AbstractTableModel tabelModel;
    JScrollPane scrollPane;
    TableSorter sorter;
   
    public pane() {
       
        setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
       
        panelTop = new PanelTop();
        add(panelTop);
       
        panelEjendom = new PanelEjendom();
        add(panelEjendom);
       
        // Laver tabelen
        tabelModel = new SagsTabelModel();
        sorter = new TableSorter(tabelModel);
        tabel = new JTable(sorter);
        sorter.addMouseListenerToHeaderInTable(tabel);

        scrollPane = new JScrollPane(tabel);
        tabel.setPreferredScrollableViewportSize(new Dimension(500, 300));
        add(scrollPane, BorderLayout.CENTER);

    }
}


//----------------------------------------------------------------------
// 1. PANEL - PanelTop : Det øverste panel som bla. indeholder søgeknap
//----------------------------------------------------------------------

class PanelTop extends JPanel {
   
    JButton knapSøg,knapNulstil;
   
    public PanelTop() {
        setLayout(new FlowLayout(FlowLayout.RIGHT));
       
        // Laver komponenter
        knapSøg = new JButton("Udfør søgning");         

        knapSøg.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
               
                new Thread(new Runnable() {
                    public void run() {
                        opdaterTabel(); // Skal kalde den opdaterTabel() som ligger i klassen GUISager
                    }
                }).start();
            }
        });

        knapNulstil = new JButton("Nulstil søgning");
       
        add(knapSøg);
        add(knapNulstil); 
    }
}

//----------------------------------------------------------------------
// 2. PANEL - PanelEjendom : Indeholder søgelfelter til søgning på ejendommen
//----------------------------------------------------------------------

class PanelEjendom extends JPanel {
   
    JFormattedTextField feltVej,feltPostNr,feltBy;
   
    public PanelEjendom() {
       
        // Laver søgefelter
            feltVej = new Felt(20);
            feltPostNr = new Felt(4, new PostNr());
            feltBy = new Felt(15);
           

        // Tilføjer komponenter
            add(new JLabel("Vej: "));
            add(feltVej);
            add(new JLabel("Postnr. & by: "));
            add(feltPostNr);
            add(feltBy);
    }
}
Avatar billede disky Nybegynder
11. februar 2003 - 09:48 #1
Du siger opdaterTabel() skal kaldes fra et underobjekt, men ingen klasser arver fra klassen opdaterTabel() er i. En nedarvet klasse kan altid kalde en metode i en super klasse.

Hvis det er imellem forskellige klasser, kan du lave metoderne public så kan de kaldes udefra. Hvis du ikke vil bruge denne løsning, kan du lave en mailbox i modtager klassen der så modtager en besked, der fortæller hvad den skal gøre.
Avatar billede jakoba Nybegynder
11. februar 2003 - 09:53 #2
du giver en reference til objektet med i construkctoren:
      pane = new pane( this );      // i GIUSager instansen

klassen pane laves så om så den huske sin forælder-instans

    GUISager minForelder;
    public pane( GUISager forelder ) {
        minFoerelser = forelder;
        ...
        // og den reference skal så igen med når du laver dit panelTop objekt
        panelTop instasVariabelNavn = new PanelTop( minForelder );

klassen panelTop laves om på samme vis:

    GUISager minAne;
    public pane( GUISager ane ) {
        minAne = ane;
        ...
                  public void run() {
                        minAne.opdaterTabel(); // Skal kalde den opdaterTabel() som ligger i klassen GUISager
                    }

PS: og metoden opdaterTabel skal så nok helst være public. :-)

mvh JakobA
Avatar billede jakoba Nybegynder
11. februar 2003 - 09:56 #3
Ups. linien
    public pane( GUISager ane ) {
skulle være
    public panelTop( GUISager ane ) {
Avatar billede c88 Nybegynder
11. februar 2003 - 09:59 #4
jakoba, okey det giver mening.. men er der virkelig ikke en nemmere måde?

Jeg har valgt at dele det op i alle de her objekter for at gøre det mere overskueligt.. men det bliver jo mere og mere kompelkst..

har jeg valgt at gøre det på en forkert måde?
Avatar billede c88 Nybegynder
11. februar 2003 - 10:04 #5
..men hvordan kan opdaterTabel() se værdien af feltVej i klassen PanelEjendom ?
Avatar billede c88 Nybegynder
11. februar 2003 - 10:05 #6
disky, vil du ik forklare hvad du mener med en mailbox?
Avatar billede disky Nybegynder
11. februar 2003 - 10:44 #7
det er en besked kasse man kan lægge en besked i udefra, og klassen der indeholder denne mailbox, undersøger så om der ligger noget i den, gør der det behandler den data.

På fint hedder de 'interprocess kommunikation'

Men det er nok ikke den løsning du har brug for her.
Avatar billede c88 Nybegynder
11. februar 2003 - 12:25 #8
disky, nej det tror jeg heller ikke..

For at overskueliggøre det for mig selv har jeg lavet nogle små testklasser hvori det samme problem opstår.

Jeg får en NullPointerException i testMetode()

Det er simpelthen pga. min manglende grundlæggende java-viden, men jeg har ikke kunne læse mig frem til det. Jeg ville sætte stor pris på hvis nogen fortalte mig hvad det er jeg gør forkert, og hvor jeg kan læse om det.


public class test {
 
    public objekt1 o1;
    public String t;
   
    public test() {
       
        t = "Teststreng i constructoren";
       
        o1 = new objekt1(this);
       
        System.out.println("Fra constructoren:");
        System.out.println(o1.o2.værdi);  // <-- men denne her er ok
       
    }
   
    public void testMetode() {
        System.out.println("Fra testeMetode():");
        System.out.println(o1.o2.værdi);      // <-- NullPointerException
    }
   
    public static void main(String[] args) {
        test test = new test();
    }
   
}

// Klassen hvori de 2 andre klasser laves
class objekt1 {

    public objekt2 o2;
    public objekt3 o3;
   
    public objekt1(test test) {
        o2 = new objekt2();
        o3 = new objekt3(test);
    }

}

// Klassen som indeholder værdien
class objekt2 {
   
    public String værdi;
   
    public objekt2() {
        værdi = "Teststreng";
    }
}

// Klassen som kører metoden
class objekt3 {

    public objekt3(test test) {
        System.out.println(test.t); // Det er muligt at få fat i strengen t
        test.testMetode(); // ..og det er muligt at køre en metode
    }
}
Avatar billede c88 Nybegynder
11. februar 2003 - 12:35 #9
jeg får:

Teststreng i constructoren
Fra testeMetode():
java.lang.NullPointerException
        at test.testMetode(test.java:20)
        at objekt3.<init>(test.java:57)
        at objekt1.<init>(test.java:37)
        at test.<init>(test.java:11)
        at test.main(test.java:24)
Exception in thread "main"
Avatar billede arne_v Ekspert
11. februar 2003 - 12:57 #10
Jeg kan ikke helt forklare dit problem.

Men du laver noget som du ikke bør gøre: du kalder en
ikke statisk metode i klassen test nemling testMetode inden
klassesn constructor er kørt færdig.

Det kunne måske være årsag til dit problem.
Avatar billede jakoba Nybegynder
11. februar 2003 - 13:55 #11
det er vist heller ikke lovligt at lave en parameter med samme navn som den klasse den er en instans af?
  public objekt3(test test)
Avatar billede arne_v Ekspert
11. februar 2003 - 15:16 #12
Compileren brokker sig ikke, så det er sikkert to name-spaces.

Men det er ihvertfald forvirrende.

Java code convention siger:
  - class navne skal starte med stort
  - member/metode/variabel navn skal starte med småt
Avatar billede jakoba Nybegynder
11. februar 2003 - 15:33 #13
Hey, det er jo indlysende:
        o1 = new objekt1(this);
o1 har ikke nogen værdi før den constructor er udført. og derfor må constructoren naturligvis heller ikke kalde en metode der ønsker at bruge den.

mvh JakobA
Avatar billede jakoba Nybegynder
11. februar 2003 - 15:51 #14
public class test {

    public objekt1 o1;
    public objekt1 o1a;
    public String t;
 
    public test() {
     
        t = "Teststreng i constructoren";
     
        o1 = new objekt1(this);    // fejler for o1 findes ikke endnu
        o1a = new objekt1(this);    // går godt for nu findes 01
     
        System.out.println("Fra constructoren:");
        System.out.println(o1.o2.værdi);  // <-- men denne her er ok
     
    }
 
    public void testMetode() {
        System.out.println("Fra testeMetode():");
        System.out.println(o1.o2.værdi);      // <-- NullPointerException
    }
 
    public static void main(String[] args) {
        test itest = new test();
    }
 
}

// Klassen hvori de 2 andre klasser laves
class objekt1 {

    public objekt2 o2;
    public objekt3 o3;
 
    public objekt1(test itest) {
        o2 = new objekt2();
        o3 = new objekt3(itest);
    }

}

// Klassen som indeholder værdien
class objekt2 {
 
    public String værdi;
 
    public objekt2() {
        værdi = "Teststreng";
    }
}

// Klassen som kører metoden
class objekt3 {

    public objekt3(test itest) {
        System.out.println(itest.t); // Det er muligt at få fat i strengen t
        if ( itest.o1 != null ) {                            // TILFØJET BETINGELSE
            System.out.println("Kalder testeMetode():");      // TILFØJET linie
            itest.testMetode(); // ..og det er muligt at køre en metode
        }
    }
}
Avatar billede c88 Nybegynder
11. februar 2003 - 20:41 #15
jakoba, ahh ja.. det er jo klart.. eller, ja - det er altid indlysende efter man har gennemskuet det ;)

Det gjorde det lige en smule nemmere at gennemskue efter jeg fik opstilt testobjekterne..

Men mange tak for hjælpen :)

Det virker til at du har styr på din java.. kan du ikke anbefale en god generel bog (med lidt JDBC og swing evt.) som ikke starter på et alt for lavt niveau? og evt. en bog om OO analyse og design? så må jeg lige smide nogle ekstra point oven i..
Avatar billede arne_v Ekspert
11. februar 2003 - 20:51 #16
svar kun med hensyn til OOAD bog>

Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and the Unified Process (2nd Edition)
by Craig Larman
Avatar billede c88 Nybegynder
12. februar 2003 - 10:08 #17
arne v, tak for anbefalingen - jeg har lige bestilt bogen.. håber jeg kan lærer en masse af den :)
Avatar billede c88 Nybegynder
12. februar 2003 - 10:09 #18
jakoba, vil du ik lave et "svar" så jeg kan lukke spørgsmålet?
Avatar billede arne_v Ekspert
12. februar 2003 - 10:18 #19
Det er en rigtig god bog. Ikke en bog som man læser på 2 timer og så har
man lært det. Men en bog som man læser - lærer noget, læser igen - lærer
noget mere etc..
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester