java - used - JPanel no se actualiza hasta cambiar el tamaño de Jframe
que es jpanel java (5)
Eche un vistazo a los documentos para JPanel.add()
, que hereda de java.awt.Container
:
Anexa el componente especificado al final de este contenedor. Este es un método conveniente para addImpl (java.awt.Component, java.lang.Object, int). Este método cambia la información relacionada con el diseño y, por lo tanto, invalida la jerarquía de componentes. Si el contenedor ya se ha mostrado, la jerarquía debe validarse posteriormente para mostrar el componente agregado.
Énfasis añadido.
Por lo tanto, si modifica un contenedor después de que ya se haya mostrado, debe llamar a validate()
para que se muestre. Simplemente invocar repaint()
no es suficiente. Es posible que haya notado que llamar a setVisible(true)
también funciona; esto se debe a que llama a validate()
internamente .
Subclasifico JPanel para sobrescribir paintComponent (Graphics), quiero dibujar una imagen en jpanel en un jframe
Pero mi imagen no se muestra hasta que hago un cambio al tamaño de jframe. Este es mi código:
public class ImagePanel extends JPanel{
public void setImage(BufferedImage bi)
{
image = bi;
revalidate();
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(image != null)
{
g.drawImage(image, 0, 0, this);
}
}
}
Si desea "actualizar" el JPanel, debe llamar a repaint (), que llamará a su paintComponent (). Esto debería solucionar su problema:
public void setImage(BufferedImage bi)
{
image = bi;
EventQueue.invokeLater(new Runnable()
{
public void run()
{
repaint();
}
});
}
Es una buena práctica actualizar y cambiar la GUI utilizando la EDT. Aquí hay más información sobre la EDT si está interesado:
¿Cómo funciona el hilo de despacho de eventos?
repaint
no necesita ser llamado desde el EDT. Si está cambiando la GUI, como establecer texto en una JLabel, debería estar dentro de la EDT. Aquí hay más información sobre lo que se puede llamar fuera de la EDT (cortesía de nIcE cOw):
También tuve el mismo problema pero encontré una solución. Simplemente cree un objeto jframe
en la parte superior y llame a los métodos jframe
en la parte inferior como jf.pack()
, jf.setVisible()
, jf.setSize()
, jf.setDefaultCloseOpetion()
debe estar en la parte inferior de todas las interfaces de usuario agregadas. marco usted encontrará que funciona muy bien.
Tuve el mismo problema y lo solucioné mediante una llamada a setVisible (true); El JFrame que estaba usando.
Ejemplo: si su JFrame no se actualiza después de usar:
jframe.setContentPane(new MyContentPane());
arreglarlo con:
jframe.setContentPane(new MyContentPane());
jframe.setVisible(true);
Sé que suena tonto hacer esto aunque tu JFrame ya esté visible, pero esa es la única manera que he encontrado hasta ahora para solucionar este problema (la solución propuesta anteriormente no me funcionó).
Aquí hay un ejemplo completo. Ejecútelo y luego descomente el "f.setVisible (true);" Instrucciones en las clases Panel1 y Panel2 y verás la diferencia. No olvide las importaciones (Ctrl + Shift + O para las importaciones automáticas).
Clase principal :
public class Main {
private static JFrame f;
public static void main(String[] args) {
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(new Panel1(f));
f.pack();
f.setVisible(true);
}
}
Clase panel1:
public class Panel1 extends JPanel{
private JFrame f;
public Panel1(JFrame frame) {
f = frame;
this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
JButton b = new JButton("Panel 1");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
f.setContentPane(new Panel2(f));
// Uncomment the instruction below to fix GUI "update-on-resize-only" problem
//f.setVisible(true);
}
});
add(b);
}
}
Clase panel2:
public class Panel2 extends JPanel{
private JFrame f;
public Panel2(JFrame frame) {
f = frame;
this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
JButton b = new JButton("Panel 2");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
f.setContentPane(new Panel1(f));
// Uncomment the instruction below to fix GUI "update-on-resize-only" problem
//f.setVisible(true);
}
});
add(b);
}
}
Espero que ayude.
Saludos.