checkbox status abfragen und drucken

Joe30

Mitglied
Hallo,
ich bin blutiger Java-Anfänger und stehe vor schon vor einem großen Problem.
Ich habe mit Hilfe von Netbeans eine kleine Swing Gui gemacht der Daten einer mysql DB in einem Jtable ausgibt.
Mein Problem ist: ich möchte gerne checkboxen selektieren und anschließend nur ausgewählte Dantensätze ausdrucken.
Die ersten vier Spalten im Jtable sind Objekte, column 5 ist ein Boolean (für die checkboxen). Somit werden mir zumindest die checkboxen ausgegeben und ich kann diese selektieren.
Mein Problem ist nur, wie Frage ich ab, welche checkboxen gewählt wurden und wie kann ich diese anschließend ausdrucken.

So sieht der Search Button aus
Java:
 private void searchActionPerformed(java.awt.event.ActionEvent evt) {                                       
   
    DefaultTableModel model=(DefaultTableModel) jTable1.getModel();
    
    // Textfeld auslesen
    String searchBand=band.getText();
    String searchSong=song.getText();
    String searchJahr=jahr.getText();
   
    //Tabelle leer machen
    model.setRowCount(0);
    
    try {
        
         // ComboBox auslesen
        Object combo = jComboBox1.getSelectedItem();
        // ausgelesenes Object in String wandeln
        String auswahl = combo.toString();
        
         // SQL select mit order by ComboBox
        String sql="Select * from library where Band like '%"+searchBand+"%' and Song like '%"+searchSong+"%' and Jahr like '%"+searchJahr+"%'  order by "+auswahl+""; 
        
        //Datenbank Connect
        Class.forName("com.mysql.jdbc.Driver");
        Connection con= (Connection)
        DriverManager.getConnection(this.url,this.user,this.pass);
        //
        
        //ab hier absetzen des Selects und Ausgabe der Abfrage
        Statement stmt=con.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        Integer count = 0;
        
        while (rs.next())
        {
            String id = rs.getString("ID");
            String bandField = rs.getString("Band");
            String songField = rs.getString("Song");
            String jahrField = rs.getString("Jahr"); 
            count = count + 1;
            model.addRow(new Object []{id,bandField,songField,jahrField});
        }
        //gezählte Sätze ausgeben
        selection.setText(" "+count+" Zeile(n) ausgewählt"); 
        //Fortschrittsbalken setzen
        jProgressBar1.setValue(100);
    }
    catch(ClassNotFoundException | SQLException e) {
        JOptionPane.showMessageDialog(this, e.getMessage());
    }
        
    }                                      

    private void updateActionPerformed(java.awt.event.ActionEvent evt) {                                       
        
        DefaultTableModel model=(DefaultTableModel) jTable1.getModel();
        selection.setText("");
                    
        //Zeile in Tabelle auslesen
        int row = jTable1.getSelectedRow();
    
        //ID in der DB auslesen, wichtig für update
        String rowID = jTable1.getModel().getValueAt(row, 0).toString();
        
        String sql = "update library set Band = ?, Song = ?, Jahr = ? where ID = "+rowID+"";
        
        try{
            Class.forName("com.mysql.jdbc.Driver");
            Connection con= (Connection)
            DriverManager.getConnection(this.url,this.user,this.pass);
            PreparedStatement pst = con.prepareStatement(sql);
            
            pst.setString(1, band.getText());
            pst.setString(2, song.getText());
            pst.setString(3, jahr.getText());
            
            
            pst.executeUpdate();
            
            //Felder leeren
            band.setText("");
            song.setText("");
            jahr.setText("");
            
            JOptionPane.showMessageDialog(null, "Update erfolgreich");
            
        }
        catch (ClassNotFoundException | SQLException | HeadlessException e){
            JOptionPane.showMessageDialog(null, e);
        }
        
    }


und über Button Drucken wird das Jtable ausgedruckt (nur eben komplett und nicht nur ausgewählte Sätze)

Java:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
       
        try {
            jTable1.print();
            } catch(PrinterException pe) {
                JOptionPane.showMessageDialog(null, "Fehler beim Drucken");
}
        
    }

