Search code examples
javaswingtimerdelayjlabel

Trying To Delay the Appearance of JLabels in a JDialog


Hi I've there a little problem: What I want is to delay the appearance of JLabels in a JDialog-Window, in terms of that the first line of JLabels shoud come out and then two seconds later the second line of Jlabels etc. I've tried something with Windowlistener,the doClick()-Method etc., bu every time the Jdialog revalidates all of its panels AT ONCE and shows them without any delaying!

Please help me(Just copy the code below and try out)!

package footballQuestioner;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;

public class attempter {

    public static void main(String[] args) throws InterruptedException {

        JDialog dialog = new Punkte();
    }

}

class Punkte extends JDialog {

    private JPanel screenPanel = new JPanel(new GridLayout(4, 1));
    private JButton button = new JButton();
    private int i = 1;

    private class WindowHandler implements WindowListener {

        @Override
        public void windowActivated(WindowEvent e) {

        }

        @Override
        public void windowClosed(WindowEvent e) {
        }

        @Override
        public void windowClosing(WindowEvent e) {
        }

        @Override
        public void windowDeactivated(WindowEvent e) {
        }

        @Override
        public void windowDeiconified(WindowEvent e) {
        }

        @Override
        public void windowIconified(WindowEvent e) {
        }

        @Override
        public void windowOpened(WindowEvent e) {
            button.doClick(1000);
            button.doClick(1000);
            button.doClick(1000);
            button.doClick(); // here im trying to delay the appearance of the
                                // JLabels....
        }

    }

    private class ButtonHandler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            switch (i) {

            case 1:
                settingUpPanel(getPanelFromScreenPanel(i), "Right", new Color(
                        102, 205, 0));
                settingUpPanel(getPanelFromScreenPanel(i), "Wrong", Color.RED);
                break;
            case 2:
                settingUpPanel(getPanelFromScreenPanel(i), "Trefferquote",
                        Color.YELLOW);
                break;
            case 3:
                settingUpPanel(getPanelFromScreenPanel(i), "Ausgezeichnet",
                        Color.BLUE);
                break;
            }
            System.out.println(i);
            i++;

        }
    }

    public Punkte() {

        button.addActionListener(new ButtonHandler());
        addWindowListener(new WindowHandler());

        setModal(true);
        setResizable(true);
        setLayout(new BorderLayout());
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        settingUpScreenPanel();

        add(screenPanel);

        setSize(1200, 1000);
        centeringWindow();
        setVisible(true);
    }

    private void settingUpScreenPanel() {

        JPanel titlePanel = new JPanel(new GridBagLayout());
        JPanel rightWrongCountPanel = new JPanel(new GridLayout(1, 2));
        JPanel shareOfRightQuestions = new JPanel(new GridBagLayout());
        JPanel grade = new JPanel(new GridBagLayout());

        settingUpPanel(titlePanel, "Result", Color.BLACK);

        // settingUpPanel(rightWrongCountPanel,
        // "Right: "+numberOfRightAnsers+"/6",new Color(102,205,0));
        // settingUpPanel(rightWrongCountPanel,
        // "Wrong: "+(6-numberOfRightAnsers)+"/6", Color.RED);
        // settingUpPanel(shareOfRightQuestions,
        // "Trefferquote: "+(numberOfRightAnsers*100/6)+"%",Color.YELLOW);
        // settingUpPanel(summaSummarum,
        // getBufferedImage("footballQuestioner/Strich.png"));
        // settingUpPanel(grade,"Aushezeichnet", Color.BLUE);

        borderingJPanel(screenPanel, null, null);

        titlePanel.setOpaque(false);
        rightWrongCountPanel.setOpaque(false);
        shareOfRightQuestions.setOpaque(false);
        grade.setOpaque(false);

        screenPanel.add(titlePanel);
        screenPanel.add(rightWrongCountPanel);
        screenPanel.add(shareOfRightQuestions);
        screenPanel.add(grade);

    }

    private void settingUpPanel(JComponent panel, String string, Color color) {

        Font font = new Font("Rockwell Extra Bold", Font.PLAIN, 65);
        JPanel innerPanel = new JPanel(new GridBagLayout());
        JLabel label = new JLabel(string);

        label.setForeground(color);
        label.setFont(font);

        innerPanel.add(label);
        innerPanel.setOpaque(false);

        panel.add(innerPanel);

        panel.validate();
        panel.repaint();

    }

    public JPanel getPanelFromScreenPanel(int numberOfPanel) {

        JPanel screenPanel = (JPanel) getContentPane().getComponent(0);
        JPanel labelPanel = (JPanel) screenPanel.getComponent(numberOfPanel);

        return labelPanel;
    }

    public void centeringWindow() {
        Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
        int x;
        int y;

        x = (int) (dimension.getWidth() - getWidth()) / 2;
        y = (int) (dimension.getHeight() - getHeight()) / 2;

        setLocation(x, y);
    }

    public void borderingJPanel(JComponent panel, String jPanelname,
            String fontStyle) {

        Font font = new Font(fontStyle, Font.BOLD + Font.ITALIC, 12);

        if (jPanelname != null) {
            panel.setBorder(BorderFactory.createTitledBorder(BorderFactory
                    .createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY,
                            Color.WHITE), jPanelname,
                    TitledBorder.DEFAULT_JUSTIFICATION,
                    TitledBorder.DEFAULT_POSITION, font));
        } else if (jPanelname == null || fontStyle == null) {
            panel.setBorder(BorderFactory.createTitledBorder(BorderFactory
                    .createEtchedBorder(EtchedBorder.LOWERED, Color.BLACK,
                            Color.WHITE)));
        }

        panel.setOpaque(false);

    }

}

Solution

  • This is a really good use case for javax.swing.Timer...

    This will allow you to schedule a callback, at a regular interval with which you can perform an action, safely on the UI.

    private class WindowHandler extends WindowAdapter {
    
        @Override
        public void windowOpened(WindowEvent e) {
            System.out.println("...");
            Timer timer = new Timer(2000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JPanel panel = getPanelFromScreenPanel(1);
                    panel.setLayout(new GridBagLayout());
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridwidth = GridBagConstraints.REMAINDER;
    
                    for (int index = 0; index < 100; index++) {
                        panel.add(new JLabel(Integer.toString(index)), gbc);
                    }
                    panel.revalidate();
                }
            });
            timer.start();
            timer.setRepeats(false);
        }
    
    }
    

    Now, if you wanted to do a series of actions, separated by the interval, you could use a counter to determine the number of "ticks" that have occurred and take appropriate action...

    private class WindowHandler extends WindowAdapter {
    
        @Override
        public void windowOpened(WindowEvent e) {
            System.out.println("...");
            Timer timer = new Timer(2000, new ActionListener() {
                private int counter = 0;
                private int maxActions = 10;
                @Override
                public void actionPerformed(ActionEvent e) {
                    switch (counter) {
                        case 0:
                            // Action for case 0...
                            break;
                        case 1:
                            // Action for case 1...
                            break;
                        .
                        .
                        .
                    }
                    counter++;
                    if (counter >= maxActions) {
                        ((Timer)e.getSource()).stop();
                    }
                }
            });
            timer.start();
        }
    
    }
    

    Take a look at How to use Swing Timers for more details