Aufteilen von User Interfaces?

Angiii

Erfahrenes Mitglied
Hallo,

ich bastle gerade an einem Java-Applet mit Eclipse und mit Hilfe des Visual Editors. Um den Überblick zu behalten, will ich meinen Applet-Code in mehrere Dateien aufteilen. Hauptelement des Applets ist eine JTabbedPane. Die einzelnen Tabs befinden sich jeweils in einzelnen Klassen und werden dann in der JTabbedPane zusammengeführt. Vom Grundaufbau funktioniert dies auch. Im ersten Tab befindet sich Buttons, die die Kommunikation zum Endgerät herstellen (z.B. Connect). In den restlichen Tabs sollen sich verschiedene Eigenschaften des Geräts einstellen lassen.

Jedoch habe ich Probleme bei der Interaktion von Funktionen zwischen den einzelnen Tabs (die Tabs arbeiten nicht zusammen). Nun will ich zum Beispiel in Tab1 eine Verbindung zum Gerät herstellen. Tab2 soll die Verbindung von Tab1 nutzen, um Nutzdaten zu übertragen. Jedoch schaffe ich es nicht, dass Tab2 auf die Verbindung von Tab1 zugreifen kann. Wenn ich das gesamte Applet in nur einer Klasse mache, stellt sich das Problem nicht, jedoch wird mir das zu unübersichtlich.

Ich dachte ich könnte mein Ziel durch Vererbung (tab2 extends tab1) erreichen, leider funktioniert das nicht. Wäre toll wenn mir jemand einen Tipp geben könnte! Arbeite erste seit zweieinhalb Wochen mit Java und habe noch nicht alle Geheimnisse dieser Sprache durchschaut (komm eigentlich aus der C-Ecke icon_wink.gif ).

Hier mal ein Auszug meines Codes:

Code:
public class tab1  {
   
   public JPanel jPanelTab1 = null; 
   private JButton Connect = null;
   
   public Communication XPort;  //  In der Klasse Communication befindet sich alles was zum Verbindungsaufbau und zur Datenübertragung benötigt wird.

   public JPanel getJPanelTab1() {
      if (jPanelTab1 == null) {
         jPanelTab1 = new JPanel();
         jPanelTab1.setLayout(null);
              jPanelTab1.add(getConnect(), null);

      }
      return jPanelTab1;
   }

        // Durch das Drücken des Connect Buttons auf Tab1 wrid eine Verbindung hergestellt
   private JButton getConnect() {
      if (Connect == null) {
         Connect = new JButton();
         Connect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent e) {
               System.out.println("actionPerformed()");
            XPort = new Communication();   // <---------                     
               try {
                  XPort.connect("192.168.68.146", 10001); // öffnet Verbindung zu XPort
               } catch (Exception Ex) {
                  System.out.println("Error while connecting: " + Ex);
               }
         
            }
         });
      }
      return Connect;
   }
   
}


public class tab2 extends tab1{
      
   private byte functionID, value;
      
   private JPanel jPanelTab2 = null;  //  @jve:decl-index=0:visual-constraint="152,64"
   private JSlider BackLight = null;
         
   public byte [] sendbuf(){
      
      byte[] array = new byte [3];
      
      array[0] = -11
      array[1] = 0x08;
      array[2] = value;
         
      return array;   
   }
   

   public JPanel getJPanelTab2() {
      if (jPanelTab2 == null) {
         jPanelTab2 = new JPanel();
         jPanelTab2.setLayout(null);
         jPanelTab2.add(getStart(), null);
         
      }
      return jPanelTab2;
   }
   
     
   private JSlider getBackLight() {
      if (BackLight == null) {
         BackLight = new JSlider(JSlider.HORIZONTAL,1,100, 20); // Slider-Wertebereich
         
         BackLight.addChangeListener(new javax.swing.event.ChangeListener() {
         
                        public void stateChanged(javax.swing.event.ChangeEvent e) {
               
         byte[] sendarray = sendbuf();   
         value = (byte) BackLight.getValue();
               
         try{
         XPort.send(sendarray);   // Überträgt Array an XPort, soll Verbindung aus Tab1 nutzen!
         
         } catch (Exception ex){System.out.println("txtfehl");}
            
            
            }
         });
      
      }
      return BackLight;
   }

}
 
Nun, irgendwer sollte alle Tabs (bzw. die Klassen und deren Aufgabe) kennen.
Diesen *Jemanden* fragtste einfach nach (z.b) der Connection.
 
