0

I'm finding that when I use removeAll() in JPanel, then attempt to add new contents via add() (e.g. a simple text JLabel), the original contents get cleared okay, but the new contents don't appear. Yes, I'm remembering to order a repaint() opperation on the JPanel afterwards, and yes, I'm conducting these opperations in SwingUtilities.invokeLater(). But if I leave the frame untouched, the new contents of the JPanel doesn't appear.

However, if I manually resize the frame, then the contents DOES appear.

Can anyone give me any advice as to how to get the contents to display by itself? Thanks.

Sample code:

public class SimpleTester extends JFrame implements WindowListener {

private static final long serialVersionUID = 6768852132139940161L;
private JPanel panel;

public SimpleTester() throws HeadlessException {
    super("SimpleTester");
    panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
    panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    panel.add(Box.createRigidArea(new Dimension(60, 60)));
    this.getContentPane().setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS));
    this.getContentPane().add(panel);
    this.addWindowListener(this);
    this.pack();
}

public static void main(String[] args) {
    SimpleTester tester = new SimpleTester();
    tester.setVisible(true);
    final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int pos = 0;
    while(true) {
        SwingUtilities.invokeLater(new Replacer(tester.mainPanel(), new JLabel(alphabet.substring(pos, pos+1))));
        pos++;
        if(pos>=alphabet.length()) {
            pos = 0;
        }
        synchronized(tester) {
            try {
                tester.wait(3000L);
            } catch (InterruptedException e) {
                System.exit(0);
            }
        }
    }
}

@Override
public void windowActivated(WindowEvent arg0) {
    // TODO Auto-generated method stub

}

@Override
public void windowClosed(WindowEvent arg0) {
    // TODO Auto-generated method stub

}

@Override
public void windowClosing(WindowEvent arg0) {
    System.exit(0);
}

@Override
public void windowDeactivated(WindowEvent arg0) {
    // TODO Auto-generated method stub

}

@Override
public void windowDeiconified(WindowEvent arg0) {
    // TODO Auto-generated method stub

}

@Override
public void windowIconified(WindowEvent arg0) {
    // TODO Auto-generated method stub

}

@Override
public void windowOpened(WindowEvent arg0) {
    // TODO Auto-generated method stub

}

public JPanel mainPanel() {
    return panel;
}

public static class Replacer implements Runnable {

    private JPanel holder;
    private Component [] fillers;

    public Replacer(JPanel host, Component... contents) {
        holder = host;
        fillers = contents;
    }

    @Override
    public void run() {
        holder.removeAll();
        holder.repaint();
        if(fillers==null) {             
        } else {
            for(int x=0;x<fillers.length;x++) {
                holder.add(fillers[x]);
            }
            holder.repaint();
        }
    }

}

}

Cambot
  • 257
  • 2
  • 13
  • 3
    You need to `revalidate()` the container too, before calling `repaint()`. – kiheru Nov 30 '14 at 12:39
  • 1
    Instead use a [`CardLayout`](http://download.oracle.com/javase/8/docs/api/java/awt/CardLayout.html) as shown in [this answer](http://stackoverflow.com/a/5786005/418556). – Andrew Thompson Nov 30 '14 at 13:34
  • @kiheru Thanks! That's just what I needed to know! – Cambot Dec 02 '14 at 10:43
  • @Andrew Thompson Thanks, also. This strikes me as a technique that would be superior to rebuilding the panel in many situations. Certainly handy to know about! – Cambot Dec 02 '14 at 10:46

0 Answers0