Grundlage für "App" und Strukturierung

Schlagdraufunschluss_124

Aktives Mitglied
Hallo! Ich versuche eine App zu programmieren, die mir meinen Notendurchschnitt ausrechnet und das alles etwas grafisch umzusetzen . Hierbei soll man seine Schulfächer und seine Noten in eine Tabelle eingeben können( Am besten wäre es wenn ich es vielleicht wie in Excel lösen könnte, sprich dass man vielleicht jedes Feld anklicken kann; Andernfalls müsste ich dann die Eingabe eben anders regeln...) Allerdings bin ich mir unsicher, wie ich das ganze Projekt strukturieren soll. Meine Idee war es eine Boot-Klasse zu erstellen, die die Hauptklasse aufruft. Hier sollte dann alles "zusammenlaufen". Vielleicht kann man die "Eingabe", sowie die Grafik in eine andere Klasse auch separieren.Und wie sollte ich die Tabelle mit den Feldern angehen (Etwa für jedes einzelne Feld ein TextField?-Das würde doch keinen Sinn machen oder ?)

Danke für eure Antworten!
 
Ich würde mal sagen, du fängst an die Funktionlität deines Models abzubilden und dann fügst du die UI hinzu. Überlege dir gut, welche UI Widgets für deine Anzeige geeignet sind und zeichne es evtl. für dich auf. Wenn du dann zufrieden bist, machen.
 
Am besten solltest du dir erstmal ein UI Mookup erstellen, wie es aussehen soll.
Dann eine Activity, die die Daten eingibt, vllt. noch eine, die am Ende das Ergebnis präsentiert.
Wozu brauchst du eine Boot Klasse?
 
Im Prinzip ja...
Ich bin hier gerade aber schon auf das erste Problem gestoßen:
1) Ich versuche, dass meine Tabelle, wo man später alles einträgt, eine variable Zeilenzahl hat-sodass der Benutzer auf Knopfdruck eine weitere Zeile hinzufügen/entfernen kann.
2)Ich hab versucht den Inhalt der Zeilen per Variablen abzugreifen, allerdings ist der String im Sysout dauernd "null"- warum??

Hier der Code:
Java:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Scanner;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableModel;

public class Tabelle extends JFrame {  
    JTable table;    
    String column2;
    static String column1;  

    public Tabelle() {    
        setLayout(new FlowLayout());      
        String[] spaltenName = {"Fach","Note"};      
        String [][] data = {
                {column1,column2}  
        };
          
        table = new JTable (data,spaltenName);
        table.setPreferredScrollableViewportSize(new Dimension(500,50));
        table.setFillsViewportHeight(true);
      
        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane);
    }
    public static void main (String [] args){
        Tabelle gui = new Tabelle();
        gui.setDefaultCloseOperation(gui.EXIT_ON_CLOSE);
        gui.setVisible(true);
        gui.setSize(600,200);      
        while(true)
            System.out.println("Zeilen"+column1);      
    }
}

PS: Achja, und warum muss ich column1 zu "static" machen-Gibts da auch ne andere Lösung?
 
Zuletzt bearbeitet von einem Moderator:
Ich dachte bisher auch, es geht um eine Android App...
Was steht denn in der Tabelle drin? Die Noten? Eier? Werde mal bitte konkreter. 😀
 
In der Tabelle sollen die Fächer und Noten selbst eingetragen werden. Ich hab schonmal am Anfang die Tabelle halt mit irgendwas befüllt, allerdings ändert sich nichts im Sysout, wenn ich selbe in der Tabelle etwas eingetragen. Sprich es kommt immer der selbe Sysout.
@JStein52 Danke für den Tipp mit der getter-Methode, die Ausgabe an sich funtioniert jetzt.

Java:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Scanner;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableModel;

public class Tabelle extends JFrame {

    JTable table;

    String column2="g";
    private String column1="f";

