Change class that extends JFrame to class that ext

2019-09-14 20:16发布

问题:

I'm a Java-Newbie an I'm trying to build my first app. I read lots of tutorials and demos and searched for concrete answers to my question but haven't found something that helps. For testing I wrote this class, that connects an access database with a JTable. Now I want to add this Class in a main app but therefore i have to change my exisiting class to JPanel. I tested some changes, but I don't get an output JTable inside my app anymore. Can anybody explain the way I have to change my class? Thanks a lot!

    package de.test.gui;

import java.awt.BorderLayout;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

class Projekt {
    private int Platz;
    private String ProjektName;
    private String StimmZahl;

    public Projekt(int platz, String projektName, String stimmZahl) {
        this.Platz = platz;
        this.ProjektName = projektName;
        this.StimmZahl = stimmZahl;
    }

    public int getPlatz(){
        return this.Platz;
    }

    public String getProjektName() {
        return this.ProjektName;
    }

    public String getStimmZahl(){
        return this.StimmZahl;
    }

}
public class TabelleProjekt extends JFrame {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public TabelleProjekt() {
        super();
        setLocationRelativeTo(null);
        setSize(500,300);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    static Connection getConnection() {
        Connection con = null;
        try {
          con = DriverManager.getConnection("jdbc:ucanaccess://C:/Projekt/testdb.accdb");
        } catch (SQLException ex) {
            // TODO Auto-generated catch block
            Logger.getLogger(TabelleProjekt.class.getName()).log(Level.SEVERE, null, ex);
        }
        return con;
    }

    static ArrayList<Projekt> getProjekt() {
        ArrayList<Projekt> projekt = new ArrayList<Projekt>();

        Connection con = getConnection();
        Statement st;
        ResultSet rs;
        Projekt p;

        try {
            st = con.createStatement();
            rs = st.executeQuery("SELECT * FROM TESTTABLE");

            while(rs.next()){
                p = new Projekt(
                        rs.getInt("KBOE"),
                        rs.getString("NAME"),
                        rs.getString("VORNAME")
                );
                projekt.add(p);

            }

        } catch (SQLException ex) {
            // TODO Auto-generated catch block
            Logger.getLogger(TabelleProjekt.class.getName()).log(Level.SEVERE, null, ex);
        }

        return projekt;

    }

