JTable con ArrayList como lo hago?

Hola amigos espero que me puedan brindar una ayuda con este problema lo que pasa es lo siguiente hice un programa que toma los datos de unos alumnos para hallar el promedio pero todos los datos los meti en un ArrayList (tiene datos tipo String y Double) hasta aqui todo bien el problema es quiero que al final me salga todo en una tabla para que se vea mas ordenado y no encuentro la manera para hacer el JTable ya que solo me acepta Strings les pego el codigo el programa corre y me saca la lista al final con los alumnos y el promedio de cada alumno pero quiero que al final me coloque los datos en una tabla gracias

PD disculpen si la pregunta parece muy tonta pero realmente tengo poco tiempo programando

// Importar libreria java.util.arralist para usar el arreglo multidatos (ArrayList)

// Importar libreria java.text.numberformat para darle formato a los datos tipo double
// esto para solo mostrar dos digitos en vez de los que se muestran originalmente (6)

// Importar libreria javax.swing.* para trabajar com ventanas
// Importar libreria java.awt.* para obtener tamaño de la pantalla
import java.util.ArrayList;
import java.text.NumberFormat;
import javax.swing.*;
import java.awt.*;

// Extender la clase main a JFrame para poder crear las ventanas
public class PDSemanaUno extends JFrame
{
// Se crea una variable para hallar las dimensiones de la pantalla y asignarle
// esos valores a la variable " tv "
private Dimension tv = Toolkit.getDefaultToolkit().getScreenSize();

// Se crea un constructor para crear la ventana principal del programa
// ojo el nombre del constructor debe ser igual al nombre del main
public PDSemanaUno()
{
// setTitle nombrar la ventana,setsize para darle el tamaño a la ventana
// setVisisble se pone true
setTitle("Procesamiento de Datos");
setSize(tv.width,tv.height);
setVisible(true);
}
// se crea una variable tipo static para almacenar el promedio, esta variable
// se usara en un metodo que devolvera un valor dado al main
static double prom;

public static void main( String args [] ){
// se llama al constructor PDsemanaUno para modo de pantalla completa
new PDSemanaUno();

// Declaracion de variables
String nom;
String mensaje1 = "Ingrese el nombre del estudiante: ";
String mensaje2 = "Ingrese calificacion N.-1 :";
String mensaje3 = "Ingrese calificacion N.-2 :";
String mensaje4 = "Ingrese calificacion N.-3 :";
int opc,cal1,cal2,cal3;

// Se crea un ArrayList de nombre lista para almacenar los datos
// De Diferentes tipos
ArrayList lista = new ArrayList();
// Se crea el NumberFormat a utilizar " nf "
NumberFormat nf = NumberFormat.getInstance();
// se indica la cantidad de decimales a mostrar
nf.setMaximumFractionDigits(2);
do{
// variable nom recibe valores de la ventana
nom = JOptionPane.showInputDialog(mensaje1);

// como las ventanas reciben solo valores tipo string debemos
// usar una variable auxiliar para " input " para luego transformar
// esos a valores por medio de un " parse " al valor deseado
String input = JOptionPane.showInputDialog(null,mensaje2);
cal1 = Integer.parseInt(input);
input = JOptionPane.showInputDialog(null,mensaje3);
cal2 = Integer.parseInt(input);
input = JOptionPane.showInputDialog(null,mensaje4);
cal3 = Integer.parseInt(input);

//lista.add añade al ArrayList la variable segun el caso con
lista.add("Nombre del alumno:\n"+nom);
lista.add("Calificacion 1:\n"+cal1);
lista.add("Calificacion 2:\n"+cal2);
lista.add("Calificacion 3\n"+cal3);

// usamos un metodo " promedio_individual " para hallar el promedio del
// alumno para eso enviamos al metodo las calificaciones 1,2,3
promedio_individual (cal1, cal2, cal3);
{
// despues de recibidos añadimos el valor del promedio " prom " al ArrayList
lista.add("Su promedio es:\n"+(nf.format( prom )));
// usamos JOptionpane para mostrar el promedio en una ventana
JOptionPane.showMessageDialog( null,"Su promedio es:\n"+(nf.format( prom )) );
}

// por medio de una ventana preguntamos si desea seguir agregando estudiantes
input = JOptionPane.showInputDialog(null,"¿Desea ingresar otro alumno?\n1.-Si\n2.-No" );
opc = Integer.parseInt(input);
}while(opc != 2);

// llamamos al metodo " lista_tabulada " para mostrar resultados del
// ArrayList " lista "
lista_tabulada (lista);
}

//Metodo promedio recibe los valores de las calificaciones 1,2,3 parar hallar
// el promedio
// para poder devolver valores a la clase main debe declararse la
// variable que sera devuelta fuera del metodo main como una variable static
// ejemplo "static float prom;" y el metodo a ser utilizar debe ser static
// ejemplo "public static float promedio(int calif1, int calif2, int calif3)"
// para poder ser usado el metodo puede ser publico o privado
public static double promedio_individual( int cal1, int cal2, int cal3)
{
double suma = cal1+cal2+cal3;
prom = suma/3;
return prom;
}

public static void lista_tabulada( ArrayList lista2 )
{
JTextArea outputTextArea = new JTextArea();

outputTextArea.setText( "\tLista de datos ingresados\n" );

for ( int i = 0; i < lista2.size(); i++ )
outputTextArea.append( lista2.get(i) + "\n" );

// display results
JOptionPane.showMessageDialog( null, outputTextArea,"Representacion tabular",
JOptionPane.INFORMATION_MESSAGE );

// salir de la ejecucion
System.exit(0);
}
}

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

TableModel

Puedes implementar TableModel o usar un DefaultTableModel o extender AbstractTableModel. Revisa esas clases y tambien Vector (porque DefaultTableModel usa un Vector de Vectores como fuente de datos).