Question

I have a MessageWindow class that has to be initialized 4 times by a for loop, so I can see 4 messages in a JWindow for 3 seconds.

The problem is that I see only the last of them 'cause Timer( 3000, new ActionListener() { ... }); doesn't work for the others. What should I change?

import javax.swing.Timer;

import java.awt.event.*;

import javax.swing.*;

import java.util.*;

import java.awt.*;

public class Test extends JFrame {
private int playerInAction;

public Test() {
    setVisible( true );
    setSize( 800, 500 );
    setLocationRelativeTo( null );
    for( int i = 1; i < 5; i++ ) {
        playerInAction = i;
        System.out.println( "Player in Action: " + playerInAction );
        showJWindow();
    }
}

public static void main(String[] args) {
    Test c = new Test();
    c.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}

public void showJWindow() {
    final MessageWindow window = new MessageWindow( "John", playerInAction );
    window.setVisible( true );
    Timer timer = new Timer( 3000, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            window.dispose();
        }
    });
    timer.setRepeats( false );
    timer.start();
}

class MessageWindow extends JWindow {
    private Message m;
    private String[] player;

    MessageWindow( String playerName, int p ) {
        setSize( 320, 100 );
        setLocationRelativeTo( null );
        player = new String[2];
        player[0] = "";
        player[1] = "";

        switch( p ) {
            case 1: player[0] += playerName; break;
            case 2: player[0] += "Brian"; break;
            case 3: player[0] += "Elisabeth"; break;
            case 4: player[0] += "Jack"; break;
        }
        player[0] += "'s turn.";
        // player[1] += ...
        m = new Message( player );
        m.setBackground( Color.DARK_GRAY );
        // m.setOpaque( true );
        getContentPane().add( m );
    }

    private class Message extends JPanel {
        private Graphics2D graphic;
        private String[] player;

        Message( String[] player ) {
            this.player = player;
        }

        private void drawString( Graphics g, String[] text, int x, int y ) {
            int stringLen1 = (int) graphic.getFontMetrics().getStringBounds( text[0], graphic ).getWidth();  
            int start1 = ( getSize().width - stringLen1 ) / 2 - 30;
            int stringLen2 = (int) graphic.getFontMetrics().getStringBounds( text[1], graphic ).getWidth(); 
            int start2 = ( getSize().width - stringLen2 ) / 2;

            g.drawString( text[0], start1 + x, y += g.getFontMetrics().getHeight() );
            g.drawString( text[1], start2, y += g.getFontMetrics().getHeight() + 10 );
        }

        protected void paintComponent( Graphics g ) {
            super.paintComponent( g );
            graphic = ( Graphics2D ) g;

            Font font2 = new Font( "Segoe Print", Font.BOLD, 20 );
            graphic.setFont( font2 );
            graphic.setColor( Color.WHITE );
            drawString( g, player, 30, 0 );
            // player[1] = "";
            graphic.setColor( Color.RED );
            graphic.drawRect( 0, 0, getSize().width - 1, getSize().height - 1 );
        }
    }
}
}
Was it helpful?

Solution

Showing a JWindow is non-blocking, so your code should produce 4 JWindows, one on top of the other, all of which show the last player (as you changed the int variable as well).
If you want to show 4 JWindows one after another (Why? Isn't it easier to reuse the window?), then you should show the new window and start a new timer AFTER the previous one fired.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top