    public Tabelle() {

        setLayout(new FlowLayout());

        String[] spaltenName = { "Fach", "Note" };

        String[][] data = { { column1, column2 }, { "hallo", "hallo" }

        };

        table = new JTable(data, spaltenName);
        table.setPreferredScrollableViewportSize(new Dimension(500, 50));
        table.setFillsViewportHeight(true);

        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane);

    }

    public static void main (String [] args){
        Tabelle gui = new Tabelle();
        gui.setDefaultCloseOperation(gui.EXIT_ON_CLOSE);
        gui.setVisible(true);
        gui.setSize(600,200);
        while(true)
        System.out.println("Zeile"+gui.getColumn());
       
       
   
   

   
}
    public String getColumn(){
        return column1;
    }
}
 
Ich habe irgendwie immernoch dasselbe Problem🙁
Bin ich zu einfach zu blöd oder woran liegt es diesmal..
Ich dachte nämlich mit "getValueAt" greife ich nicht mehr aud das Attribut zu...
Java:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Scanner;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

public class Tabelle extends JFrame implements TableModel {

   JTable table;

   private int col = 2;
   private int row = 1;
   private Object name;
   private static Object value;

   String column2 = "g";
   private String column1 = "f";

   public Tabelle() {

       setLayout(new FlowLayout());

       String[] spaltenName = { "Fach", "Note" };

       String[][] data = { { column1, column2 }, { "hallo", "hallo" }

       };

       table = new JTable(data, spaltenName);
       table.setPreferredScrollableViewportSize(new Dimension(500, 50));
       table.setFillsViewportHeight(true);

       JScrollPane scrollPane = new JScrollPane(table);
       add(scrollPane);

   }

   public static void main(String[] args) {
       Tabelle gui = new Tabelle();
       gui.setDefaultCloseOperation(gui.EXIT_ON_CLOSE);
       gui.setVisible(true);
       gui.setSize(600, 200);
       System.out.println("Col"+gui.getColumnCount());
       System.out.println("Row"+gui.getRowCount());
       gui.ausgabe();

   }

   
   public void ausgabe() {

           System.out.println("Value" + name);
   }

   @Override
   public int getColumnCount() {
       return col;
   }


   @Override
   public int getRowCount() {
       return row;
   }

   @Override
   public Object getValueAt(int col, int row) {       // Greife ich hier immer noch auf ein Attribut zu?
       return name;
   }

   
   
   @Override
   public void addTableModelListener(TableModelListener l) {
       // TODO Auto-generated method stub
       
   }

   @Override
   public Class<?> getColumnClass(int columnIndex) {
       // TODO Auto-generated method stub
       return null;
   }

   @Override
   public String getColumnName(int columnIndex) {
       // TODO Auto-generated method stub
       return null;
   }

   @Override
   public boolean isCellEditable(int rowIndex, int columnIndex) {
       // TODO Auto-generated method stub
       return false;
   }

   @Override
   public void removeTableModelListener(TableModelListener l) {
       // TODO Auto-generated method stub
       
   }

   @Override
   public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
       // TODO Auto-generated method stub
       
   }

}
 
Ich habe irgendwie immernoch dasselbe Problem
Was auch immer das genau sein mag...
1. Deine "Tabelle" Klasse ist sowohl ein TableModel als auch ein JFrame bzw. sowohl ein Model als auch eine View. Fang damit gar nicht erst an.
2. Dein Tabelle-Klasse ist zwar ein TableModel, wird aber nie als solches verwendet.
3. Du hast zwei Instanzen von Object, nämlich "name" und "value". Beide werden nirgendwo instanziiert. Was also sollen sie anders sein als null?
Stimme @mrBrown zu: Es fehlt dir noch zu viel Verstehen, um sinnvoll eine Gui anzufangen.
 
Ok, des hab ich jetzt auch eingesehen😀
Ich find halt mit GI machts mehr Spaß...

Also, ich hab nochmal ganz von vorne Angefangen😉
Warum meckert er, dass ich es die Methode bei der Eingabe-Klasse nicht gibt?
Java:
public class Main {