Hoffe das war einigermaßen verständlich geschrieben... bin halt echt ein totaler Anfänger.
Ich bin für jede Hilfe Dankbar
 
Du wirst wahjrscheinlich irgendeine Zuordnung von Tabelleneinträgen zu Datenbankeinträgen brauchen. Am einfachsten wäre es, wenn du innerhalb deiner Tabelle jedem Eintrag einen Index zuweist, welchen du auch in der Datenbank verwendest. Dann selektierst du also in der mySQL-Tabelle alle Einträge, die diese Indizes besitzen.
Du könntest z.B. ´ne Hashmap verwenden, in der du dem Indexeintrag der Tabelle (GUI) einen Index der Tabelle (SQL) zuordnest: Id1 (GUI) --> ID5 (SQL).

EDIT: Hab ich dich richtig veratdnen, in deiner JTable ist in jeder Zeile je eine Checkbox? Und deren "Index" willst du also erhalten? Dann lauf doch durch alle Datensätze der JTable und prüfe mit getValueAt(int row, int col), ob die checkbox auf true steht (ist jetzt nur ´ne fixe Idee, hab´s selbst nicht probiert). Sollte dem so sein, holst du dir noch den Index aus dieser Zeile und gibts diesen an die Datenbank weiter.
 
Zuletzt bearbeitet:
Vielen Dank schonmal für deine schnelle Antwort.
Ich glaub du hast mich auf eine Idee gebracht.
In der Mysql DB habe ich eine eindeutige ID (mit auto_increment)... evtl. ist es ja möglich die angehakten checkboxen anhand der ID in ein array zu speichern, anschließend wenn der Button drucken gedrückt ist, werden diese Sätze dann selektiert, im Jtable ausgegeben und gedruckt. Vielleicht ist es aber auch möglich dem jTable1.print(); mitzuteilen das es nur die gewählten Zeilennummern ausdrucken soll ?!?
Leider fehlt mir noch der Ansatzpunkt wie ich genau die Zeilennummer von den checkboxen herausbekomme :-(

Vielleicht funktioniert es ja ähnlich wie bei der Zeilenmarkierung im Jtable. Hier lese ich aus welche Zeile ausgewählt ist und schreibe diese dann in die Textfelder um z.B. ein update durchzuführen

Java:
    private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {                                     
    
    // Markierte Zeile auslesen
    int row = jTable1.getSelectedRow();
    
    //Werte in Textzellen übernehmen
    String rowID = jTable1.getModel().getValueAt(row, 1).toString();
    band.setText(jTable1.getModel().getValueAt(row, 1).toString());
    song.setText(jTable1.getModel().getValueAt(row, 2).toString());
    jahr.setText(jTable1.getModel().getValueAt(row, 3).toString());
    
    }

Ich glaube auf jedenfall das ich deinen Tipp getValueAt(int row, int col) am WE mal ausprobieren werde.

Vielen Dank nochmal
 
Ich hab jetzt mal folgendes probiert:

// Versuch die gecheckte Box abzufragen
String check = jTable1.getValueAt(0,4).toString();
band.setText(check);

läuft zwar nicht rund... aber zumindest schreibt er mir true oder false ins Textfeld
 
Siehste, und damit kannst du also dann auch die Textzeile erhalten. Prüfen, ob da true oder false drin steht, falls true dann getValue(row, 1) oder wo deine ID steht.
 
schon wieder ein neues Problem 🙂
habe jetzt folgendes geschrieben

Java:
 //Zeilennummer
        int row = 0;
        // Zeilen des Jtables auslesen
        int count = jTable1.getRowCount();
        
        while(row < count){
        //Zeilen ID heruasfinden
        Object rowid = jTable1.getValueAt(row, 0);
        String check = (String) jTable1.getModel().getValueAt(row,4).toString();
        System.out.println(check+" Row ID "+rowid+"Zeile"+row);
        row++;
        }

ich lasse mir hier die ID und checkox true oder false ausgeben. Das Problem ist, das es nur bei Zeilen funktioniert die ich schonmal angehakt (oder den haken weggemacht) habe.
Wenn ich z.B die ersten drei Zeilen anhake kommt folgende Ausgabe

run:
true Row ID 18Zeile0
true Row ID 19Zeile1
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
true Row ID 20Zeile2
at datenbank.Form.jButton1ActionPerformed(Form.java:559)
at datenbank.Form.access$800(Form.java:11)
at datenbank.Form$10.actionPerformed(Form.java:165)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6504)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6269)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4860)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4686)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2713)
at java.awt.Component.dispatchEvent(Component.java:4686)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
at java.awt.EventQueue.access$000(EventQueue.java:101)
at java.awt.EventQueue$3.run(EventQueue.java:666)
at java.awt.EventQueue$3.run(EventQueue.java:664)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:680)
at java.awt.EventQueue$4.run(EventQueue.java:678)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
 