    public static void main(String[] args) {

        JTable table = new JTable();

        DefaultTableModel model = new DefaultTableModel();
        Object[] columnsName = new Object [3];
        columnsName[0] = "Platz";
        columnsName[1] = "Projektname";
        columnsName[2] = "Stimmzahl";

        model.setColumnIdentifiers(columnsName);

        Object[] rowData = new Object[3];

        for (int i = 0; i < getProjekt().size(); i++) {
            rowData[0] = getProjekt().get(i).getPlatz();
            rowData[1] = getProjekt().get(i).getProjektName();
            rowData[2] = getProjekt().get(i).getStimmZahl();

            model.addRow(rowData);

        }

        table.setModel(model);
        System.out.println(getProjekt().size());
        TabelleProjekt window = new TabelleProjekt();
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        JScrollPane pane = new JScrollPane(table);
        panel.add(pane,BorderLayout.CENTER);
        window.setContentPane(panel);
        window.setVisible(true);


    } 


}

If I change it to

public class TabelleProjekt extends JPanel {

I get problems here:

public TabelleProjekt() {
    super();
    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

window.setContentPane(panel);

Now I tried to use camickrs advice and use my logic in a SimpleTableDemo. Somehow it still doesn't work.

package de.test.gui;

/*
 * SimpleTableDemo.java requires no other files.
 */

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import java.awt.Dimension;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SimpleTableDemo extends JPanel {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private boolean DEBUG = false;

    static Connection getConnection() {
        Connection con = null;
        try {
            con = DriverManager.getConnection("jdbc:ucanaccess://C:/Projekt/testdb.accdb");
        } catch (SQLException ex) {
            // TODO Auto-generated catch block
            Logger.getLogger(TabelleProjekt.class.getName()).log(Level.SEVERE, null, ex);
        }
        return con;
    }

    class Projekt {
        private int Platz;
        private String ProjektName;
        private String StimmZahl;

        public Projekt(int platz, String projektName, String stimmZahl) {
            this.Platz = platz;
            this.ProjektName = projektName;
            this.StimmZahl = stimmZahl;
        }

        public int getPlatz() {
            return this.Platz;
        }

        public String getProjektName() {
            return this.ProjektName;
        }

        public String getStimmZahl() {
            return this.StimmZahl;
        }

        ArrayList<Projekt> getProjekt() {
            ArrayList<Projekt> projekt = new ArrayList<Projekt>();

            Connection con = getConnection();
            Statement st;
            ResultSet rs;
            Projekt p;

            try {
                st = con.createStatement();
                rs = st.executeQuery("SELECT * FROM JK_850_All_for_Vest_Future_T");

                while (rs.next()) {
                    p = new Projekt(rs.getInt("KBOE"), rs.getString("NAME"), rs.getString("VORNAME"));
                    projekt.add(p);

                }

            } catch (SQLException ex) {
                // TODO Auto-generated catch block
                Logger.getLogger(TabelleProjekt.class.getName()).log(Level.SEVERE, null, ex);
            }

            return projekt;

        }

        public void SimpleTableDemo() {
            /*
             * super(new GridLayout(1,0));
             */

            DefaultTableModel model = new DefaultTableModel();
            Object[] columnsName = new Object[3];
            columnsName[0] = "Platz";
            columnsName[1] = "Projektname";
            columnsName[2] = "Stimmzahl";

            model.setColumnIdentifiers(columnsName);

            Object[] rowData = new Object[3];

            for (int i = 0; i < getProjekt().size(); i++) {
                rowData[0] = getProjekt().get(i).getPlatz();
                rowData[1] = getProjekt().get(i).getProjektName();
                rowData[2] = getProjekt().get(i).getStimmZahl();

                model.addRow(rowData);

                final JTable table = new JTable(model);
                table.setPreferredScrollableViewportSize(new Dimension(500, 370));
                table.setFillsViewportHeight(true);

                if (DEBUG) {
                    table.addMouseListener(new MouseAdapter() {
                        public void mouseClicked(MouseEvent e) {
                            printDebugData(table);
                        }
                    });
                }

                // Create the scroll pane and add the table to it.
                JScrollPane scrollPane = new JScrollPane(table);

                // Add the scroll pane to this panel.
                add(scrollPane);
            }

        }

    }

    private void printDebugData(JTable table) {
        int numRows = table.getRowCount();
        int numCols = table.getColumnCount();
        javax.swing.table.TableModel model = table.getModel();

        System.out.println("Value of data: ");
        for (int i = 0; i < numRows; i++) {
            System.out.print("    row " + i + ":");
            for (int j = 0; j < numCols; j++) {
                System.out.print("  " + model.getValueAt(i, j));
            }
            System.out.println();
        }
        System.out.println("--------------------------");

    }

    /**
     * Create the GUI and show it. For thread safety, this method should be
     * invoked from the event-dispatching thread.
     */
    private static void createAndShowGUI() {
        // Create and set up the window.
        JFrame frame = new JFrame("SimpleTableDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create and set up the content pane.
        SimpleTableDemo newContentPane = new SimpleTableDemo();
        newContentPane.setOpaque(true); // content panes must be opaque
        frame.setContentPane(newContentPane);

        frame.setPreferredSize(new Dimension(500, 370));

        // Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        // Schedule a job for the event-dispatching thread:
        // creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

I just get an empty window

回答1:

The code relating to the frame can't be part of the class that extend the JPanel. That code should be part of the main() method of your class that creates the GUI.

Read the section from the Swing tutorial on How to Use Tables.

The SimpleTableDemo shows one way to structure your code so that the important logic is part of the class extending the JPanel.

Edit:

I have two objects that return columnnames and data from the database.... says my objects are undefined?!

Well the structure of your code is wrong if you are getting a compile error.

A simple way is to create a method to return the TableModel:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.table.*;

public class SSCCE extends JPanel
{
    SSCCE()
    {
        JTable table = new JTable( getTableModel() );
        JScrollPane scrollPane = new JScrollPane( table );

        setLayout( new BorderLayout() );
        add(scrollPane, BorderLayout.CENTER);
    }

    private TableModel getTableModel()
    {
        DefaultTableModel model = new DefaultTableModel(5, 3);

        return model;
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SSCCE());
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater( () -> createAndShowGUI() );
/*
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
*/
    }
}

I gave a simple implementation of the getTableModel() method.

Now you need to modify that method to get the data from your data base. So you need to:

  1. build the SQL
  2. get the ResultSet
  3. get the column names from the ResultSet
  4. get the rows of data from the ResultSet
  5. create the DefaultTableModel using the column names and data
  6. return the DefaultTableModel

Note there is no need for the Projekt class if you are just going to store each field separately in the TableModel. So get this simple approach working first.

Once you get the above suggestion working you may want to consider store the Projekt object in the TableModel. In this case you will need to create a custom TableModel. Checkout Row Table Model for an example of creating a custom TableModel for a specific object.

The purpose of the TableModel is to store the data. There should be no need for the ArrayList. That is you don't want to store data in two places. So the data from the ResultSet should be loaded directly to the TableModel.