    public static void main(String[]args) {
      
        System.out.println("Fachanzahl: ");
        System.out.println("Anz:"+Eingabe.class.getFachanz());//<- Ich hab doch getFachanz in der EingabeKlasse erstellt
        new Eingabe();
  
      
    }
  
  

}

Java:
import java.util.Scanner;

public class Eingabe {

   public int fachanz;
   String[] fach = new String[fachanz];

   public Eingabe() {

       Scanner scr = new Scanner(System.in);
       fachanz=Integer.parseInt(scr.next());
      

   }
  
   public int getFachanz(){
       return fachanz;
   }

}
 
Zuletzt bearbeitet:
drehe es mal um:
Code:
        Eingabe meineEingabe = new Eingabe();
System.out.println("Fachanzahl: ");
        System.out.println("Anz:"+meineEingabe.getFachanz());//<- Ich hab doch getFachanz in der EingabeKlasse erstellt
getFachanz war ja keine Klassenmethode (static)
 
Ich find halt mit GI machts mehr Spaß
Das ist primär auch keine Frage von Gui oder nicht Gui, sondern zunächst die Frage von "planvollem Vorgehen" oder "wildem rumprobieren".
Warum meckert er, dass ich es die Methode bei der Eingabe-Klasse nicht gibt?
Der Rückgabewert von Eingabe.class ist Class, und die Klasse Class hat keine Methode "getFachanz".
Entweder: mache getFachanz statisch und rufe sie über "Eingabe.getFachanz()" (geht, hat aber nix mit OOP zu tun)
oder (besser): Erzeuge eine Instanz von Eingabe() und rufe auf der Instanz "getFachanz()" auf.
 
Cool Danke😀
Es funktioniert!

Java:
public class Main {

    public static void main(String[]args) {
        System.out.println("Fachanzahl: ");
       
        Eingabe eingabe = new Eingabe();
        System.out.println("Anz:"+eingabe.getFachanz());
       
       
       
    }
   
   

}
 
So hallo mal wieder... Ich hab wieder ein Problem😀
Wie kann ich es schaffen, dass nur "Teile" vom Konstruktor aufrufe:
Ich hab nämlich mein Programm in 3 Klasse aufgeteilt: Main, Eingabe und Ausgabe.
Allerdings muss ich die ganze jetzt die ganze Zeit zwischen Ein- und Ausgabe hin-und her "switchen", damit am Ende die Konsolenausgabe stimmt
1. Mach es überhaupt Sinn, so einen Aufwand zu betreiben damit alle Klassen schön "clean" bleiben und sich nichts vermischt?(Ich könnte ja auch meine Ausgabeklasse wegwerfen und die Ausgabe zur EingabeKlasse hinzufügen)
2. Wenn es doch Sinn machen sollte, wie kann ich es dann lösen, dass nicht immer der ganze Konstrukor von z.B der EingabeKlasse aufgerufen wird, sodass meine Sysouts überhaupt nicht mehr stimmen?

Die Main:
Java:
public class Main {

    public static void main(String[]args) {
        new Ausgabe();
    }
}
Die Eingabe:
Java:
import java.util.Scanner;

public class Eingabe {

    Scanner scr;
    Eingabe ver;
    public boolean goOn;
    public int fachanz;
    String fach[];
  

    public Eingabe() {
        scr = new Scanner(System.in);
        fachanz = Integer.parseInt(scr.next());
      
        String fach[]= new String[fachanz];
        for(int i=0; i<fachanz;i++){
            fach[i]= scr.next();
            System.out.println("Fachbelegung: "+fach[i]);
        }
    }

    public int getFachanz() {
        return this.fachanz;
    }
}
Die Ausgabe:
Java:
public class Ausgabe {