Welche davon ist denn die Zeile 559 in deinem ganzen Programm? So könnte man erkennen, in welcher Zeile das Programm hängt.
 
Zeile 559 ist eigentlich
Java:
System.out.println(" Row ID "+rowid+"Zeile "+row);
aber wenn ich sie auskommentiere dann ist es die Zeile 558
Java:
String check = (String) jTable1.getModel().getValueAt(row,4).toString();
hier will ich die checkbox (Boolean) auslesen.

Und ich denke das ist auch das Problem.
Vielleicht bin ich gleich zu tief eingestiegen, aber es hat trotz geringer Vorkenntisse einfach zu gut geklappt bis hierher 🙂

Habe jetzt schon öfters über tablecell rendere gelesen... vielleicht müsste ich ja eher hier ansetzen bei dem was ich vorhabe.

Ich möchte einfach das man z.B. zwei Datensätze anhakt und anschließend sollen diese dann gedruckt werden... evtl. ist ja mein Ansatz völlig verkehrt?
 
So ein kleiner Erfolg :toll:

Java:
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
                             
        //Zeilennummer
        int row = 0;
        // Zeilen des Jtables auslesen
        int count = jTable1.getRowCount();
        
        while(row < count){
        //Zeilen ID heruasfinden
        Object rowid = jTable1.getValueAt(row, 0);
            if (jTable1.getValueAt(row,4) == Boolean.TRUE)
                 {String test = "true"; System.out.println(test+" Row ID "+rowid+"Zeile "+row);}
            else {System.out.println("False Row ID "+rowid+"Zeile "+row);}
        row++;
        }

Jetzt kann ich Haken setzen, es kommen keine Fehlermeldungen mehr und die richtigen ID's werden ausgegeben.
Jetzt Habe ich vor die checkboxen mit true in ein Array zu schreiben => dann diese ID's zu selektieren => dann ausdrucken
Ist das vom Ansatz sinnvoll?
 
Das sieht jedenfalls besser aus als der Weg über String. Ich hab nur noch nicht ganz verstanden, warum du auch jetzt noch über den String gehst, wo du dann "true" reinschreibst. Warum machst du das nicht direkt über eine boolean-Variable?

Dein Ansatz fürs Drucken klingt gut, speichere einfach die ausgewählten IDs in einer ArrayList.
Dass jTable eine Druckfunktion hat, wusste ich bisher nicht, vielleicht kannst du ja vor dem Drucken ein weiteres Objekt vom Typ jTable erstellen, das du aber nicht deinem Fenster hinzufügst. Da kopierst du dann die ausgewählten Einträge rüber (die Checkboxen kannst du dabei weg lassen, auf dem Papier kann man ja schlecht was anklicken 😉) und druckst dann diese jTable.
 
Bin jetzt glaub ich doch fast am Ziel....
Eine Frage hab ich jedoch noch: Da ich mir jetzt eine zweites Jtable gemacht habe um die gecheckten Daten auszudrucken, wollte ich wissen ob es in Netbeans die Möglichkeit gibt ein jtable auszublenden.
Meine Hilfstabelle Jtable2 soll natürlich nicht zu sehen sein.
So sieht der Code jetzt aus:

