Avatar billede Slettet bruger
20. maj 2004 - 13:28 Der er 30 kommentarer og
1 løsning

Begynderspørgsmål - flere klasser

Hej eksperter.

Jeg er helt ny i Java og skal bruge lidt hjælp til et lille program jeg sidder og roder lidt med.
Jeg har lavet to klasser, én der trækker nogle data ud fra en Interbase database og en anden, der opretter en JFrame (med en sampletekst).

Jeg vil nu høre om det er muligt at få vist de data jeg udtrækker fra min database i den ene klasse i dette JFrame vindue...

Min databaseklasse ser ud som følger:

import java.sql.*;

public class VisOplysninger
{
  // Metode der opretter forbindelse til databasen
  public VisOplysninger()
  {
    String url = "jdbc:interbase://localhost/d:/Test/KVU.ib";

    try
    {
      Class.forName("interbase.interclient.Driver");
      Connection conn = DriverManager.getConnection(url, "sysdba", "masterkey");
      System.out.println("Forbindelse til database er etableret!");

      // Træk alle poster ud af databasen med SQL-sætning
      Statement stmt = conn.createStatement();
      String sql = "SELECT * FROM Bruger ORDER BY Brugernavn DESC";

      // Vis alle rækker under hinanden
      ResultSet rs = stmt.executeQuery (sql);
      while (rs.next())
      {
        String brugernavn = rs.getString(1);
        String navn = rs.getString(2);
        String adgangskode = rs.getString(3);

        System.out.println("Brugernavn: " + brugernavn + " og password: " + adgangskode);
        //System.out.println("Brugernavn: " + brugernavn);
      }
      rs.close();
      conn.close();

    }
    catch(Exception e)
    {
      System.out.println("Der kunne ikke etableres forbindelse til databasen!");
    }

  }
}

Min JFrameklasse ser ud således:

import java.awt.*;
import javax.swing.*;

public class GuiLayout extends JFrame
{
  private JLabel velkomstTekst;
  private JLabel oplysninger;
  private String brugernavn;

  public GuiLayout()
  {
    super ("Dette er titlen på vinduet");
    setSize (300, 300);

    velkomstTekst = new JLabel("Dette er en test af tekst i et vindue!");

    Container content = getContentPane();
    content.setLayout(new FlowLayout());
    content.add (velkomstTekst);

    System.out.println("");
  }

  public static void main (String[] args)
  {
    GuiLayout f = new GuiLayout();
    f.show();
  }
}

Begge klasser virker fint seperat, men jeg kan altså bare ikke hitte ud af hvordan jeg får data fra recordsettet over i mit nyligt oprettede vindue.
Skal der bruges en label? Og hvordan får jeg data ind i en sådan hvis dette er tilfældet?

Håber der er nogle skarpe Javahajer der kan hjælpe :-)
Avatar billede ullesan Nybegynder
20. maj 2004 - 14:03 #1
du laver en

public static Resultset getResultset ved VisOplysninger og hiver denne metode så fra
GuiLayout med

Resultset r = VisOplysninger.getResultset()
Avatar billede Slettet bruger
20. maj 2004 - 14:09 #2
Hej ullesan,
Takker for svaret, men jeg kan ikke helt følge din tankegang :-)
Mener du at jeg skal lave en metode i VisOplysninger klassen?

Og i givet fald, hvordan skal denne se ud? Altså, hvad skal den indeholde?

Som du nok kan fornemme er jeg pænt dum ud i Java...

Håber du kan hjælpe lidt mere.
Avatar billede arne_v Ekspert
20. maj 2004 - 14:23 #3
Jeg lavede det her til et andet spørgsmål for en måneds tid siden:

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

public class SimpleDBGUI2 extends JFrame implements ActionListener {
    private JButton find;
    private JTextField crit;
    private JTextArea res;
    private DBHandler db;
    public SimpleDBGUI2() {
        getContentPane().setLayout(new BorderLayout());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 400);
        crit = new JTextField();
        getContentPane().add(crit, BorderLayout.NORTH);
        res = new JTextArea();
        getContentPane().add(res, BorderLayout.CENTER);
        find = new JButton("Søg");
        find.addActionListener(this);
        getContentPane().add(find, BorderLayout.SOUTH);
        db = new DBHandler("TestMSAccess", "Admin", "");
    }
    public void actionPerformed(ActionEvent evt) {
      res.setText("");
      ArrayList lst = db.getAll(crit.getText());
      for(int i = 0; i < lst.size(); i++) {
        res.setText(res.getText() + lst.get(i) + "\r\n");
      }
    }
    public static void main(String[] args) {
        SimpleDBGUI2 f = new SimpleDBGUI2();
        f.show();
    }
}

