GUI-Applet JTable füllt Hintergrund völlig aus

kniffel

Mitglied
Hallo Leute,

ich arbeite gerade an einem Applet, dass sich mit einer Datenbank verbindet, Datensätze holt und sie in deiner Tabelle darstellt. (Außerdem kann man auch neue Datensätze einfügen und löschen. Aber das hat jetzt nichts mit dem Problem zu tun)

Wenn ich mein Applet starte, und meinen DB-Get Button drücke, werden die Datensätze aus der DB geholt, die Tabelle gezeichnet und in die Tabelle eingefügt.
Siehe hier:
bild1.png

http://kniffel.comeze.com/materials/temp.use/bild1.png

Wenn ich allerdings dann sehr schnell über den DB-Delete Button darunter gehe, (Nur drüber fahre)
dann wird die Tabelle in den Hintergrund geschoben und so groß wie das Appletfenster ist.
Siehe hier:
bild2.png

http://kniffel.comeze.com/materials/temp.use/bild2.png

Bevor ich euch den Code poste, möchte ich gleich darauf hinweisen, dass:
Ja es ist sehr ineffizient jedes Mal, wenn ein Button gedrückt wird, die Verbindung zur DB neu zu erstellen und jedes mal auch eine neue Tabelle zu zeichnen. Aber ich habe derzeit noch keine brauchbare Alternative programmieren können.

Es ist viel Code, ich habe es nur sehr schwach gekürzt, da vielleicht die unwahrscheinlichsten Befehle die Ursache sind.

Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.applet.*;
import java.util.*;
import java.sql.*;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
//*gekürzt*

public class Neobux extends JApplet implements ActionListener {

