1

Javaゲームにリスタート/リプレイ機能を追加しようとしています。現在、私のゲームクラス(GUIとゲームが初期化される場所)には、次のものがあります。

init() method
Game() object

ゲームオブジェクトには、ゲームウィンドウ全体のGUIが含まれ、さまざまなオブジェクト(実際のゲームウィンドウ、スコアボード、カウントダウンタイマーなど)が含まれます。

GUIの再起動ボタンをクリックした場合、またはゲームが終了した場合に、ゲームが(カウントダウンとスコアリングとともに)再起動する機能を追加したいと思います。オブジェクト(スコアリング、カウントダウン)を再インスタンス化するのが最善であることは理解していますが、インスタンス化すると、それらは私のGUIの一部になります。

i.e. add(scoreboard)

GUIを再インスタンス化せずにオブジェクトを再インスタンス化する方法はありますか?理想的には、GUI用の完全に新しいJFrameを再度開かなくても、オブジェクトを再インスタンス化したいと思います。誰かが私が持つべきクラスとメソッド(そしてそれらが何をするか)についてのある種の概要を私に提供してくれるなら、それは大いにありがたいです。

ありがとう!

4

1 に答える 1

5

データ(モデル)をGUI(ビュー)から分離します。

一例を挙げると、スコアボードはおそらくJTableです。JTableはビュークラスにあり、TableModelはモデルクラスにあります。

すべてのGUIコンポーネントに対して同じことを行います。コンポーネントごとに、モデルクラスにコンポーネントデータのモデルがあります。

これが私がまとめたストップウォッチGUIのモデルクラスです。GUIを見なくても、ストップウォッチを構成するすべてのデータコンポーネントを識別できるはずです。

package com.ggl.stopwatch.model;

import java.util.ArrayList;
import java.util.List;

import javax.swing.table.DefaultTableModel;

public class StopwatchModel {

    protected boolean isSplitTime;

    protected long startTime;

    protected long endTime;

    protected DefaultTableModel tableModel;

    protected List<Long> splitTimes;

    protected String[] columnNames = {"", "Increment", "Cumulative"};

    public StopwatchModel() {
        this.splitTimes = new ArrayList<Long>();
        this.isSplitTime = false;
        this.startTime = 0;
        this.endTime = 0;
        setTableModel();
    }

    public void resetTimes() {
        this.splitTimes.clear();
        this.isSplitTime = false;
        this.startTime = 0;
        this.endTime = 0;
    }

    public boolean isSplitTime() {
        return isSplitTime;
    }

    public long getStartTime() {
        return startTime;
    }

    public long getEndTime() {
        return endTime;
    }

    public long getLastSplitTime() {
        int size = splitTimes.size();
        if (size < 1) {
            return getStartTime();
        } else {
            return splitTimes.get(size - 1);
        }
    }

    public long getPenultimateSplitTime() {
        int size = splitTimes.size();
        if (size < 2) {
            return getStartTime();
        } else {
            return splitTimes.get(size - 2);
        }
    }

    public DefaultTableModel getTableModel() {
        return tableModel;
    }

    public int getTableModelRowCount() {
        return tableModel.getRowCount();
    }

    public void clearTableModel() {
        tableModel.setRowCount(0);
    }

    public int addTableModelRow(long startTime, long previousSplitTime, 
            long currentSplitTime, int splitCount) {
        String[] row = new String[3];

        row[0] = "Split " + ++splitCount;
        row[1] = formatTime(previousSplitTime, currentSplitTime, false);
        row[2] = formatTime(startTime, currentSplitTime, false);

        tableModel.addRow(row);

        return splitCount;
    }

    public void setStartTime() {
        if (getStartTime() == 0L) {
            this.startTime = System.currentTimeMillis();
        } else {
            long currentTime = System.currentTimeMillis();
            int size = splitTimes.size();
            if (size > 0) {
                long splitTime = splitTimes.get(size - 1);
                splitTime = splitTime - getEndTime() + currentTime;
                splitTimes.set(size - 1, splitTime);
            }
            this.startTime = currentTime - getEndTime() + getStartTime();
        }
    }

    protected void setTableModel() {
        this.tableModel = new DefaultTableModel();
        this.tableModel.addColumn(columnNames[0]);
        this.tableModel.addColumn(columnNames[1]);
        this.tableModel.addColumn(columnNames[2]);
    }

    public void setSplitTime() {
        this.splitTimes.add(System.currentTimeMillis());
        isSplitTime = true;
    }

    public void setEndTime() {
        Long split = System.currentTimeMillis();
        if (isSplitTime) {
            this.splitTimes.add(split);
        }
        this.endTime = split;
    }

    public String formatTime(long startTime, long time, boolean isTenths) {
        long elapsedTime = time - startTime;

        int seconds = (int) (elapsedTime / 1000L);

        int fraction = (int) (elapsedTime - ((long) seconds * 1000L));
        fraction = (fraction + 5) / 10;
        if (fraction > 99) {
            fraction = 0;
        }
        if (isTenths) {
            fraction = (fraction + 5) / 10;
            if (fraction > 9) {
                fraction = 0;
            }
        }


        int hours = seconds / 3600;
        seconds -= hours * 3600;

        int minutes = seconds / 60;
        seconds -= minutes * 60;

        StringBuilder builder = new StringBuilder();

        builder.append(hours);
        builder.append(":");
        if (minutes < 10) builder.append("0");
        builder.append(minutes);
        builder.append(":");
        if (seconds < 10) builder.append("0");
        builder.append(seconds);
        builder.append(".");
        if ((!isTenths) && (fraction < 10)) builder.append("0");
        builder.append(fraction);

        return builder.toString();
    }

}

