【发布时间】:2020-03-31 12:37:05
【问题描述】:
我现在正在学习 Java,并尝试使用 Swing 制作记忆游戏。
在应用程序中,我希望能够调整游戏板的大小(这是一个带有多个按钮的 JPanel)。我尝试使用几个 JButton 来实现这一点,它们都具有相同的自定义 Actionlistener。按钮在它们注册点击并成功设置我的模型尺寸的意义上起作用。但是我无法让我的面板重绘。
下面的代码是否足以发现问题?
编辑:有人询问后,我添加了更多代码。
我将面板作为参数传递给我的听众。我不确定这是否是 Java 中的好习惯。还有更优雅的方式吗?
public class MemoryApp {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MemoryModel model = new MemoryModel();
MemoryView view = new MemoryView(model);
MemoryPanel panel = new MemoryPanel(model);
new MemoryController(model, view, panel);
}
});
}
}
public class MemoryModel {
private String faceText;
private boolean faceUp;
private int rows;
private int cols;
private int size;
private ArrayList<String> cards;
MemoryModel(){
this.rows = 2;
this.cols = 3;
this.size = this.rows * this.cols;
this.cards = new ArrayList<String>();
generateCards(getSize());
}
private void generateCards(int s) {
for (int i=0; i<s; i++) {this.cards.add("" + i);}
}
public String getCard(int index) {return cards.get(index);}
public int getSize() {return size;}
public void setCols(int cols) {this.cols = cols;}
public void setRows(int rows) {this.rows = rows;}
public void setSize(int size) {this.size = size;}
}
public class MemoryView extends JFrame{
private MemoryPanel memoryPanel;
private ToolBar toolBar;
public MemoryView(MemoryModel model){
super("title");
// setup frame configuration
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(640, 320);
setLocationRelativeTo(null);
setVisible(true);
// GUI elements
memoryPanel = new MemoryPanel(model);
toolBar = new ToolBar(model, memoryPanel);
// layout
setLayout(new BorderLayout());
// add components
add(toolBar, BorderLayout.NORTH);
add(memoryPanel, BorderLayout.CENTER);
}
}
public class MemoryPanel extends JPanel{
private ArrayList<JButton> memoryButtons;
private CardListener cardListener;
public MemoryPanel(MemoryModel model) {
memoryButtons = new ArrayList<JButton>();
cardListener = new CardListener(model);
for (int i=0; i < model.getSize() ; i++) {
JButton button = new JButton("text");
memoryButtons.add(button);
add(button);
}
setBorder(BorderFactory.createEtchedBorder());
setLayout(new GridLayout(model.getRows() ,model.getCols()));
}
}
public class ToolBar extends JPanel{
private JButton resizeSmall;
private JButton resizeMedium;
private ButtonListener buttonListener;
public ToolBar(MemoryModel model, MemoryPanel memoryPanel) {
buttonListener = new ButtonListener(model, memoryPanel);
resizeSmall = new JButton("resizeSmall");
resizeMedium = new JButton("resizeMedium");
resizeSmall.setName("resizeSmall");
resizeMedium.setName("resizeMedium");
resizeSmall.addActionListener(buttonListener);
resizeMedium.addActionListener(buttonListener);
add(resizeSmall);
add(resizeMedium);
setBorder(BorderFactory.createEtchedBorder());
setLayout(new GridLayout(1, 2));
}
}
public class ButtonListener implements ActionListener{
private MemoryModel model;
private int rows;
private int cols;
private JButton button;
private MemoryPanel panel;
public ButtonListener(MemoryModel model, MemoryPanel memoryPanel) {
this.model = model;
this.panel = memoryPanel;
}
@Override
public void actionPerformed(ActionEvent e) {
button = ((JButton) e.getSource());
switch(button.getName()) {
case "resizeSmall":
rows = 2;
cols = 3;
break;
case "resizeMedium":
// etc
case "resizeLarge":
// etc
}
model.setCols(cols);
model.setRows(rows);
model.setSize(rows*cols);
panel.revalidate();
panel.repaint();
}
}
【问题讨论】:
-
请发帖minimal reproducible example。 (
ButtonListener已发布但未在代码中使用。另一方面CardListener已使用但未发布) -
对不起。我添加了更多课程。并删除了对 CardListener 的引用,因为它与此处无关。
-
用户点击
ToolBar中的两个JButtons resizeSmall 或 resizeMedium 之一,这应该会改变网格的尺寸并且您想在网格的每个单元格中放置一个单独的JButton。我说的对吗? -
是的,没错。