Hola que tal, llevo mucho tiempo sin escribir entradas en el blog ya que me he dedicado principalmente a mi canal de youtube (si no lo conoces puedes encontrarlo aquí) pero tengo toda la intención de retomarlo nuevamente y así ir compartiendo diferentes entradas que como siempre, se que les puede servir.
En esta oportunidad y despúes de que hace mucho me preguntaran por esto, quise hacer este ejemplo sobre como personalizar un JTable, ya en otra ocasión mostré como crear un JTable y llenarlo desde la BD (lo puedes ver aquí) pero ahora les mostraré básicamente todo lo necesario para poder controlar el estilo visual de este componente, agregarle colores, vincular otros elementos como botones o iconos entre otras cosas...
El resultado final será este
Estructura del proyecto.
Esta es la estructura del proyecto, es un ejemplo muy simple pero por organización quise agrupar las clases necesarias en paquetes las cuales iré explicando paso a paso.Aplicacion.java
Esta es la clase principal, será la encargada de iniciar al sistema llamando a la ventanaTabla.import gui.VentanaTabla; public class Aplicacion { public static void main(String[] args) { // TODO Auto-generated method stub VentanaTabla miVentana=new VentanaTabla(); miVentana.setVisible(true); } }
Utilidades.java
Esta clase simplemente cumplirá la función de almacenar variables estáticas o constantes que usaremos en todo el sistema, especificamente para las referencias a las columnas de nuestra tabla.package utilidades; public class Utilidades { public static final int DOCUMENTO=0; public static final int NOMBRE=1; public static final int DIRECCION=2; public static final int TELEFONO=3; public static final int PROFESION=4; public static final int EDAD=5; public static final int NOTA1=6; public static final int NOTA2=7; public static final int NOTA3=8; public static final int PROMEDIO=9; public static final int PERFIL=10; public static final int EVENTO=11; public static int filaSeleccionada; }
PersonaVo.java
Esta clase básicamente es un pojo qué nos permitirá gestionar la información que se presente en nuestra tabla, para este caso como no vamos a trabajar con bases de datos entonces simplemente usaremos el constructor con parámetros para ir asignando la información de las personas.package vo; public class PersonaVo { private String documento; private String nombre; private String direccion; private String telefono; private String profesion; private int edad; private double nota1; private double nota2; private double nota3; private double promedio; public PersonaVo(){ } public PersonaVo(String documento, String nombre, String direccion, String telefono, String profesion, int edad, double nota1, double nota2, double nota3, double promedio) { super(); this.documento = documento; this.nombre = nombre; this.direccion = direccion; this.telefono = telefono; this.profesion = profesion; this.edad = edad; this.nota1 = nota1; this.nota2 = nota2; this.nota3 = nota3; this.promedio = promedio; } public String getDocumento() { return documento; } public void setDocumento(String documento) { this.documento = documento; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getDireccion() { return direccion; } public void setDireccion(String direccion) { this.direccion = direccion; } public String getTelefono() { return telefono; } public void setTelefono(String telefono) { this.telefono = telefono; } public String getProfesion() { return profesion; } public void setProfesion(String profesion) { this.profesion = profesion; } public int getEdad() { return edad; } public void setEdad(int edad) { this.edad = edad; } public double getNota1() { return nota1; } public void setNota1(double nota1) { this.nota1 = nota1; } public double getNota2() { return nota2; } public void setNota2(double nota2) { this.nota2 = nota2; } public double getNota3() { return nota3; } public void setNota3(double nota3) { this.nota3 = nota3; } public double getPromedio() { return promedio; } public void setPromedio(double promedio) { this.promedio = promedio; } }
GestionEncabezadoTabla.java
Esta clase como ya se imaginarán es la encargada de definir el estilo visual del encabezado, aquí podremos establecer cual es el color del texto, tipo de fuente y color de las columnas a presentar, para eso debemos implementar la interfaz lo que permitirá sobreescribir el método getTableCellRendererComponent() encargado de la personalización.package utilidades; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.table.TableCellRenderer; // // Permite personalizar el encabezado de la tabla para definir el color que tendrá en las // columnas // @author CHENAO // // public class GestionEncabezadoTabla implements TableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JComponent jcomponent = null; if( value instanceof String ) { jcomponent = new JLabel((String) value); ((JLabel)jcomponent).setHorizontalAlignment( SwingConstants.CENTER ); ((JLabel)jcomponent).setSize( 30, jcomponent.getWidth() ); ((JLabel)jcomponent).setPreferredSize( new Dimension(6, jcomponent.getWidth()) ); } //jcomponent.setBorder(javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 1, new java.awt.Color(221, 211, 211))); jcomponent.setBorder(javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 1, new java.awt.Color(255, 255, 255))); jcomponent.setOpaque(true); //jcomponent.setBackground( new Color(236,234,219) ); jcomponent.setBackground( new Color(65,65,65) ); jcomponent.setToolTipText("Tabla Seguimiento"); jcomponent.setForeground(Color.white); return jcomponent; } }
ModeloTabla.java
Esta clase hereda de la clase DefaultTableModel y nos permitirá definir el modelo que alimentará a la tabla con los titulos de las columnas y los datos a presentar.package utilidades; import javax.swing.table.DefaultTableModel; public class ModeloTabla extends DefaultTableModel{ String[] titulos; Object[][] datos; // // Determina el modelo con el que se va a construir la tabla // @param datos // @param titulos // public ModeloTabla(Object[][] datos, String[] titulos) { super(); this.titulos=titulos; this.datos=datos; setDataVector(datos, titulos); } public ModeloTabla() { // TODO Auto-generated constructor stub } public boolean isCellEditable (int row, int column) { //Definimos si una celda puede ser o no editable if (column!=Utilidades.PERFIL && column!=Utilidades.EVENTO && column!=Utilidades.NOTA1 && column!=Utilidades.NOTA2 && column!=Utilidades.NOTA3){ return false; }else{ return true; } } }
adicionalmente se usa el método isCellEditable(int row, int column) que nos permitirá definir cuales campos de que columnas podrán ser editables o no, esto para el caso de que queramos introducir datos directamente o simplemente bloquear esta posiblidad.
GestionCeldas.java
Esta es una de las clases principales ya que determina el aspecto visual de la tabla específicamente hablando de las celdas, fuentes, componentes gráficos que queramos vincular entre otros aspectos, para este proceso heredamos de la clase DefaultTableCellRenderer y sobreescribimos el método getTableCellRendererComponent() que será llamado cada que se escuche algún evento sobre la tabla y así definir las acciones sobre las celdas.package utilidades; import java.awt.Color; import java.awt.Component; import java.awt.Font; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.table.DefaultTableCellRenderer; // // Esta clase permite gestionar la tabla y los eventos realizados sobre ella // cada celda seria un objeto personalizable // @author CHENAO // // public class GestionCeldas extends DefaultTableCellRenderer{ private String tipo="text"; //se definen por defecto los tipos de datos a usar private Font normal = new Font( "Verdana",Font.PLAIN ,12 ); private Font bold = new Font( "Verdana",Font.BOLD ,12 ); //etiqueta que almacenará el icono a mostrar private JLabel label = new JLabel(); //iconos disponibles para ser mostrados en la etiqueta dependiendo de la columna que lo contenga private ImageIcon iconoGuardar = new ImageIcon(getClass().getResource("/recursos/iconos/ico_guardar.png")); private ImageIcon iconoBuscar = new ImageIcon(getClass().getResource("/recursos/iconos/ico_buscar.png")); public GestionCeldas(){ } // //constructor explicito con el tipo de dato que tendrá la celda // @param tipo // public GestionCeldas(String tipo){ this.tipo=tipo; } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean focused, int row, int column) { // //Este metodo controla toda la tabla, podemos obtener el valor que contiene // definir que celda está seleccionada, la fila y columna al tener el foco en ella. // // cada evento sobre la tabla invocará a este metodo // //definimos colores por defecto Color colorFondo = null; Color colorFondoPorDefecto=new Color( 192, 192, 192); Color colorFondoSeleccion=new Color( 140, 140 , 140); /* * Si la celda del evento es la seleccionada se asigna el fondo por defecto para la selección */ if (selected) { this.setBackground(colorFondoPorDefecto ); } else { //Para las que no están seleccionadas se pinta el fondo de las celdas de blanco this.setBackground(Color.white); } /* * Se definen los tipos de datos que contendrán las celdas basado en la instancia que * se hace en la ventana de la tabla al momento de construirla */ if( tipo.equals("texto")) { //si es tipo texto define el color de fondo del texto y de la celda así como la alineación if (focused) { colorFondo=colorFondoSeleccion; }else{ colorFondo= colorFondoPorDefecto; } this.setHorizontalAlignment( JLabel.LEFT ); this.setText( (String) value ); //this.setForeground( (selected)? new Color(255,255,255) :new Color(0,0,0) ); //this.setForeground( (selected)? new Color(255,255,255) :new Color(32,117,32) ); this.setBackground( (selected)? colorFondo :Color.WHITE); this.setFont(normal); //this.setFont(bold); return this; } //si el tipo es icono entonces valida cual icono asignar a la etiqueta. if( tipo.equals("icono")) { if( String.valueOf(value).equals("PERFIL") ) { label.setIcon(iconoBuscar); } else if( String.valueOf(value).equals("EVENTO") ) { label.setIcon(iconoGuardar); } label.setHorizontalAlignment( JLabel.LEFT ); label.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED)); // return boton; return label; } //definie si el tipo de dato el numerico para personalizarlo if( tipo.equals("numerico")) { if (focused) { colorFondo=colorFondoSeleccion; }else{ colorFondo=colorFondoPorDefecto; } // System.out.println(value); this.setHorizontalAlignment( JLabel.CENTER ); this.setText( (String) value ); this.setForeground( (selected)? new Color(255,255,255) :new Color(32,117,32) ); this.setBackground( (selected)? colorFondo :Color.WHITE); // this.setBackground( (selected)? colorFondo :Color.MAGENTA); this.setFont(bold); return this; } return this; } }para definir los eventos sobre las celdas, cosas como cambiar de color si la celda contendrá datos numéricos o si se van a mostrar componentes graficos dentro de la celdas se usa la variable tipo y dependiendo de este se realiza la lógica necesaria de personalización.
VentanaTablas.java
Por último tenemos la ventana de nuestro sistema donde se presentará la tabla personalizada, aquí usamos las constantes de la clase Utilidades.java para definir las columnas que se presentarán, así mismo el método construirTabla() se encargará de definir el modelo y generar las instancias de la clase GestionCeldas.javapackage gui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.BevelBorder; import javax.swing.border.EmptyBorder; import javax.swing.table.JTableHeader; import utilidades.GestionCeldas; import utilidades.GestionEncabezadoTabla; import utilidades.ModeloTabla; import utilidades.Utilidades; import vo.PersonaVo; import javax.swing.JLabel; import javax.swing.JOptionPane; import java.awt.Font; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import javax.swing.JScrollPane; import javax.swing.JTable; public class VentanaTabla extends JFrame implements MouseListener{ private JPanel contentPane; private JScrollPane scrollPaneTabla; private JTable tablaPersonas; ArrayListComo pueder ver implementamos la interfaz MouseListener para definir los eventos del mouse en los iconos vinculados a la tabla, este proceso lo veremos en el onClick();listaPersonas;//lista que simula la información de la BD ModeloTabla modelo;//modelo definido en la clase ModeloTabla private int filasTabla; private int columnasTabla; public VentanaTabla() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(1121, 453); iniciarComponentes(); setLocationRelativeTo(null); construirTabla(); } private void iniciarComponentes() { contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(new BorderLayout(0, 0)); JLabel lblTablaPersonas = new JLabel("Tabla Personas"); lblTablaPersonas.setFont(new Font("Rockwell", Font.BOLD, 25)); contentPane.add(lblTablaPersonas, BorderLayout.NORTH); scrollPaneTabla = new JScrollPane(); contentPane.add(scrollPaneTabla); tablaPersonas = new JTable(); tablaPersonas.setBackground(Color.WHITE); tablaPersonas.setBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null)); tablaPersonas.addMouseListener(this); //tablaSeguimiento.addKeyListener(this); tablaPersonas.setOpaque(false); scrollPaneTabla.setViewportView(tablaPersonas); } // //Metodo que permite construir la tabla de personas //se crean primero las columnas y luego se asigna la información // private void construirTabla() { listaPersonas=consultarListaPersonas(); ArrayList titulosList=new ArrayList<>(); titulosList.add("Documento"); titulosList.add("Nombre"); titulosList.add("Direccion"); titulosList.add("Telefono"); titulosList.add("Profesion"); titulosList.add("Edad"); titulosList.add("Nota1"); titulosList.add("Nota2"); titulosList.add("Nota3"); titulosList.add("Promedio"); titulosList.add(" "); titulosList.add(" "); //se asignan las columnas al arreglo para enviarse al momento de construir la tabla String titulos[] = new String[titulosList.size()]; for (int i = 0; i < titulos.length; i++) { titulos[i]=titulosList.get(i); } //obtenemos los datos de la lista y los guardamos en la matriz //que luego se manda a construir la tabla Object[][] data =obtenerMatrizDatos(titulosList); construirTabla(titulos,data); } // //Permite simular el llenado de personas en una lista //que posteriormente alimentará la tabla //@return // private ArrayList consultarListaPersonas() { ArrayList lista=new ArrayList<>(); lista.add(new PersonaVo("1234", "Cristian David Henao", "Calle 2# 23-09 Armenia", "7564323", "Ingeniero",23, 2.5, 4.3, 3.0, (2.5+4.3+3)/33)); lista.add(new PersonaVo("3455", "Juan Camilo Perez", "Calle 2# 23-09 Armenia", "7564323", "Ingeniero",0, 0, 0,0,0)); lista.add(new PersonaVo("3214", "Marlon Guapacha", "Calle 2# 23-09 Armenia", "7564323", "Ingeniero",0, 0, 0,0,0)); lista.add(new PersonaVo("7886", "Marina Marin", "Calle 2# 23-09 Armenia", "7564323", "Ingeniero",0, 0, 0,0,0)); lista.add(new PersonaVo("4331", "Juliana Henao", "Calle 2# 23-09 Armenia", "7564323", "Ingeniero",0, 0, 0,0,0)); lista.add(new PersonaVo("98675", "David Henao", "Calle 2# 23-09 Armenia", "7564323", "Ingeniero",0, 0, 0,0,0)); lista.add(new PersonaVo("1221", "Cristian mendez Henao", "Calle 2# 23-09 Armenia", "7564323", "Ingeniero",0, 0, 0,0,0)); return lista; } // // Llena la información de la tabla usando la lista de personas trabajada // anteriormente, guardandola en una matriz que se retorna con toda // la información para luego ser asignada al modelo // @param titulosList // @return // private Object[][] obtenerMatrizDatos(ArrayList titulosList) { //se crea la matriz donde las filas son dinamicas pues corresponde //a todos los usuarios, mientras que las columnas son estaticas // correspondiendo a las columnas definidas por defecto // String informacion[][] = new String[listaPersonas.size()][titulosList.size()]; for (int x = 0; x < informacion.length; x++) { informacion[x][Utilidades.DOCUMENTO] = listaPersonas.get(x).getDocumento()+ ""; informacion[x][Utilidades.NOMBRE] = listaPersonas.get(x).getNombre()+ ""; informacion[x][Utilidades.DIRECCION] = listaPersonas.get(x).getDireccion()+ ""; informacion[x][Utilidades.TELEFONO] = listaPersonas.get(x).getTelefono()+ ""; informacion[x][Utilidades.PROFESION] = listaPersonas.get(x).getProfesion()+ ""; informacion[x][Utilidades.EDAD] = listaPersonas.get(x).getEdad()+ ""; informacion[x][Utilidades.NOTA1] = listaPersonas.get(x).getNota1()+ ""; informacion[x][Utilidades.NOTA2] = listaPersonas.get(x).getNota2()+ ""; informacion[x][Utilidades.NOTA3] = listaPersonas.get(x).getNota3()+ ""; informacion[x][Utilidades.PROMEDIO] = listaPersonas.get(x).getPromedio()+ ""; //se asignan las plabras clave para que en la clase GestionCeldas se use para asignar el icono correspondiente informacion[x][Utilidades.PERFIL] = "PERFIL"; informacion[x][Utilidades.EVENTO] = "EVENTO"; } return informacion; } // // Con los titulos y la información a mostrar se crea el modelo para // poder personalizar la tabla, asignando tamaño de celdas tanto en ancho como en alto // así como los tipos de datos que va a poder soportar. // @param titulos // @param data // private void construirTabla(String[] titulos, Object[][] data) { modelo=new ModeloTabla(data, titulos); //se asigna el modelo a la tabla tablaPersonas.setModel(modelo); filasTabla=tablaPersonas.getRowCount(); columnasTabla=tablaPersonas.getColumnCount(); //se asigna el tipo de dato que tendrán las celdas de cada columna definida respectivamente para validar su personalización tablaPersonas.getColumnModel().getColumn(Utilidades.EDAD).setCellRenderer(new GestionCeldas("numerico")); tablaPersonas.getColumnModel().getColumn(Utilidades.NOTA1).setCellRenderer(new GestionCeldas("numerico")); tablaPersonas.getColumnModel().getColumn(Utilidades.NOTA2).setCellRenderer(new GestionCeldas("numerico")); tablaPersonas.getColumnModel().getColumn(Utilidades.NOTA3).setCellRenderer(new GestionCeldas("numerico")); tablaPersonas.getColumnModel().getColumn(Utilidades.PROMEDIO).setCellRenderer(new GestionCeldas("numerico")); tablaPersonas.getColumnModel().getColumn(Utilidades.PERFIL).setCellRenderer(new GestionCeldas("icono")); tablaPersonas.getColumnModel().getColumn(Utilidades.EVENTO).setCellRenderer(new GestionCeldas("icono")); //se recorre y asigna el resto de celdas que serian las que almacenen datos de tipo texto for (int i = 0; i < titulos.length-7; i++) {//se resta 7 porque las ultimas 7 columnas se definen arriba System.out.println(i); tablaPersonas.getColumnModel().getColumn(i).setCellRenderer(new GestionCeldas("texto")); } tablaPersonas.getTableHeader().setReorderingAllowed(false); tablaPersonas.setRowHeight(25);//tamaño de las celdas tablaPersonas.setGridColor(new java.awt.Color(0, 0, 0)); //Se define el tamaño de largo para cada columna y su contenido tablaPersonas.getColumnModel().getColumn(Utilidades.DOCUMENTO).setPreferredWidth(130);//documento tablaPersonas.getColumnModel().getColumn(Utilidades.NOMBRE).setPreferredWidth(380);//nombre tablaPersonas.getColumnModel().getColumn(Utilidades.DIRECCION).setPreferredWidth(350);//direccion tablaPersonas.getColumnModel().getColumn(Utilidades.TELEFONO).setPreferredWidth(130);//telefono tablaPersonas.getColumnModel().getColumn(Utilidades.PROFESION).setPreferredWidth(280);//profesion tablaPersonas.getColumnModel().getColumn(Utilidades.EDAD).setPreferredWidth(80);//edad tablaPersonas.getColumnModel().getColumn(Utilidades.NOTA1).setPreferredWidth(100);//nota1 tablaPersonas.getColumnModel().getColumn(Utilidades.NOTA2).setPreferredWidth(100);//nota2 tablaPersonas.getColumnModel().getColumn(Utilidades.NOTA3).setPreferredWidth(100);//nota3 tablaPersonas.getColumnModel().getColumn(Utilidades.PROMEDIO).setPreferredWidth(130);//promedio tablaPersonas.getColumnModel().getColumn(Utilidades.PERFIL).setPreferredWidth(30);//accion perfil tablaPersonas.getColumnModel().getColumn(Utilidades.EVENTO).setPreferredWidth(30);//accion evento //personaliza el encabezado JTableHeader jtableHeader = tablaPersonas.getTableHeader(); jtableHeader.setDefaultRenderer(new GestionEncabezadoTabla()); tablaPersonas.setTableHeader(jtableHeader); //se asigna la tabla al scrollPane scrollPaneTabla.setViewportView(tablaPersonas); } @Override public void mouseClicked(MouseEvent e) { //capturo fila o columna dependiendo de mi necesidad int fila = tablaPersonas.rowAtPoint(e.getPoint()); int columna = tablaPersonas.columnAtPoint(e.getPoint()); //uso la columna para valiar si corresponde a la columna de perfil garantizando // que solo se produzca algo si selecciono una fila de esa columna // if (columna==Utilidades.PERFIL) { //sabiendo que corresponde a la columna de perfil, envio la posicion de la fila seleccionada validarSeleccionMouse(fila); }else if (columna==Utilidades.EVENTO){//se valida que sea la columna del otro evento JOptionPane.showMessageDialog(null, "Evento del otro icono"); } } // // Este metodo simularia el proceso o la acción que se quiere realizar si // se presiona alguno de los botones o iconos de la tabla // @param fila // private void validarSeleccionMouse(int fila) { Utilidades.filaSeleccionada=fila; //teniendo la fila entonces se obtiene el objeto correspondiente para enviarse como parammetro o imprimir la información PersonaVo miPersona=new PersonaVo(); miPersona.setDocumento(tablaPersonas.getValueAt(fila, Utilidades.DOCUMENTO).toString()); miPersona.setNombre(tablaPersonas.getValueAt(fila, Utilidades.NOMBRE).toString()); String info="INFO PERSONA\n"; info+="Documento: "+miPersona.getDocumento()+"\n"; info+="Nombre: "+miPersona.getNombre()+"\n"; JOptionPane.showMessageDialog(null, info); } //estos metododos pueden ser usados dependiendo de nuestra necesidad, por ejemplo para cambiar el tamaño del icono al ser presionado @Override public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub } }
Y listo, todo el código se encuenta documentado pero adicionalmente lo pueden encontrar en mi GITHUB desde este enlace, aquí termina nuestro ejemplo, espero que les pueda servir y sea de fácil entendimiento...
También te podría Interesar.
- Imagenes en Java
- Componentes de Texto.
- Componentes Atomicos Java Swing
- Componentes Java Swing
- Que es Java Swing?
- Clases Abstractas.
- Herencia en Java.
- ¿ String Vrs StringBuffer Vrs StringBuilder ?
- Comparando Fechas En Java
- Tutorial Aplicaciones Web con Jboss Seam
¿Hay algo que quieras anexar o comentar sobre esta entrada? no dudes en hacerlo.....y si te gustó...... te invito a compartir y Suscribirte ingresando al botón "Participar en este sitio" para darte cuenta de mas entradas como esta ;)
excelente tutorial cristian, tengo una consulta, tengo un jtable en una ventana y quiero introducirle los datos que recibo de un formulario que tengo en otra ventana, ¿cómo podría hacerlo?
ResponderEliminarHola, esos datos debes procesarlos en un ArrayList que luego asignarás al JTable, mira el proceso de llenado, en ese metodo asignas el array
EliminarTengo una pregunta, que parte del codigo me permitiria modificar los elementos (personas) directamente desde la tabla?
ResponderEliminarHola! Podría de alguna forma integrar este JTable en un JFrame, es que tengo mi proyecto diseñado y me gusta este estilo de tabla. Muchas gracias!.
ResponderEliminarque tal Cristian tus videos me han ayudado mucho a entender algunas cosa de java, estoy dando formato a tablas pero tengo un problema la barra del scroll horizontal no se activa y el ejemplo de tu blog tampoco lo hace me podrías orientar un poco, gracias.
ResponderEliminarque tal cristian tengo una pregunta en PERSONAVO no entiendo el porque de estas líneas y no lo explicas en tu video
ResponderEliminarpublic personaVo() {
}
Eso se llama constructor vacío
EliminarHola, muchas gracias, te lo has currado bien!! un buen trabajo y bien explicado.
ResponderEliminarBuenos días, una cosa a mejorar a mi aprecer, es si te animas a comentar más cada sentencia, pues se da que por más que el código ayuda mucho, al final no sacamos la idea de como hacerlo, sino que hacemos un mero copy paste, de tu código y lo modificamos. Gracias y saludos.
ResponderEliminarHola Cristian, muchas gracias por tus vídeos me han Sido de mucha ayuda, quiero hacerte una pregunta, a la hora de compilar el proyecto, no me deja ver esas ventanas dónde pongo estos formatos a las tablas, necesito de alguna librería que tenga que descargar para que me funcione en el .jar?
ResponderEliminarHola Cristian, te escribo de Perú, a tu proyecto JTable personalizado como le acoplaria datos de una tabla como el de Access??
ResponderEliminarMuchas gracias crack!!!
ResponderEliminarExcelente, sumamente claro y bien explicado. Gracias!!
ResponderEliminarCristian, estoy buscando los íconos que usaste pero no los encuentro. Gracias por tu ayuda.
ResponderEliminar