updating JFrame again

前端 未结 2 1564
栀梦
栀梦 2021-01-25 16:07

The following code shown below will add 3 JLabels to a JFrame and then remove the 3 JLabels. After 2 seconds it will repaint back the 3 JLabels.

import javax.swi         


        
2条回答
  •  北荒
    北荒 (楼主)
    2021-01-25 16:54

    1. Simpy use a CardLayout to swap views in and out.
    2. Use a Swing Timer rather than your current background Thread as your current code is not Swing thread safe and carries risk of pernicious unpredictable thread exceptions.
    3. I would give the main JPanel the CardLayout, and then add a JLabel holding JPanel with a suitable String constant.
    4. I'd then add to the main CardLayout using JPanel, an empty JLabel using another String constant in the add method. i.e., add(new JLabel(), BLANK_COMPONENT);
    5. I'd then in my Swing Timer simply call next() on my CardLayout object, passing in the main CardLayout-using component: cardLayout.next(myMainJPanel);

    For example,

    import java.awt.CardLayout;
    import java.awt.Dimension;
    import java.awt.event.*;
    
    import javax.swing.*;
    
    public class RepaintTest extends JPanel {
       private static final int PREF_W = 400;
       private static final int PREF_H = PREF_W;
       private static final int LABEL_COUNT = 3;
       private static final String LABEL_PANEL = "label panel";
       private static final Object BLANK_COMPONENT = "blank component";
       private static final int TIMER_DELAY = 2000;
       private CardLayout cardLayout = new CardLayout();
    
       public RepaintTest() {
          JPanel labelPanel = new JPanel();
          for (int i = 0; i < LABEL_COUNT; i++) {
             labelPanel.add(new JLabel("Label " + (i + 1)));
          }
    
          setLayout(cardLayout);
          add(labelPanel, LABEL_PANEL);
          add(new JLabel(), BLANK_COMPONENT);
    
          new Timer(TIMER_DELAY, new TimerListener()).start();
    
       }
    
       @Override
       public Dimension getPreferredSize() {
          return new Dimension(PREF_W, PREF_H);
       }
    
       private class TimerListener implements ActionListener {
          @Override
          public void actionPerformed(ActionEvent e) {
             cardLayout.next(RepaintTest.this);
          }
       }
    
       private static void createAndShowGui() {
          RepaintTest mainPanel = new RepaintTest();
    
          JFrame frame = new JFrame("RepaintTest");
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
          frame.getContentPane().add(mainPanel);
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    

提交回复
热议问题