Hier kopiere ich zum testen mal von jtable 1 in jtable2 (jtable2 sollte nicht zu sehen sein)
Java:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        //Table Model einlesen
        DefaultTableModel model=(DefaultTableModel) jTable2.getModel();
        
        //Kopieren der Daten in zweites Jtable
        model.addRow(new Object[]{});
        String copy1 = (String) jTable1.getValueAt(0, 1);
        jTable2.setValueAt(copy1, 0, 0);
        
        String copy2 = (String) jTable1.getValueAt(0, 2);
        jTable2.setValueAt(copy2, 0, 1);
        
        String copy3 = (String) jTable1.getValueAt(0, 3);
        jTable2.setValueAt(copy3, 0, 2);

so geht's weiter
Java:
//Zeilennummer
        int row = 0;
        
        // Zeilen des Jtables auslesen
        int count = jTable1.getRowCount();
        
        int[] array = new int[count]; 
        int i = 0; //Zähler für array
        
        
        while(row < count){
        //Zeilen ID heruasfinden
        Object rowid = jTable1.getValueAt(row, 0);
        Integer zeile = new Integer(rowid.toString()); // Object rowid zu Integer um ins Array speichern zu können
        
        int a = 5;
            if (jTable1.getValueAt(row,4) == Boolean.TRUE)
            {array[i]= zeile; System.out.println(array[i]); i++;} 
                //{String test = "true"; System.out.println(test+" Row ID "+rowid+"Zeile "+row);}
            //else {System.out.println("False Row ID "+rowid+" Zeile "+row);}
        row++;
        }  
                       
        try {
            jTable2.print();
            } catch(PrinterException pe) {
                JOptionPane.showMessageDialog(null, "Fehler beim Drucken");
}
        
    }

Das array in der Schleife werde ich später noch durch das Kopieren der gecheckten Datensätze ersetzen
 
Füge das jTable, das du fürs Drucken benutzt, einfach nicht in dein Fenster ein, d.h. keinen add()-Befehl. Dann musst du es auch nicht ausblenden, was du natürlich mit
Java:
jTable2.setVisible(false);
könntest. Das wäre aber sehr unsauber programmiert. Wenn du es nicht zum Fenster hinzufügst, musst du dir nicht einmal die Mühe machen, das jTable2 vor dem nächsten Drucken erst zu leeren. Erzeuge es einfach erst vor dem Drucken, dann wird es vom Garbage Collector anschließend automatisch entfernt und du kannst beim nächsten Drucken einfach ein neues erzeugen.
 
So ähnlich hab ichs probiert. Ich hab das zweite jTable einfach neben das Hauptfenster gesetzt. Dann ist es zwar nicht sichtbar wird aber auch scheinbar nicht gefüllt. Werd jetzt noch etwas googlen, vielleicht findet sich noch was.
Die andere Möglichkeit wäre evtl. auch die Checkboxen die false sind aus dem Jtable1 zu entfernen, dann bräuchte ich natürlich kein zweites als Hilfstable. Aber mal schauen wie's besser hinhaut.

Vielen dank auf jedenfall
 
Also vielen Dank nochmal für eure Hilfe. Habs jetzt gelöst... das zweite Jtabel habe ich so klein gemacht das es im GUI nicht sichtbar ist.
Der Quellcode für den Drucken button sieht jetzt so aus

Java:
 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        
        //Table Model einlesen
        DefaultTableModel model=(DefaultTableModel) jTable2.getModel();
        
        //Zeilennummer
        int row = 0;
        
        // Zeilen des Jtables auslesen
        int count = jTable1.getRowCount();
        
        int i = 0; //Zähler Zeil jTable2
        
        while(row < count){                     
            if (jTable1.getValueAt(row,4) == Boolean.TRUE)
            {model.addRow(new Object[]{});
            String copy1 = (String) jTable1.getValueAt(row, 1);jTable2.setValueAt(copy1, i, 0);
            String copy2 = (String) jTable1.getValueAt(row, 2);jTable2.setValueAt(copy2, i, 1);
            String copy3 = (String) jTable1.getValueAt(row, 3);jTable2.setValueAt(copy3, i, 2); i++;}
            row++;
            }  
                       
        try {
            jTable2.print();model.setRowCount(0);
            } catch(PrinterException pe) {
                JOptionPane.showMessageDialog(null, "Fehler beim Drucken");
}
        
    
        
    }
 

Neue Themen


Zurück
Oben