1

私はGUIクラスGuiを持っています:

public class Gui extends JFrame implements Runnable
{

private JPanel outer, inner;
private JLabel[][] labels = new JLabel[22][12];
private Color[][] defaultMap, map;
Thread t;
private int row, col;
private Color color;

public Gui()
{
    Container content = getContentPane();
    content.setLayout(new BorderLayout());

    setBackground(Color.BLACK);
    setSize(1000, 1000);
    setLocation(300, 0);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false);

    defaultMap = createMap();
    draw(defaultMap);
}

public Color[][] createMap()
{
    Color[][] map = new Color[22][12];
    for (int i = 0; i < 22; i++)
    {
        for (int j = 0; j < 12; j++)
        {
            map[i][j] = Color.WHITE;
        }
    }
    for (int i = 0; i < 22; i++)
    {
        map[i][0] = Color.GRAY;
        map[i][11] = Color.GRAY;
    }
    for (int i = 0; i < 12; i++)
    {
        map[0][i] = Color.GRAY;
        map[21][i] = Color.GRAY;
    }
    return map;
}

public void draw(Color[][] map)
{

    outer = new JPanel();
    outer.setLayout(new BorderLayout());
    outer.setBackground(Color.WHITE);
    outer.setPreferredSize(new Dimension());

    inner = new JPanel();
    inner.setLayout(new GridLayout(22, 12, 2, 2));
    inner.setBackground(Color.BLACK);

    for (int i = 0; i < 22; i++)
    {
        for (int j = 0; j < 12; j++)
        {
            labels[i][j] = new JLabel();
            JLabel label = labels[i][j];
            label.setPreferredSize(new Dimension(20, 20));
            label.setBackground(map[i][j]);
            label.setOpaque(true);
            inner.add(label);
        }
    }

    add(outer);
    add(inner);
    pack();
}

public void move(int row, int col, Color color)
{
    System.out.println(row+","+col);
    map = defaultMap;
    map[row][col] = color;
    t = new Thread(this);
    t.start();
}

@Override
public void run()
{
    draw(map);
}
}

私のメインクラスから次のように呼び出されます:

public static void main(String[] args)
{
    SwingUtilities.invokeLater(new Runnable()
    {
        @Override
        public void run()
        {
            try
            {
                gui = new Gui();
                gui.setVisible(true);
                gui.move(2,5,Color.GREEN);
                Thread.sleep(1000);
                gui.move(3,5,Color.GREEN);
                Thread.sleep(1000);
                gui.move(4,5,Color.GREEN);
            } catch (InterruptedException ex)
            {
                Logger.getLogger(Tetris.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    });
}

そのため、 gui.move() 関数が呼び出されると奇妙なことが起こっています。残りは無視するか、役立つ場合は使用できます。ただし、毎回、緑色のブロックを GUI の 2,5 に「追加」する必要があります。3,5; そして4,5; 1秒後。

問題:

Gui はしばらくの間黒のままで、すぐに適切なグリッドと色で再描画/更新され、最初の 2 つのブロックは正しく緑色に着色されていますが、4,5 の最後のブロックがありません。繰り返しますが、最初の「defaultMap」はすぐにペイントする必要がありますが、そうではありません。JFrame は、すべてが一度にペイントされて最後の緑のブロックが差し引かれるまで黒です。次に、各緑色のブロックを 1 秒おきにペイントする必要があります。

興味深い部分は、Gui の move メソッドの System.out.println() ビットが、期待どおりに行と列を出力することです...それらは、ターミナルで約 1 秒後に出力されます。つまり、何かがうまくいっているということです。しかし、Gui がどうなるかはわかりません...

編集:ストーリーのわずかな違い。よく調べてみると、マップ全体が塗りつぶされるとすぐに最後の緑色のブロックが一瞬表示されますが、すぐに白く塗り直されて「消える」ことに気付きました。

4

1 に答える 1

6

あなたは EDT (Event Dispatching Thread) で眠っています。EDT をブロックしないでください。

  • EDT に電話しないsleepでください。wait
  • 実行時間の長いすべてのタスクを他のスレッドに移動します (Executorsまたはを使用SwingWorker)
  • UI の繰り返し更新または遅延更新については、次を使用できます。javax.swing.Timer
  • すべての UI 操作は EDT で実行する必要があります (SwingUtilities.invokeLaterまたはjavax.swing.Timerまたはを使用)。SwingWorker

Swingタグ wikiで Swing の同時実行の詳細を参照してください。

于 2013-05-15T14:11:17.733 に答える