class DBHandler {
  private Connection con;
  private Statement stmt;
  public DBHandler(String dsn, String usr, String pwd) {
      try {
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        con = DriverManager.getConnection("jdbc:odbc:" + dsn, usr, pwd);
        stmt = con.createStatement();
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      } catch (SQLException e) {
        e.printStackTrace();
      }
  }
  public ArrayList getAll(String crit) {
      ArrayList res = new ArrayList();
      try {
        ResultSet rs = stmt.executeQuery("SELECT * FROM t1 WHERE f2 LIKE '" + crit + "'");
        while (rs.next()) {
            res.add(new Record(rs.getInt(1), rs.getString(2)));
        }
        rs.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }
      return res;
  }
}

class Record {
  private int f1;
  private String f2;
  public Record() {
      f1 = 0;
      f2 = "";
  }
  public Record(int f1, String f2) {
      this.f1 = f1;
      this.f2 = f2;
  }
  public int getF1() {
      return f1;
  }
  public String getF2() {
      return f2;
  }
  public void setF1(int f1) {
      this.f1 = f1;
  }
  public void setF2(String f2) {
      this.f2 = f2;
  }
  public String toString() {
      return (f1 + " " + f2);
  }
}
Avatar billede _carsten Nybegynder
20. maj 2004 - 14:44 #4
Jeg ville formentlig bruge en tabel til at vise data i.

Denne er lavet ud fra dine klasser (og virker formentlig)


// -------- GuiLayout

import java.awt.*;
import javax.swing.*;
import java.util.Vector;
import javax.swing.table.DefaultTableModel;

public class GuiLayout extends JFrame
{
  private JLabel velkomstTekst;
  private JLabel oplysninger;
  private String brugernavn;

  public GuiLayout()
  {
    super ("Dette er titlen på vinduet");
    setSize (300, 300);

        scroll = new javax.swing.JScrollPane();
        table = new javax.swing.JTable();

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });

        table.setModel(createModel());
        scroll.setViewportView(table);

        getContentPane().add(scroll, java.awt.BorderLayout.CENTER);

        pack();
       
        DefaultTableModel model = (DefaultTableModel)table.getModel();
    model.addColumn("Brugernavn");
    model.addColumn("Navn");
        model.addColumn("Adgangskode");
       
        new VisOplysninger(model);

  }

  public DefaultTableModel createModel(){
    return (new javax.swing.table.DefaultTableModel(
          new Vector(), new Vector())
      {
        public Class getColumnClass(int columnIndex) {
            return String.class;
        }
    });
  }
   
  public static void main (String[] args)
  {
    GuiLayout f = new GuiLayout();
    f.show();
  }
}



// -------  VisOplysninger

import java.sql.*;
import javax.swing.table.DefaultTableModel;
import java.util.Vector;

public class VisOplysninger
{
  // Metode der opretter forbindelse til databasen
  public VisOplysninger(DefaultTableModel model)
  {
    String url = "jdbc:interbase://localhost/d:/Test/KVU.ib";

    try
    {
      Class.forName("interbase.interclient.Driver");
      Connection conn = DriverManager.getConnection(url, "sysdba", "masterkey");
      System.out.println("Forbindelse til database er etableret!");

      // Træk alle poster ud af databasen med SQL-sætning
      Statement stmt = conn.createStatement();
      String sql = "SELECT * FROM Bruger ORDER BY Brugernavn DESC";

      // Vis alle rækker under hinanden
      ResultSet rs = stmt.executeQuery (sql);
      Vector v;
     
      while (rs.next())
      { v = new Vector();
        v.add(rs.getString(1));
        v.add(rs.getString(2));
        v.add(rs.getString(3));
       
        model.addRow(v);

      }
      rs.close();
      conn.close();

    }
    catch(Exception e)
    {
      System.out.println("Der kunne ikke etableres forbindelse til databasen!");
    }

  }
}
Avatar billede Slettet bruger
20. maj 2004 - 14:45 #5
arne v, tak for svaret.
Jeg kan ud fra min egen kode, når jeg afvikler den i JBuilder, se at der både oprettes et nyt vindue med tekst i + at der udskrives en liste i bunden af skærmen med de brugere jeg har i min database.