Ja, so ungefähr war auch mein Grundgedanke, aber mit der Umsetzung haberts noch. Die zur Kommunikation benötigten Funktionen befinden sich in einer separaten Klasse namens "Communication".

Diese Klasse binde ich mit
public Communication XPort;
XPort = new Communication();

im ersten Tab ein und stelle dort dann mit XPort.connect("192.168.68.146", 10001); eine Verbindung zum Gerät her (hier handelt es sich um einen Lantronix XPort....).

Diese Verbindung will ich nun an Tab2 weitergeben um dort mit dem Befehl XPort.send(sendarray); Daten senden zu können. Nun kann ich die Verbindung aus Tab1 nicht ohne weiteres in Tab2 nutzen. Ich dachte ich könnte in Tab2 einfach Tab1 mit folgendem Code einbinden:
Code:
public tab1 nutzeTab1; // Einbinden von Tab1

nutzeTab1.XPort.send(sendarray); // Funktion die ausgeführt werden soll mit Verwendung der Verbindung aus Tab1

Leider funktionierte das nicht. Mein Gedanke war, dass Tab2 einfach eine Unterklasse von Tab1 sein soll und ich dann die Verbindung aus Tab1 nutzen kann.
 
in deiner hauptklasse (wo dein jtabbedpane) drin ist, hast du doch zugriff auf beide tabs. übergib diese klasse doch als Parent an deine tabs. bau 2 methoden ein:
setConnection
getConnection

in tab1 setzt du die connection in den Parent mit parent.setConnection

in tab2 kannst du dir die connection dann mit parent.getConnection aus dem Parent holen.

hoffe das hilft
 
so wie in deinem Code wird es nicht funktionieren.
Das wird ja nix zugewiesen.
(Klassennamen bitte IMMER mit einem großen Buchstaben beginnen!)

die Klasse, die beide Tabs kennt, könnte doch tab2 von tab1 berichten...
Java:
tab2.setConnectionTab(tab1);
 
Dein Problem liegt ja nicht an Java direkt, sondern an der Struktur deine Programms!
Wichtig ist, so löse ich solche Probleme immer, dass du eine gobale Klasse hast, die alles aufruft! Bei dir sollte das die appletKlasse sein!
Wichtig ist auch, dass du GUI und Funktionalität komplett trennst
Die Tabs sollten wirklich nur Methoden der Hauptklasse aufrufen!
Auch wenn du alles gerne extigrierst, dann musst du Funktionen bereitstellen, die das an die jeweiligen Klassen weiterleitet. Im Netzwerk nennt sich sowas Middleware... Alle anderen Klassen, sollten dann einen Verweis auf diese Hauptklasse haben!

Am besten du skizzierst dir sowas vorher... :google: UML

Guck dir UML mal an! Damit plant man sowas!

Hoffe das hat dir geholfen!
 
Also Bodo, zuerst fand ich deine Antwort wenig hilfreich, da ich nicht ganz verstand was du mir sagen wolltest. Als dann aber nichts voran ging, hab ich mich doch einmal mit dem UML-Modell beschäftigt und das Ganze skizziert. Und plötzlich verstand ich, worauf ihr alle raus wolltet und wieso mein ursprünglicher Programmaufbau nie funktionieren konnte.

Hab das ganze jetzt wie folgt gelöst:
In meinen einzelnen Tab-Klassen befindet sich jetzt nur noch der Code für die Initialisierung der Grafikelemente. Die gesamte Funktionalität läuft über einen ActionListener in der Hauptklasse, welcher dann auch die einzelnen Tabs ansteuert. Die zur Kommunikation nötigen Funktionen befinden sich wieder in einer extra Klasse.

Vielleicht lässt es sich noch schöner umsetzen, aber im Moment find ich meinen Code voll in Ordnung, da er jetzt endlich ein bißchen übersichtlicher ist.
Vielen Dank euch allen für Eure Hilfe!
 
Hi Angii,

danke für dein Feedback!
Größere Projekte erfodern meist eine bisschen Planung!
Wenn man die nötige Übersicht hat, geht alles ganz einfach!
Und das praktische ist, das lässt sich in allen Lebenslagen und Programmierspreachen verwenden, und: Du hast dein Problem allein gelöst!

Gratulation und noch viel Erfolg beim Programmieren!!
 
Zurück