Añadir JScrollbar a JPanel con FlowLayout
Hola:
Me gustaria añadir un scrollbar a un jpanel con flowlayout y no hay manera, lo he intentado todo ya y no consigo hacerlo y lo peor de todo es que no se donde esta el fallo, la verdad es que soy bastante nuevo en java y aun tengo muchos fallos tontos por lo que me gustaria que alguien me pudiera ayudar a ver mi fallo y conseguir que salga la scrollbar.
Este es mi codigo:
package com.foolsrecords.tpv.tablaproductos.vista;
//Hacemos todas las importaciones necesarias
import com.foolsrecords.tpv.modelo.Producto;
import com.foolsrecords.tpv.modelo.eventos.ControladorEventListener;
import com.foolsrecords.tpv.modelo.eventos.ProductoSeleccionadoListener;
import com.foolsrecords.tpv.servicios.ServicioItemVenta;
import com.foolsrecords.tpv.servicios.ServicioProducto;
import com.foolsrecords.tpv.vista.componentes.JProductoButton;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
//Creamos la clase principal
public class TablaProductos extends javax.swing.JPanel {
//Creamos las variables y objetos necesarios para poder trabajar
private Map<Integer, JProductoButton> mapaProductos;
ProductoSeleccionadoListener objEven = new ProductoSeleccionadoListener(this);
ServicioItemVenta servItemVenta = new ServicioItemVenta();
//Creamos el constructor
public TablaProductos() {
initComponents();
inicializarPanelProductos(0); //con los subproductos de tipo 1
}
//Inicializamos el panel de productos y le pasamos la familia de los productos como parametro para mostrar los botones correctos
public void inicializarPanelProductos(int tipoProducto) {
//Creamos un objeto para conectar con la base de datos a traves de la clase servicioproducto
ServicioProducto servicio = new ServicioProducto();
//Conectamos con la base de datos y cojemos los productos de la familia enviada como parametro
List<Producto> productos = servicio.getProductos(tipoProducto);
//Creamos un mapaproductos para poder crear los botones dinamicamente
mapaProductos = new HashMap();
//Borramos el panel jpanelproductos para montarlo de nuevo como nosotros queremos
jpanelProductos.removeAll();
//Creamos los 15 botones que contendra el panel y los hacemos todos invisibles
for (int i = 1; i <= 30; i++) {
mapaProductos.put(i, new JProductoButton());
mapaProductos.get(i).addActionListener(objEven);
mapaProductos.get(i).setVisible(false);
jpanelProductos.add(mapaProductos.get(i), i - 1);
}
//Hacemos visibles tantos botones como productos tenemos en la familia enviada como parametro
for (int i = 0; i < productos.size(); i++) {
JProductoButton boton = mapaProductos.get(i + 1);
UIManager.put("Button.select", Color.WHITE);
boton.setVisible(true);
boton.setProducto(productos.get(i));
boton.setHorizontalTextPosition(SwingConstants.CENTER);
boton.setVerticalTextPosition(SwingConstants.BOTTOM);
boton.setFocusPainted(false);
boton.setBackground(Color.WHITE);
boton.setFont(new java.awt.Font("Arial", 1, 9));;
boton.setText(productos.get(i).getDescripcion());
boton.setIcon(new javax.swing.ImageIcon(productos.get(i).getImagen().getScaledInstance(88, 70, Image.SCALE_SMOOTH)));
boton.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 204), 2));
boton.setPreferredSize(new java.awt.Dimension(79, 97));
boton.setMinimumSize(new java.awt.Dimension(79, 97));
boton.setMaximumSize(new java.awt.Dimension(79, 97));
}
jpanelProductos.repaint();
}
//Este metodo es generado automaticamente por netbeans
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jScrollPane2 = new javax.swing.JScrollPane();
jpanelProductos = new javax.swing.JPanel();
setMinimumSize(new java.awt.Dimension(410, 300));
setName(""); // NOI18N
setPreferredSize(new java.awt.Dimension(410, 300));
setLayout(null);
jPanel1.setPreferredSize(new java.awt.Dimension(410, 300));
jPanel1.setLayout(null);
jpanelProductos.setPreferredSize(new java.awt.Dimension(400, 800));
jpanelProductos.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 2, 2));
jScrollPane2.setViewportView(jpanelProductos);
jPanel1.add(jScrollPane2);
jScrollPane2.setBounds(0, 0, 410, 300);
add(jPanel1);
jPanel1.setBounds(0, 0, 410, 300);
}// </editor-fold>
// Variables declaration - do not modify
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JPanel jpanelProductos;
// End of variables declaration
//Creamos los get y los set necesarios
public javax.swing.JPanel getJpanelProductos() {
return jpanelProductos;
}
public void setJpanelProductos(javax.swing.JPanel jpanelProductos) {
this.jpanelProductos = jpanelProductos;
}
public void setControlador(ControladorEventListener controlador) {
this.objEven.setControlador(controlador);
}
}
Si alguien pudiera ayudarme le estare muy agradecido.
Gracias por todo.
- Inicie sesión o regístrese para enviar comentarios
No entiendo cual es el problema
Hola, hice una pequeña prueba con el codigo que mostraste pero no entiendo cual es el problema que tienes o a qué resultado quieres llegar, esto es lo que me muestra a mi:
por favor proporciona más información
Hola: Gracias por todo, ya
Hola:
Gracias por todo, ya tengo funcionando mi codigo, simplemente lo borre todo y lo hice todo de nuevo por que ya me estaba volviendo loco y ahora todo funciona perfectamente, este es mi codigo nuevo:
package com.foolsrecords.tpv.tablaproductos.vista;
//Hacemos todas las importaciones necesarias
import com.foolsrecords.tpv.modelo.Producto;
import com.foolsrecords.tpv.modelo.eventos.ControladorEventListener;
import com.foolsrecords.tpv.modelo.eventos.ProductoSeleccionadoListener;
import com.foolsrecords.tpv.servicios.ServicioItemVenta;
import com.foolsrecords.tpv.servicios.ServicioProducto;
import com.foolsrecords.tpv.vista.componentes.JProductoButton;
import java.awt.Color;
import java.awt.Image;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
//Creamos la clase principal
public class TablaProductos extends javax.swing.JPanel {
//Creamos las variables y objetos necesarios para poder trabajar
private Map<Integer, JProductoButton> mapaProductos;
ProductoSeleccionadoListener objEven = new ProductoSeleccionadoListener(this);
ServicioItemVenta servItemVenta = new ServicioItemVenta();
//Creamos el constructor
public TablaProductos() {
initComponents();
inicializarPanelProductos(0); //con los subproductos de tipo 1
}
//Inicializamos el panel de productos y le pasamos la familia de los productos como parametro para mostrar los botones correctos
public void inicializarPanelProductos(int tipoProducto) {
//Creamos un objeto para conectar con la base de datos a traves de la clase servicioproducto
ServicioProducto servicio = new ServicioProducto();
//Conectamos con la base de datos y cojemos los productos de la familia enviada como parametro
List<Producto> productos = servicio.getProductos(tipoProducto);
//Creamos un mapaproductos para poder crear los botones dinamicamente
mapaProductos = new HashMap();
//Borramos el panel jpanelproductos para montarlo de nuevo como nosotros queremos
jpanelProductos.removeAll();
//Creamos los 15 botones que contendra el panel y los hacemos todos invisibles
for (int i = 1; i < productos.size()+2; i++) {
mapaProductos.put(i, new JProductoButton());
mapaProductos.get(i).addActionListener(objEven);
mapaProductos.get(i).setVisible(false);
jpanelProductos.add(mapaProductos.get(i), i - 1);
}
//Hacemos visibles tantos botones como productos tenemos en la familia enviada como parametro
for (int i = 0; i < productos.size(); i++) {
JProductoButton boton = mapaProductos.get(i + 1);
UIManager.put("Button.select", Color.WHITE);
boton.setVisible(true);
boton.setProducto(productos.get(i));
boton.setHorizontalTextPosition(SwingConstants.CENTER);
boton.setVerticalTextPosition(SwingConstants.BOTTOM);
boton.setFocusPainted(false);
boton.setBackground(Color.WHITE);
boton.setFont(new java.awt.Font("Arial", 1, 9));;
boton.setText(productos.get(i).getDescripcion());
boton.setIcon(new javax.swing.ImageIcon(productos.get(i).getImagen().getScaledInstance(88, 70, Image.SCALE_SMOOTH)));
boton.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 204), 2));
boton.setPreferredSize(new java.awt.Dimension(76, 97));
boton.setMinimumSize(new java.awt.Dimension(76, 97));
boton.setMaximumSize(new java.awt.Dimension(76, 97));
}
jpanelProductos.repaint();
}
//Este metodo es generado automaticamente por netbeans
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane2 = new javax.swing.JScrollPane();
jpanelProductos = new javax.swing.JPanel();
setMinimumSize(new java.awt.Dimension(410, 300));
setName(""); // NOI18N
setPreferredSize(new java.awt.Dimension(410, 300));
setLayout(null);
jpanelProductos.setPreferredSize(new java.awt.Dimension(350, 2000));
jpanelProductos.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 2, 2));
jScrollPane2.setViewportView(jpanelProductos);
add(jScrollPane2);
jScrollPane2.setBounds(0, 0, 410, 300);
}// </editor-fold>
// Variables declaration - do not modify
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JPanel jpanelProductos;
// End of variables declaration
//Creamos los get y los set necesarios
public javax.swing.JPanel getJpanelProductos() {
return jpanelProductos;
}
public void setJpanelProductos(javax.swing.JPanel jpanelProductos) {
this.jpanelProductos = jpanelProductos;
}
public void setControlador(ControladorEventListener controlador) {
this.objEven.setControlador(controlador);
}
public javax.swing.JScrollPane getjScrollPane2() {
return jScrollPane2;
}
public void setjScrollPane2(javax.swing.JScrollPane jScrollPane2) {
this.jScrollPane2 = jScrollPane2;
}
}
Ahora simplemente tengo un pequeño problema, la barra de scroll aparece siempre y yo quiero que aparezca solo cuando sea necesario, se que el problema es debido a que el jpanel es mucho mas grande que el jscrollpane pero lo tenia que poner mas grande para que saliera el scroll y no se como hacer que el jpanel crezca conforme voy añadiendo los botones de los distintos productos, si alguien puede ayudarme con esto o darme alguna idea estare muy agradecido.
Un saludo.
Encontré esto
No se exactamente como solucionar el problema, pero investigando un poco en internet me encontré con esto: http://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.htm...
que quizá te pueda ayudar...
Haré unas pruebas con esos ejemplos un poco más tarde cuando tenga tiempo
Pues
Pues agregando los botones manualmente al panel (mediante el evento clic de otro boton), el panel si cambia de tamaño gracias al método
JPanel.revalidate();
y tienen el efecto que tú quieres. Por lo que más o menos veo, el problema está en que los botones se crean automáticamente dentro de un ciclo for y, aunque llame a revalidate(), el panel no cambia de tamaño.Seguiré investigando alguna forma de agregar automáticamente los botones y hacer que crezca el panel, o tal vez ofrecerte una alternativa, como por ejemplo usar un JTable para mostrar los productos y utilizar un botón aparte y hacer que la acción del botón y la selección de una fila en el JTable se junten para pasar la información del producto a otro formulario, que yo supongo es lo que quieres hacer.
Espero haberme dado a entender bien...
Al parecer ya quedó
Después de experimentar un poco (o mucho) y de buscar, hice un par de modificaciones que quizá hagan que quede tu formulario como tienes planeado...
algunos de los cambios son estos:
jpanelProductos.revalidate();
yjpanelProductos.repaint();
después del ciclo donde haces visibles los botonesframe.setLayout(new BorderLayout();
GridLayout gl = new java.awt.GridLayout(0, 5); gl.setHgap(3); gl.setVgap(3);
Espero no se me olvide nada mas! y que esto te ayude
Hola pc-carm:Muchisimas
Hola pc-carm:
Muchisimas gracias por todo de verdad, me has guiado por el buen camino y gracias a ti lo tengo funcionando ya, si necesitas algo mio solo tienes que pedirmelo, muchisimas gracias de verdad.
Te explico, tu codigo no me ha servido tal y como me lo pones pero gracias a ti he dado con la solucion que es lo que cuenta. Lo que me dices iba perfecto pero tenia un pequeño problema con el gridlayout por eso lo quite ya de un principio, el problema es que igual hay un producto en el panel que 300 y cuando hay mas de 10 todo es perfecto pero si hay menos queda mal, te pongo unas imagenes para ke lo veas:
PANEL CON MAS DE 10 PRODUCTOS:
PANEL CON MENOS DE 10 PRODUCTOS:
Eso es lo que me pasa con tu solucion y ya me pasaba antes, pero gracias a ti he investigado por el buen camino y ya lo tengo solucionado todo y funcionando a la perfeccion, lo que te agradezco enormemente, solo he tenido que añadir 4 lineas de codigo que son estas:
int valor1 = (int) Math.ceil(alto) ;
int valor = valor1 * 100;
jpanelProductos.setPreferredSize(new java.awt.Dimension(350, valor));
Ahora ya todo funciona perfectamente, muchisimas gracias de nuevo, te debo una y gorda jejejeje.
Por si alguien lo quiere o
Por si alguien lo quiere o por si tu quieres verlo pc-carm dejo el codigo completo que funciona perfectamente:
package com.foolsrecords.tpv.tablaproductos.vista;
//Hacemos todas las importaciones necesarias
import com.foolsrecords.tpv.modelo.Producto;
import com.foolsrecords.tpv.modelo.eventos.ControladorEventListener;
import com.foolsrecords.tpv.modelo.eventos.ProductoSeleccionadoListener;
import com.foolsrecords.tpv.servicios.ServicioProducto;
import com.foolsrecords.tpv.vista.componentes.JProductoButton;
import java.awt.Color;
import java.awt.Image;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
//Creamos la clase principal
public class TablaProductos extends javax.swing.JPanel {
//Creamos las variables y objetos necesarios para poder trabajar
private Map<Integer, JProductoButton> mapaProductos;
ProductoSeleccionadoListener objEven = new ProductoSeleccionadoListener(this);
//Creamos el constructor
public TablaProductos() {
initComponents();
inicializarPanelProductos(0); //con los subproductos de tipo 1
}
//Inicializamos el panel de productos y le pasamos la familia de los productos como parametro para mostrar los botones correctos
public void inicializarPanelProductos(int tipoProducto) {
//Creamos un objeto para conectar con la base de datos a traves de la clase servicioproducto
ServicioProducto servicio = new ServicioProducto();
//Conectamos con la base de datos y cojemos los productos de la familia enviada como parametro
List<Producto> productos = servicio.getProductos(tipoProducto);
//Creamos un mapaproductos para poder crear los botones dinamicamente
mapaProductos = new HashMap();
//Borramos el panel jpanelproductos para montarlo de nuevo como nosotros queremos
jpanelProductos.removeAll();
//Creamos los 15 botones que contendra el panel y los hacemos todos invisibles
for (int i = 1; i < productos.size()+2; i++) {
mapaProductos.put(i, new JProductoButton());
mapaProductos.get(i).addActionListener(objEven);
mapaProductos.get(i).setVisible(false);
jpanelProductos.add(mapaProductos.get(i), i - 1);
}
//Hacemos visibles tantos botones como productos tenemos en la familia enviada como parametro
for (int i = 0; i < productos.size(); i++) {
JProductoButton boton = mapaProductos.get(i + 1);
UIManager.put("Button.select", Color.WHITE);
boton.setVisible(true);
boton.setProducto(productos.get(i));
boton.setHorizontalTextPosition(SwingConstants.CENTER);
boton.setVerticalTextPosition(SwingConstants.BOTTOM);
boton.setFocusPainted(false);
boton.setBackground(Color.WHITE);
boton.setFont(new java.awt.Font("Arial", 1, 9));;
boton.setText(productos.get(i).getDescripcion());
boton.setIcon(new javax.swing.ImageIcon(productos.get(i).getImagen().getScaledInstance(76, 70, Image.SCALE_SMOOTH)));
boton.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 204), 2));
boton.setPreferredSize(new java.awt.Dimension(76, 97));
boton.setMinimumSize(new java.awt.Dimension(76, 97));
boton.setMaximumSize(new java.awt.Dimension(76, 97));
}
double alto = (double)((double)productos.size()/5);
int valor1 = (int) Math.ceil(alto) ;
int valor = valor1 * 100;
jpanelProductos.setPreferredSize(new java.awt.Dimension(350, valor));
jpanelProductos.repaint();
jpanelProductos.revalidate();
}
//Este metodo es generado automaticamente por netbeans
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane2 = new javax.swing.JScrollPane();
jpanelProductos = new javax.swing.JPanel();
setMinimumSize(new java.awt.Dimension(410, 300));
setName(""); // NOI18N
setPreferredSize(new java.awt.Dimension(410, 300));
setLayout(null);
jScrollPane2.setBorder(null);
jpanelProductos.setPreferredSize(new java.awt.Dimension(350, 10));
jpanelProductos.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 2, 2));
jScrollPane2.setViewportView(jpanelProductos);
add(jScrollPane2);
jScrollPane2.setBounds(0, 0, 410, 300);
}// </editor-fold>
// Variables declaration - do not modify
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JPanel jpanelProductos;
// End of variables declaration
//Creamos los get y los set necesarios
public javax.swing.JPanel getJpanelProductos() {
return jpanelProductos;
}
public void setJpanelProductos(javax.swing.JPanel jpanelProductos) {
this.jpanelProductos = jpanelProductos;
}
public void setControlador(ControladorEventListener controlador) {
this.objEven.setControlador(controlador);
}
public javax.swing.JScrollPane getjScrollPane2() {
return jScrollPane2;
}
public void setjScrollPane2(javax.swing.JScrollPane jScrollPane2) {
this.jScrollPane2 = jScrollPane2;
}
}
De nuevo muchas gracias por todo.