   public Ausgabe() {
      
       System.out.println("Fachanzahl: ");
      
       Eingabe eingabe = new Eingabe(); // Hier wird ja ein neues Objekt erstellt und wenn ich es richtig verstanden habe ruft das Programm jetzt den Konstruktor von der Eingabe Klasse auf, arbeitet diesen ab und erst wenn er fertig ist, macht er wieder mit der Ausgabe Klasse weiter, wobei glaube ich der Fehler liegt
       System.out.println("Anz:"+eingabe.getFachanz());
       System.out.println("Fächer:");      
   }
}
Meine bisherige Konsolenausgabe:
Java:
Fachanzahl:
1//<- Hier sollte eigentlich jetzt"Anz:1" kommen
Informatik//<- Hier sollte erstmal "Fächer" kommen, damit der User weiß was er überhaupt eingeben soll.
Fachbelegung: Informatik
Anz:1
Fächer:
 
1. Ja, kann Sinn machen.

2. sowas gehört nicht in den Konstruktor, der soll nur das Objekt erstellen, und auf dem rufst du dann entsprechende Methoden auf 😉
 
Mach es überhaupt Sinn, so einen Aufwand zu betreiben damit ...
Aber in der Form wie du es hier hast macht es keinen Sinn. Die Prompts für die Eingabe gehören auf jeden Fall ein die Eingabeklasse.
Wenn du schon aufteilen willst dann alles was mit dem Einlesen von Daten zu tun hat in einer Klasse/Methode, alles was mit dem Ausgeben der Ergebnisse zu tun hat in eine andere Klasse/Methode.
 
Ok, etwa so?
Java:
import java.util.Scanner;

public class Eingabe {

    Scanner scr;
    Eingabe string;
    public boolean goOn;
    public int fachanz;
    String fach[];
   

    public Eingabe() {
   
        }

    public int getFachanz() {
        return this.fachanz;
    }
   
    public int fachanz(){
        scr = new Scanner(System.in);
        fachanz = Integer.parseInt(scr.next());
        return fachanz;
    }
   
    public void StringFilling(){
        int i;
        String fach[]= new String[getFachanz()];
        for(i=0; i<fachanz;i++){
            fach[i]= scr.next();
        }
        for (i=0;i<fachanz;i++){
            System.out.println("Fachbelegung:"+ fach[i]);
        }
    }


}

PS: Wie bekomme den Rückgabetyp für den String fach[] hin?
denn wenn ich es so mache:
Java:
    public String[] StringFilling(){
        int i;
        String fach[]= new String[getFachanz()];
        for(i=0; i<fachanz;i++){
            fach[i]= scr.next();
        }
        for (i=0;i<fachanz;i++){
            System.out.println("Fachbelegung:"+ fach[i]);
        }
        return fach[];
    }


}
dann gits einen Error(
Multiple markers at this line
- Class<fach[]> cannot be resolved to a type
- fach cannot be resolved to a type
- Syntax error, insert ". class" to complete
Expression
). So hab ich's aber im Internet gelesen - Liegt also mein Fehler?
 
Also ich habs jetzt nochmal umstrukturiert:
Java:
import java.util.Scanner;

public class Eingabe {

    Scanner scr;
    Eingabe string;
    public boolean goOn;
    public int fachanz;
    String fach[];

    public Eingabe() {

    }

    public void fachanz() {
        System.out.println("Fachanzahl: ");
        scr = new Scanner(System.in);
        fachanz = Integer.parseInt(scr.next());
    }

    public String[] StringFilling() {
        System.out.println("Fächer:");
        String fach[] = new String[getFachanz()];
        return fach;
    }

    public String[] getFach() {
        return this.fach;

    }

    public int getFachanz() {
        return this.fachanz;
    }

}
Java:
public class Ausgabe {

    public Ausgabe() {
        Eingabe eingabe = new Eingabe();
        eingabe.fachanz();
        System.out.println("Anz:" + eingabe.getFachanz());
        eingabe.StringFilling();
        for (String i: eingabe.getFach()) {
            System.out.println("Fachbelegung:" + i);
        }

    }

}
Wie kann ich jetzt allerdings das Array ausgeben lassen? Wenn ich so wie oben mache, dann wirft es eine Exception.
PS: Danke für die bisherigen Antworten. Verstehe jetzt einiges mehr😀
 