Jeg har gjort dette med:
VisOplysninger vis = new VisOplysninger i min GuiLayout-klasse.

Det ser altså ud til at begge dele virker, også sammen.
Mit spørgsmål er nu hvordan jeg kan trække de enkelte resultater fra rs() over i min JFrame og vise disse listet under hinanden.
Er der ikke en metode, hvor man kan trække data over i en JLabel?

Dit eksempel ser fint ud, men jeg tror ikke lige jeg kan overføre det til mit eget problem.

Skal som sagt bare have relateret de data jeg trækker ud i den ene klasse til den anden klasse med GUI.
Data trækkes ud fra konstruktøren så der er ikke umiddelbart nogen metode jeg kan kalde.
Avatar billede arne_v Ekspert
20. maj 2004 - 14:50 #6
Måske skal du netop ikke lave den query i constructor men i en metode som du kan kalde !
Avatar billede arne_v Ekspert
20. maj 2004 - 14:52 #7
Også selv om du vælger den af carsten foreslåede JTable løsning (som er lidt
smartere end min JTextArea).
Avatar billede Slettet bruger
20. maj 2004 - 15:09 #8
Nu har jeg så, bare for at se om det hele ville virke, indsat den kode i sin fulde længde, som du Carsten skrev, men jeg får fejl på table og scroll?
Avatar billede _carsten Nybegynder
20. maj 2004 - 15:12 #9
Hvilke fejl ??
Avatar billede _carsten Nybegynder
20. maj 2004 - 15:16 #10
Compile eller Runtime ???

Vil gerne se fejlkode !
Avatar billede Slettet bruger
20. maj 2004 - 15:20 #11
Det blev bare understreget med rød i JBuilder Carsten.
Avatar billede Slettet bruger
20. maj 2004 - 15:21 #12
Kan man virkelig ikke bare gøre noget alla:

content.add (VisOplysninger vis = new VisOplysninger());

?
Avatar billede _carsten Nybegynder
20. maj 2004 - 15:21 #13
Fejlen er her

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt); // ERSTAT MED System.exit(0);
            }
        });
Avatar billede Slettet bruger
20. maj 2004 - 15:23 #14
Altså, hvor man tilføjer ResultSet'et til JFrame?
Det virker jo fint nok når man kører programmet - altså vinduet bliver vist og ResultSet bliver udskrevet i bunden af skærmen i JBuilder...

Det må da kunne laves lige så enkelt hvor man bare lister resultatet af databasekaldet under den standardtekst jeg har skrevet og tilføjet til content.
Avatar billede _carsten Nybegynder
20. maj 2004 - 15:23 #15
Det er fordi jeg ikke fik pastet exitForm(evt); metoden ind her

Nej - det kan du ikke

Men
content.add (new VisOplysninger());

Eller
VisOplysninger vis = new VisOplysninger();
content.add (vis);
Avatar billede Slettet bruger
20. maj 2004 - 15:25 #16
Jeg har selv tilføjet:

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Til min GUI klasse så jeg behøver vel egentlig ikke den WindowListener du har skrevet?
Hvad har den forøvrigt med table og scroll at gøre?
Avatar billede _carsten Nybegynder
20. maj 2004 - 15:27 #17
GLEM HVAD JEG SKREV HER: 20/05-2004 15:23:40

Du kan ikke adde en klasse til en JFrame som ikke extender eksempelvis JTextArea, JPanel, JTextField klassen skal extende en JComponent/Component
Avatar billede _carsten Nybegynder
20. maj 2004 - 15:28 #18
Den har intet med med table og scroll at gøre, men den giver de fejl (røde linier) i JBuilder
Avatar billede arne_v Ekspert
20. maj 2004 - 15:29 #19
Hvis VisOplysninger er en grafisk klasse kan du adde den.

Det bør ikek engang være så svært at extende JTextArea aller JTable.

Og så begynder brug af query i constructor at give mening.
Avatar billede Slettet bruger
20. maj 2004 - 15:31 #20
VisOplysninger bruges udelukkende til ResultSet. Det er vidst ikke en grafisk klasse.

Jeg får en grim rød understrgning under add når jeg forsøger mig med:
content.add (new VisOplysninger());
Avatar billede _carsten Nybegynder
20. maj 2004 - 15:32 #21
Ja - sådan, hvis du bruger min løsning
content.add (new VisOplysninger( model ));
Avatar billede _carsten Nybegynder
20. maj 2004 - 15:34 #22
Nu sludrer jeg igen