      String driver              = "org.gjt.mm.mysql.Driver";
      String databaseURL         = "jdbc:mysql://localhost/***";
      final String DATABASE_USER = "***";
      final String USER_PASSWORD = "***";

JButton but, but2, but3, but4, but5;
Label lab,refs,clicks,clicks2,refcost,goldcost,
      tfrefcost,tfgoldcost,lab1,lab2,lab3,lab4,
      poserg,negerg,erg,errlog;
TextField tfref,tf,tfclicks,tfclicks2, inconsole;
TextArea console;
JTable table;
JScrollPane scrollPane;

public void init() {
       this.setBackground(new Color(100,100,100));

       //*gekürzt*

       //*****BUTTON  *****//                                                    Bei Button Clicked: Color Dark_gray und nicht hellblau
       but = new JButton("Calculate");
       but.setBackground(Color.DARK_GRAY);
       but.setForeground(Color.LIGHT_GRAY);
       //Damit Button Text vollständig angezeigt wird
       but.setMargin(new Insets(0,0,0,0));
       but.addActionListener(this);
       but.addMouseListener(new MouseListener(){
          public void mouseEntered(MouseEvent evt){
                 but.setBorder(new LineBorder(Color.YELLOW, 1));
          }//Ende Entered
          public void mouseExited(MouseEvent evt){
                 but.setBorder(new LineBorder(Color.LIGHT_GRAY, 1));
          }//Ende Exited
          public void mouseClicked(MouseEvent evt){}//Ende Clicked
          public void mousePressed(MouseEvent evt){}//Ende Pressed
          public void mouseReleased(MouseEvent evt){}//Ende Released
          });//Ende MouseListener
       //*****BUTTON 2*****//
       but2 = new JButton("DB-GET");
       but2.setBackground(Color.DARK_GRAY);
       but2.setForeground(Color.LIGHT_GRAY);
       //Damit Button Text vollständig angezeigt wird
       but2.setMargin(new Insets(0,0,0,0));
       but2.addActionListener(this);
       but2.addMouseListener(new MouseListener(){
          public void mouseEntered(MouseEvent evt){
                 but2.setBorder(new LineBorder(Color.YELLOW, 1));
          }//Ende Entered
          public void mouseExited(MouseEvent evt){
                 but2.setBorder(new LineBorder(Color.LIGHT_GRAY, 1));
          }//Ende Exited
          public void mouseClicked(MouseEvent evt){}//Ende Clicked
          public void mousePressed(MouseEvent evt){}//Ende Pressed
          public void mouseReleased(MouseEvent evt){}//Ende Released
          });//Ende MouseListener

       //*gekürzt*
       //Add to Applet
       //*gekürzt*
       add(but);
       add(but2);
       add(but3);
       add(but4);

       this.resize(1100,1000);
       this.setBackground(new Color(100,100,100));
}//Ende init

public void paint(Graphics g) {
           this.setBackground(new Color(100,100,100));
           lab.setBounds(380,5,160,20);
           

           //Refnumber
           //*gekürzt*
           but.setBounds(25,92,145,30);
           g.setColor(Color.LIGHT_GRAY);
           g.drawRect(22,27,605,100);

           //Button
           //GET
           but2.setBounds(477,135,80,40);
           //DELETE
           but3.setBounds(477,175,80,40);
           //INSERT
           but4.setBounds(477,215,80,40);

           //Minirechner-Hintergrund
           g.setColor(Color.DARK_GRAY);
           g.fillRect(175,30,450,93);
           //Tabelle-Begrenzung
           g.setColor(Color.WHITE);
           g.drawRect(22,132,538,520);
           //Programmbegrenzung
           g.setColor(Color.WHITE);
           g.drawRect(1,1,1000,500);
           
           //Elemente neu zeichnen damit beim start da sind
           but.repaint();
           but2.repaint();
           but3.repaint();
           but4.repaint();
           
}//Ende paint

public void actionPerformed(ActionEvent ae){
            Object wer = ae.getSource();
            if (wer==but) {
            //minirechner();
            }//Ende but
            if (wer==but2) {
              Vector<String> columnNames = new Vector<String>();
              Vector<Vector> data = new Vector<Vector>();
              try {
                  //Mit DB verbinden
                  Class.forName( driver );
                  Connection connection = DriverManager.getConnection(databaseURL, DATABASE_USER, USER_PASSWORD);
                  //Daten lesen
                  String sql = inconsole.getText();
                  Statement stmt = connection.createStatement();
                  ResultSet rs = stmt.executeQuery( sql );
                  ResultSetMetaData md = rs.getMetaData();
                  int columns = md.getColumnCount();
                  //Get Spalten Namen
                  for (int i = 1; i <= columns; i++) {
                      columnNames.addElement( md.getColumnName(i) );
                      }//Ende for
                  //Get Zeilen Namen
                  while (rs.next()) {
                        Vector<Object> row = new Vector<Object>(columns);
                        for (int i = 1; i <= columns; i++) {
                            row.addElement( rs.getObject(i) );
                            }//Ende for
                        data.addElement( row );
                        }//Ende while
                  rs.close();
                  stmt.close();
                  }
                  catch(Exception e) {System.out.println(e);}
              //Tabelle zeichnen
              table = new JTable(data, columnNames);
              drawtable();
        }//Ende if von but2
     
        if (wer==but3) {
           String nummer;
           nummer = JOptionPane.showInputDialog(null,"Welche Zeile soll gelöscht werden? \n Geben Sie die entsprechende 'nr' ein.");
           console.setText(console.getText()+nummer);
           Vector<String> columnNames = new Vector<String>();
           Vector<Vector> data = new Vector<Vector>();
           try {
            Class.forName( driver );
            Connection connection = DriverManager.getConnection(databaseURL, DATABASE_USER, USER_PASSWORD);
            Statement statement = connection.createStatement();
            statement.executeUpdate("delete from daten where nr="+Integer.parseInt(nummer)+";");
            //statement.executeUpdate("insert into daten (nr,datum,myklicks,refklicks,dirklicks,recycle) values(7,'2011-05-08',10,350,9,3);");
            statement = null;
            String sql = "Select * from daten;";
            Statement stmt = connection.createStatement();
            ResultSet rs = stmt.executeQuery( sql );
            ResultSetMetaData md = rs.getMetaData();
            int columns = md.getColumnCount();
            for (int i = 1; i <= columns; i++) {
                columnNames.addElement( md.getColumnName(i) );
            }
            while (rs.next()) {
                Vector<Object> row = new Vector<Object>(columns);
                for (int i = 1; i <= columns; i++) {
                    row.addElement( rs.getObject(i) );
                }
                data.addElement( row );
            }
            rs.close();
            stmt.close();
            statement.close();
        } catch(Exception e) {
            System.out.println( e );
            console.append(String.valueOf(e+"\n"));
        }
        table = new JTable(data, columnNames);
        drawtable();
        }//Ende but3

        //***

}//Ende actionPerformed

public void clearconsole() {console.setText("");}
public void drawtable() {
        scrollPane = new JScrollPane(table);
        getContentPane().add(scrollPane);
        scrollPane.setBounds(25,135,450,515);
}//Ende drawtable

//public void deletetable() {
//       scrollPane.setBounds(0,0,0,0);
//}//Ende deletetable

}//Ende class