Deutlich einfacher machst du es dir, wenn Eingabe keine Instanzvariablen hat, sondern die alle nur Lokal sind 😉
 
Mmh, du meinst also ich soll alle Vars in den einzelnen Methoden deklarieren?
Dann bekomm ich ja aber Probleme mit meiner "fachanz" und mit meinem Stringarray "fach". Oder soll ich des dann einfach in der anderen Methode nochmal anlegen?
 
Du kannst die Methoden, die einlesen, einfach die entsprechenden Dinge zurückgeben lassen, wie es deine StringFilling auch schon macht.
Die Getter sind in dem Fall überflüssig
 
Welchen "Rattenschwanz"?
Entweder du willst es einlesen - dann über die Funktion, oder eben nicht.
Es spricht nichts dagegen, das eingelesene in deiner anderen Klasse zu speichern 😉
 
Mit Rattenschwanz meinte ich eigentlich, dass wenn ich die methode nochmals aufrufen würde, würden ja alle sysouts und Deklarationen usw. mitkommen obwohl ich ja nur das Ergebnis will.
Es spricht nichts dagegen, das eingelesene in deiner anderen Klasse zu speichern 😉
Das habe ich gemacht - dadurch funktioniert die AusgabeKlasse prima, aber für meine Eingabe trifft das doch nicht zu. Es würde ja keinen Sinn machen, wenn ich alle Variablen lokal in die einzelnen Methoden verfrachte, sie dann aber wieder versuch aufzurufen und in den anderen Methoden wieder abzuspeichern- Soll ich deshalb meine Vars nicht doch "extern" anlegen?
Ich hab nämlich folgendes Problem. In meiner neuen Methode HauptfachFilling(schaut, ob die eingegeben Fächer Neben oder Hauptfächer sind-> wichtig für die spätere Notengewichtung) will ich auf mein Stringarray "fach" zugreifen, allerdings kennt HauptfachFilling diese Var natürlich nicht - Wie soll ich vorgehen?
 
Mit einer Klasse, die "Daten" deines Programms enthält - Daten sind ja weder Teil der Aus-, noch der Eingabe.
Die Ein und Ausgabe kann dann auf die Daten zugreifen.

z.B. mit einer Klasse Fächer, die eine Liste (oder Array) der Haupt- und Nebenfächern enthält.
 
Ok, den Kern deiner Aussage hab ich eigentlich verstanden. Ich bin jetzt so vorgegangen:
meine Main ruft die Ausg.Klasse auf. Die Erstellt im Konstrukor eine Instanz von der DatenKlasse - Hier will eigentlich die Daten der Eingabe Klasse speichern und per GetterMethode "verfügbar" machen. Die DatenKlasse erstellt im Konstruktor dann wieder eine Instanz, die auf die EingabeKlasse verweist, aber um in der Eingabe Klasse auf die Daten der DatenKlasse zugreifen zu können, muss ich ja wieder eine Instanz in der Eingabe Klasse erstellen, was ja bedeuten würde, dass der Konstruktor der DatenKlasse 2mal aufgerufen wird- Wo liegt also jetzt mein Fehler?🙁😀
 
Weißt du warum es jetzt eine NullPointerExcetption bei Zeile 23 wirft?
Java:
import java.util.Scanner;

public class Eingabe {
    Daten daten;

    public Eingabe(Daten daten) {
        this.daten=daten;

    }

    public int fachanz() {
        int fachanz;
        Scanner scr;
        System.out.println("Fachanzahl: ");
        scr = new Scanner(System.in);
        fachanz = Integer.parseInt(scr.next());
        return fachanz;
    }

    public String[] StringFilling() {
        int i;
        Scanner scr;
        String fach[] = new String[daten.getFachanz()]; //<- NullPointerException
        scr = new Scanner(System.in);

        System.out.println("Fächer:");
        for (i = 0; i < daten.getFachanz(); i++) {
            fach[i] = scr.next();
        }
        return fach;
    }