分離したら、モデルクラスに初期化メソッドを配置します。

編集して追加:モデルクラスのインスタンスをビュークラスに渡して、ビューを生成します。これがストップウォッチGUIのメインパネルです。

package com.ggl.stopwatch.view;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

import com.ggl.stopwatch.model.StopwatchModel;
import com.ggl.stopwatch.thread.StopwatchThread;

public class StopwatchPanel {

    protected static final Insets entryInsets = new Insets(0, 10, 4, 10);
    protected static final Insets spaceInsets = new Insets(10, 10, 4, 10);

    protected JButton resetButton;
    protected JButton startButton;
    protected JButton splitButton;
    protected JButton stopButton;

    protected JLabel timeDisplayLabel;

    protected JPanel mainPanel;
    protected JPanel buttonPanel;
    protected JPanel startPanel;
    protected JPanel stopPanel;

    protected SplitScrollPane splitScrollPane;

    protected StopwatchModel model;

    protected StopwatchThread thread;

    public StopwatchPanel(StopwatchModel model) {
        this.model = model;
        createPartControl();
    }

    protected void createPartControl() {
        splitScrollPane = new SplitScrollPane(model);

        createStartPanel();
        createStopPanel();
        setButtonSizes(resetButton, startButton, splitButton, stopButton);

        mainPanel = new JPanel();
        mainPanel.setLayout(new GridBagLayout());

        int gridy = 0;

        JPanel displayPanel = new JPanel();
        displayPanel.setBorder(BorderFactory.createLineBorder(Color.BLUE, 6));

        timeDisplayLabel = new JLabel(model.formatTime(0L, 0L, true));
        timeDisplayLabel.setHorizontalAlignment(SwingConstants.CENTER);
        Font font = timeDisplayLabel.getFont();
        Font labelFont = font.deriveFont(60.0F);
        timeDisplayLabel.setFont(labelFont);
        timeDisplayLabel.setForeground(Color.BLUE);
        displayPanel.add(timeDisplayLabel);

        addComponent(mainPanel, displayPanel, 0, gridy++, 1, 1, spaceInsets,
                GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);

        buttonPanel = new JPanel();
        buttonPanel.add(startPanel);
        addComponent(mainPanel, buttonPanel, 0, gridy++, 1, 1, spaceInsets,
                GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);

        addComponent(mainPanel, splitScrollPane.getSplitScrollPane(), 0, gridy++, 1, 1, spaceInsets,
                GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
    }

    protected void createStartPanel() {
        startPanel = new JPanel();
        startPanel.setLayout(new FlowLayout());

        resetButton = new JButton("Reset");
        resetButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                model.resetTimes();
                timeDisplayLabel.setText(model.formatTime(0L, 0L, true));
                splitScrollPane.clearPanel();
                mainPanel.repaint();
            }
        });

        startPanel.add(resetButton);

        startButton = new JButton("Start");
        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                model.setStartTime();
                thread = new StopwatchThread(StopwatchPanel.this);
                thread.start();
                displayStopPanel();
            }
        });

        startPanel.add(startButton);
    }

    protected void createStopPanel() {
        stopPanel = new JPanel();
        stopPanel.setLayout(new FlowLayout());

        splitButton = new JButton("Split");
        splitButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                model.setSplitTime();
                splitScrollPane.addSplit(model.getStartTime(), 
                        model.getPenultimateSplitTime(), 
                        model.getLastSplitTime());
                splitScrollPane.setMaximum();
                splitScrollPane.repaint();
            }
        });

        stopPanel.add(splitButton);

        stopButton = new JButton("Stop");
        stopButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                model.setEndTime();
                thread.setRunning(false);
                if (model.isSplitTime()) {
                    splitScrollPane.addSplit(model.getStartTime(), 
                            model.getPenultimateSplitTime(), 
                            model.getLastSplitTime());
                    splitScrollPane.setMaximum();
                    splitScrollPane.repaint();
                }
                displayStartPanel();
            }
        });

        stopPanel.add(stopButton);
    }

    protected void addComponent(Container container, Component component,
            int gridx, int gridy, int gridwidth, int gridheight, 
            Insets insets, int anchor, int fill) {
        GridBagConstraints gbc = new GridBagConstraints(gridx, gridy,
                gridwidth, gridheight, 1.0D, 1.0D, anchor, fill, insets, 0, 0);
        container.add(component, gbc);
    }

    protected void displayStopPanel() {
        buttonPanel.remove(startPanel);
        buttonPanel.add(stopPanel);
        buttonPanel.repaint();
    }

    protected void displayStartPanel() {
        buttonPanel.remove(stopPanel);
        buttonPanel.add(startPanel);
        buttonPanel.repaint();
    }

    protected void setButtonSizes(JButton ... buttons) {
        Dimension preferredSize = new Dimension();
        for (JButton button : buttons) {
            Dimension d = button.getPreferredSize();
            preferredSize = setLarger(preferredSize, d);
        }
        for (JButton button : buttons) {
            button.setPreferredSize(preferredSize);
        }
    }

    protected Dimension setLarger(Dimension a, Dimension b) {
        Dimension d = new Dimension();
        d.height = Math.max(a.height, b.height);
        d.width = Math.max(a.width, b.width);
        return d;
    }

    public void setTimeDisplayLabel() {
        this.timeDisplayLabel.setText(model.formatTime(model.getStartTime(), 
                System.currentTimeMillis(), true));
    }

    public JPanel getMainPanel() {
        return mainPanel;
    }

}
于 2012-11-16T20:19:45.857 に答える