Du kan ikke gøre det på den måde se min kom. 20/05-2004 15:27:35
Avatar billede Slettet bruger
20. maj 2004 - 15:36 #23
Nu spørger lidt dumt igen, men burde det ikke være muligt bare at overføre resultatet direkte fra den ene klasse til den anden uden alt det med model?
Som sagt så får jeg jo resultatet i bunden af skærmen hvis jeg kalder VisOplysninger klassen med VisOplysninger vis = new VisOplysninger();
Så hvorfor kan man ikke bare tilføje den til JFrame?

Undskyld hvis jeg kører rundt i det samme hele tiden, men jeg har ikke den nødvendige baggrund i Java til at tumle med alle de mange muligheder i disker op med :-)
Avatar billede _carsten Nybegynder
20. maj 2004 - 15:38 #24
Fordi klassen ikke er grafisk!

Du kan godt overføre resultatet, men du skal have noget at putte det i, det kan så være en JTable eller et JTextArea
Avatar billede _carsten Nybegynder
20. maj 2004 - 15:39 #25
Vent lidt !
Avatar billede _carsten Nybegynder
20. maj 2004 - 15:44 #26
Nu skulle du kunne bruge content.add (new VisOplysninger());
hvis du bruger denne klasse

import java.sql.*;
import javax.swing.*;

public class VisOplysninger extends JScrollPane
{
  // Metode der opretter forbindelse til databasen
  public VisOplysninger()
  { JTextArea area = new JTextArea();
    String url = "jdbc:interbase://localhost/d:/Test/KVU.ib";

    try
    {
      Class.forName("interbase.interclient.Driver");
      Connection conn = DriverManager.getConnection(url, "sysdba", "masterkey");
      System.out.println("Forbindelse til database er etableret!");

      // Træk alle poster ud af databasen med SQL-sætning
      Statement stmt = conn.createStatement();
      String sql = "SELECT * FROM Bruger ORDER BY Brugernavn DESC";

      // Vis alle rækker under hinanden
      ResultSet rs = stmt.executeQuery (sql);
     
      while (rs.next())
      { area.append(rs.getString(1) + "\t");
        area.append(rs.getString(2) + "\t");
        area.append(rs.getString(3) + "\n");
      }
     
      setViewportView(area);
     
      rs.close();
      conn.close();

    }
    catch(Exception e)
    {
      System.out.println("Der kunne ikke etableres forbindelse til databasen!");
    }

  }
}
Avatar billede Slettet bruger
20. maj 2004 - 15:48 #27
Tak skal du have Carsten. Jeg kigger på det så snart jeg kommer tilbage til skærmen :-) Bliver lige nødt til at smutte et stykke tid.
Avatar billede _carsten Nybegynder
20. maj 2004 - 15:51 #28
OK - med din egen GuiLayout, ser det sådan ud

import java.awt.*;
import javax.swing.*;

public class GuiLayout extends JFrame
{
  public GuiLayout()
  {
    super ("Dette er titlen på vinduet");
    setSize (300, 300);
    Container content = getContentPane();
    content.add (new VisOplysninger());
  }

  public static void main (String[] args)
  {
    GuiLayout f = new GuiLayout();
    f.show();
  }
}
Avatar billede Slettet bruger
20. maj 2004 - 18:14 #29
Carsten, det er f..... fantastisk det her :-)
Det virker fint!

Du skal have nogle velfortjente point. Kan du ikke lige oprette et svar?

P.S. Hvis du gidder må du meget gerne komme med en kort forklaring om hvad du har gjort med det area. Kun hvis du gidder altså, men jeg er som skrevet tidligere totalt grøn ud i det her.

Mange tak for din indsats!
Avatar billede _carsten Nybegynder
20. maj 2004 - 19:08 #30
Tja - du var jo ikke glad for tabeller og tabelmodeller, så jeg brugte den letteste løsning (kodemæssigt), hvilket vil sige et JTextArea som Arne foreslog.

Jeg lod din VisOplysninger extende JScrollPane og oprettede et nyt JTextArea

1. Dataene puttes i JTextArea'et med din while løkke
2. JTextArea'et puttes ind i JScrollPane'et som vi extender "setViewportView(area);"
3. Din VisOplysninger puttes ind i din JFrame

Det var det.
Avatar billede Slettet bruger
20. maj 2004 - 19:31 #31
Tak for hjælpen begge to!

:-)
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