    public boolean[] hauptFachFilling() {
        int temp = 0;
        int hauptfachanz = 5;
        String hauptfachYN;
        boolean hauptfach[] = new boolean[daten.getFachanz()];
        Scanner scr = new Scanner(System.in);
        for (int i = 0; i < daten.getFachanz(); i++) {
            System.out.println(daten.getFach() + " -> Hauptfach (ja/nein)?: ");
            hauptfachYN = scr.next();
            if (hauptfachYN.equals("ja")) {
                hauptfach[i] = true;
                temp++;
                if (temp == hauptfachanz) {
                    return hauptfach;
                }
            } else if (hauptfachYN.equals("nein")) {
                hauptfach[i] = false;
            } else {
                System.out.println("Falsche Eingabe. Programm wurde beendet!");
                System.exit(0);
            }
        }
        return hauptfach;

    }

}

PS: Es hat anscheinend irgendwas mit getFachanz() zu tun....😵
 
Liegt daran, dass deine Variable daten null ist und du versuchst darüber eine Methode aufzurufen. Wie rufst du denn den Konstruktor der Klasse Eingabe auf? Ist dort das Daten - Objekt (welches du dem Konstruktor übergibst) initialisiert?
 
Wenn du noch verrätst, was Zeile 23 ist 😉
Oh sorry, ich dachte ich hätte es markiert😳
Zeile 23 ist in der StringFilling- methode : "String fach[] = new String[daten.getFachanz()];", dort wo, wie @Robat schon gesagt hat, das erste mal die Instanz Daten "ins Spiel" kommt.

@Robat: Ich rufe den Konstruktor in der DatenKlasse so auf:

Java:
public class Daten {
   Daten daten;
   int fachanz;
   String fach[];
   boolean[] hauptfach;

   public Daten() {
   
       //Instanz auf Eingabe
       Eingabe eingabe = new Eingabe(daten);
   
       //Fachanzahl
       fachanz=eingabe.fachanz();
       getFachanz();
   
       //StringFilling
       String fach[] = new String[fachanz];
       fach = eingabe.StringFilling();
   
       //HauptfachFilling
       boolean[] hauptfach = eingabe.hauptFachFilling();
   }
   public int getFachanz(){
       System.out.println("Daten.fachanz"+fachanz);
       return fachanz;
   }
   public String []getFach(){
       return fach;
   }
   public boolean[] getHauptfach(){
       return hauptfach;
   }

}


Edit: Oh, ich hab die Zeile doch markiert🙂 Und ich hab gerade gemerkt, dass es noch nicht initialisiert wurde-> Mit was muss ichs denn initialisieren?
Edit2: Ich habs jetzt mal so initialisiert:
Java:
public class Daten {
    Daten daten;
    int fachanz;
    String fach[];
    boolean[] hauptfach;

    public Daten(Daten daten) {
        this.daten = daten;
        //Instanz auf Eingabe
        Eingabe eingabe = new Eingabe(daten);
      
        //Fachanzahl
        fachanz=eingabe.fachanz();
        getFachanz();
      
        //StringFilling
        String fach[] = new String[fachanz];
        fach = eingabe.StringFilling();
      
        //HauptfachFilling
        boolean[] hauptfach = eingabe.hauptFachFilling();
    }

Aber was soll ich jetzt eigentlich in der Main dem Konstruktor von Eingabe übergeben? Ich hab doch dort schon eine Instanz von Daten erstellt:
Java:
public class Main {
  
    public static void main(String[]args) {
        Daten daten = new Daten();                       
    }
    }

Ich kann wohl nicht der Instanz "daten" ja nicht die Instanz "daten" mitgeben...
 
Zuletzt bearbeitet:
Vermutlich so:
Code:
public class Daten {
int fachanz;
String fach[];
boolean[] hauptfach;

public Daten() {

//Instanz auf Eingabe
Eingabe eingabe = new Eingabe(this);
.
.
 

Neue Themen


Zurück
Oben