Ich hoffe jemand kann mir helfen, die Tabelle in ihre Schranken zu weisen.
 
Welchen LayoutManager nutzt Du? Vermutlich keinen, also Null-Layout. Davon würde ich abraten.
Ansonsten nicht die paint() des JApplets überschreiben. Nimm ein JPanel, füge dort alle Komponenten ein und pack dann nur das JPanel auf das Applet.
Beim JPanel kannst Du dann paintComponent(Graphics g) überschreiben. (Wobei ich anhand der Screenshots keinen Grund sehe, warum man überhaupt paint bzw. paintComponent überschreiben müsste??)

Grundsätzlich sieht das was Du in der paint() machst ganz schön merkwürdig aus das setBounds und repaint() auf die Buttons hat darin gar nichts verloren.

Der MouseOverEffekt bei den Buttons ist doch immer der selbe. Daher:
Warum nicht ein MouseListener für alle Buttons (verkürzt den Code)
Ausserdem nicht immer neue Border Objekte erzeugen. Erzeuge die zwei Border Objekte einmal und verwende Sie wieder. Oder nutzte die BorderFactory.
 
Danke dir, ich werds ausprobieren.

Ich nutze NullLayout weil ich damit frei über die Größe und Position verfügen kann. Mit anderen Layouts bin ich stark an bestimmte "Positionen" gebunden. Schwer zu erklären...

Wenn ich setBounds nicht in paint schreibe, erscheint das Objekt nicht, egal wo ich es sonst hinschreiben würde.
Mit repaint() schaffe ich es, dass die Buttons schon beim start des Applets erscheinen und nicht erst, wenn ich mit dem Button drüber fahre.
 
Ich nutze NullLayout weil ich damit frei über die Größe und Position verfügen kann. Mit anderen Layouts bin ich stark an bestimmte "Positionen" gebunden. Schwer zu erklären...
Dann nutzt du die Layoutmanager falsch.

Wenn ich setBounds nicht in paint schreibe, erscheint das Objekt nicht, egal wo ich es sonst hinschreiben würde.
Mit repaint() schaffe ich es, dass die Buttons schon beim start des Applets erscheinen und nicht erst, wenn ich mit dem Button drüber fahre.
Wie Michael... schon geschrieben hat, so ist das falsch!
setBounds und repaint haben darin schonmal gar nichts verloren, auch solltest du paint des Applets nicht überschreiben. (da kommt dann z.b. so ein verhalten wie jetzt bei rum)
Verwende einen LayoutManager, dann sind deine Buttons auch von anfang an sichtbar und du musst dich nicht mit solchen "hacks" behelfen.
 
Ich weiß ihr werdet dass nur sehr ungern sehen, aber...
Fehler behoben.
Ich habe einige Stunden damit verbracht, das GUI hoffnungslos auf ein layout zu bringen, kein brauchbarer Erfolg.

Habe dann mein Design nocheinmal überfolgen und mir ist aufgefallen, dass ich GAR KEIN Layout definiert hatte.
Da es ein Applet war, hat das positionieren im überschriebenen paint funktioniert, auch ohne Layout.
Aber mit der Zeile: this.setLayout(null); ist auch mein Bug behoben.
Werde es aber dennoch etwas besser mit Panels unter kontrolle bringen...
 

Zurück
Oben