我正在尝试为我的Java游戏添加重启/重播功能。当前在我的Game类(GUI和游戏被初始化的地方)中,我有:
init() method
Game() object
游戏对象包含整个游戏窗口的GUI,并包含各种对象(例如实际游戏窗口,计分板,倒数计时器等)。
我想添加一个功能,如果他们单击GUI上的重新启动按钮或游戏结束后,游戏将重新启动(以及倒计时和计分)。我确实意识到最好重新实例化对象(计分,倒数),但是一旦实例化,它们便成为我的GUI的一部分
i.e. add(scoreboard)
有没有一种方法可以重新实例化对象而不必重新实例化我的GUI?理想情况下,我只想重新实例化对象,而不必为GUI重新打开全新的JFrame。如果有人可以为我提供我应该拥有的类和方法(以及它们的用途)的概述,将不胜感激。
谢谢!
将数据(模型)与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;
}
}
问题内容: 如果我的进程正在加载.so库,并且该库有新版本可用,是否可以在不重新启动进程的情况下切换到新库?还是答案取决于诸如库中现有功能之一是否有参数更改之类的事情? 我正在一个相当大的系统中工作,该系统运行100多个进程,每个系统加载10多个库。这些库提供特定的功能,并由独立的团队提供。因此,当其中一个库发生更改(可以说是针对错误修复)时,理想的做法是在后台发布它而不影响运行的过程。可能吗 ?
问题内容: 我想知道是否可以在不重新启动JBoss服务器的情况下部署Java类文件。我正在使用jboss v4.2.2。 另外,当我尝试部署jsp文件时,它工作正常,服务器几乎立即接收到更改。 在此先感谢:) 问题答案: 我使用Tomcat比使用JBoss更好,但是应该可以(如在Tomcat中)重新启动应用程序而无需重新启动应用程序服务器。如果服务器具有“开发模式”并且该模式处于活动状态,则应该可
问题内容: 这个问题已经在这里有了答案 : While循环中的ReactorNotRestartable错误出现刮擦 (7个答案) 去年关闭。 与: 我一直成功地运行了此过程: 但由于我已将此代码移入一个函数中,因此: 并开始使用类实例化调用该方法,例如: 并运行: 我收到以下错误: 怎么了? 问题答案: 您不能重新启动反应堆,但是应该可以通过分叉一个单独的过程来使其运行更多次: 运行两次: 结果
本文向大家介绍nginx 重新启动NGINX,包括了nginx 重新启动NGINX的使用技巧和注意事项,需要的朋友参考一下 示例 以root用户身份: Ubuntu的例子
我希望容器在计算机重新启动后自动启动,所以我使用'--restart=always'标志,但它并没有像我预期的那样运行。当我重新启动系统时,容器没有启动。 docker日志信息 添加docker ps-a message,$docker ps-a CONTAINER ID IMAGE命令CREATED STATUS PORTS NAMES a1f4d5471b0a mysql:8.0“docker
Triathlon程序执行一个长时间运行的任务,如果该任务已完全执行,则有可能重新启动该任务。我想添加停止执行以重置UI的可能性。为了达到这个目的,我增加了一个新的按钮,停止。代码如下: 如果任务已经完成,程序很好地重新启动,但是如果我在停止它之后调用start,程序就会崩溃。我该纠正什么?