我在"重新启动"地图后让actionlistener在某些按钮上工作时遇到问题.事情是btns [1]到btns [9]根本不起作用!我的变量可能有些问题,我不确定.我尝试了一切.启动新地图后,这些按钮根本无法工作(按下按钮btns [0] ..新地图后).这是我的代码,希望你帮助我们.新板(null) - 如果构造函数中有null,它应该创建一个毯子映射,我已经在Board类的构造函数中编码了(我想这并不重要,因为它是第一次启动新游戏时工作(空值) ).
如果你发现它无法找到它无法正常工作的原因,我将整个游戏上传到sentpace = http://www.sendspace.com/file/pvwtoo - Jar形式, http://www.sendspace.com/file/l18khb - BlueJ表格 - 如有必要,可以更好地协调.非常感谢您提供的所有帮助.卢克
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Game extends JFrame implements ActionListener
{
Board b;
Menu m;
Container c = getContentPane();
JPanel pnl;
ImageIcon ii;
JLabel jl;
JTextArea jt;
private JButton [] btns = new JButton[10];
String selectMore = "Select more = false";
int posx,posy;
public Game(Map m) {
createGui(m);
}
public void createGui(Map mm)
{
b = new Board(mm);
//m = new Menu();
c.add(b);
pnl = new JPanel();
ii = new ImageIcon(this.getClass().getResource("menu.png"));
pnl.setLayout(new GridLayout(16,10));
pnl.setSize(100,608);
//pnl.add(m);
pnl.setBackground(Color.BLACK);
c.add(pnl,BorderLayout.LINE_END);
setTitle("Strgame");
c.setBackground(Color.BLACK);
//this.pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 608);
setLocationRelativeTo(null);
setResizable(false);
//setUndecorated(true);
//setExtendedState(Frame.MAXIMIZED_BOTH);
setVisible(true);
manageButtons();
infoPanel();
pnl.requestFocusInWindow();
requestFocusInWindow();
}
public void manageButtons()
{
if(pnl!=null){pnl.removeAll();}
btns[0] = new JButton("New Map");
btns[1] = new JButton("Change XY to House 1");
btns[2] = new JButton("Change XY to House 2");
btns[3] = new JButton("Change XY to Road 1");
btns[4] = new JButton("Change XY to Road 2");
btns[5] = new JButton("Change XY to Road 3");
btns[6] = new JButton("Change XY to Grass");
btns[7] = new JButton("Get info of selected");
btns[9] = new JButton(selectMore);
for(int i = 0; i < 10; i++)
{
if(btns[i] != null)
{
btns[i].addActionListener(this);
btns[i].setPreferredSize(new Dimension(213,10));
btns[i].setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
btns[i].setBackground(Color.lightGray);
pnl.add(btns[i]);
}
}
}
public void infoPanel()
{
jl = new JLabel("Info");
jl.setForeground(Color.lightGray);
jl.setHorizontalAlignment(SwingConstants.CENTER);
pnl.add(jl);
jt = new JTextArea();
//jt.setPreferredSize(new Dimension(211,10));
//jt.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
jt.setBackground(Color.lightGray);
//jt.setHorizontalAlignment(SwingConstants.CENTER);
jt.setMargin(new Insets(2,2,2,2));
jt.setEditable(false);
jt.setText(" Not selected");
pnl.add(jt);
}
public int posx()
{
int [] pom = b.lastPosSelected();
posx = pom[0];
return posx;
}
public int posy()
{
int [] pom = b.lastPosSelected();
posy = pom[1];
return posy;
}
public void actionPerformed(ActionEvent e)
{
String action = e.getActionCommand();
if(action.equals("New Map"))
{
createGui(null);
b.revalidate();
b.repaint();
c.repaint();
}
else if(action.equals("Change XY to House 1"))
{
b.changexy("house");
b.revalidate();
b.repaint();
c.repaint();
}
else if(action.equals("Change XY to House 2"))
{
b.changexy("house1");
b.revalidate();
b.repaint();
c.repaint();
}
else if(action.equals("Change XY to Road 1"))
{
b.changexy("road");
b.revalidate();
b.repaint();
c.repaint();
}
else if(action.equals("Change XY to Road 2"))
{
b.changexy("road1");
b.revalidate();
b.repaint();
c.repaint();
}
else if(action.equals("Change XY to Road 3"))
{
b.changexy("road2");
b.revalidate();
b.repaint();
c.repaint();
}
else if(action.equals("Change XY to Grass"))
{
b.changexy("grass");
b.revalidate();
b.repaint();
c.repaint();
}
else if(action.equals("Select more = false"))
{
b.selMore();
b.repaint();
selectMore = "Select more = true";
btns[9].setText(selectMore);
}
else if(action.equals("Select more = true"))
{
b.selMore();
b.repaint();
selectMore = "Select more = false";
btns[9].setText(selectMore);
}
else if(action.equals("Get info of selected"))
{
jt.setText(" Name: "+b.getSelected()+"\n Costs: "+b.getSelectedCost());
}
}
public static void main(String[] args) {
new Game(null);
}
}
Run Code Online (Sandbox Code Playgroud)
按钮的"动作命令"不一定是按钮的文本.尝试用文本替换测试
if (e.getSource() == button[1])
或类似的有可靠的测试.如果它完全有效,那更有可能是运气 - 规范中没有任何内容表明按钮文本将是动作命令,事实上如果你使用a javax.swing.Action,它通常不会.
此代码还存在许多其他问题,使其更难以阅读和预测它的作用:
"THE CONSTANT".equals(something)因为您可以保证常量不为空; 另一种方法是空指针异常.
createGui,并使Pnl字段最终.然后代码更简单,您可以使用编译器来证明 pnl不能为null,从可能性的范围中消除整个类别的bug.invalidate(); revalidate(); repaint();咒语来确保显示更新 - 此处的代码是否有效将因JDK和外观而异.实际上,您根本不需要重建GUI.我认为,当重置程序状态而不是将当前显示的GUI更改为其初始状态时,不会以几乎递归的方式创建新的GUI会好得多.这可能是你的问题所在.
换句话说,我会改变这个:
if (action.equals("New Map")) {
createGui(null);
b.revalidate();
b.repaint();
c.repaint();
}
Run Code Online (Sandbox Code Playgroud)
对此:
if (action.equals("New Map")) {
b.reset();
}
Run Code Online (Sandbox Code Playgroud)
当然reset(),它会为Board类提供一种重置其状态和显示的方法.
有关更多帮助,请发布sscce,而不是指向大型复杂GUI的链接.
编辑,我的SSCCE:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Game extends JFrame implements ActionListener {
Board b;
Menu m;
Container c = getContentPane();
JPanel pnl;
JLabel jl;
JTextArea jt;
private JButton[] btns = new JButton[10];
String selectMore = "Select more = false";
int posx, posy;
public Game(Map m) {
createGui(m);
}
public void createGui(Map mm) {
b = new Board(mm);
c.add(b);
pnl = new JPanel();
pnl.setLayout(new GridLayout(16, 10));
pnl.setSize(100, 608);
pnl.setBackground(Color.BLACK);
c.add(pnl, BorderLayout.LINE_END);
setTitle("Strgame");
c.setBackground(Color.BLACK);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 608);
setLocationRelativeTo(null);
setVisible(true);
manageButtons();
infoPanel();
pnl.requestFocusInWindow();
requestFocusInWindow();
}
public void manageButtons() {
if (pnl != null) {
pnl.removeAll();
}
btns[0] = new JButton("New Map");
btns[1] = new JButton("Change XY to House 1");
System.out.println("btns[1] hash: " + btns[1].hashCode());
btns[2] = new JButton("Change XY to House 2");
btns[3] = new JButton("Change XY to Road 1");
btns[4] = new JButton("Change XY to Road 2");
btns[5] = new JButton("Change XY to Road 3");
btns[6] = new JButton("Change XY to Grass");
btns[7] = new JButton("Get info of selected");
btns[9] = new JButton(selectMore);
for (int i = 0; i < 10; i++) {
if (btns[i] != null) {
btns[i].addActionListener(this);
btns[i].setPreferredSize(new Dimension(213, 10));
btns[i].setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
btns[i].setBackground(Color.lightGray);
pnl.add(btns[i]);
}
}
}
public void infoPanel() {
jl = new JLabel("Info");
jl.setForeground(Color.lightGray);
jl.setHorizontalAlignment(SwingConstants.CENTER);
pnl.add(jl);
jt = new JTextArea();
jt.setBackground(Color.lightGray);
jt.setMargin(new Insets(2, 2, 2, 2));
jt.setEditable(false);
jt.setText(" Not selected");
pnl.add(jt);
}
public int posx() {
int[] pom = b.lastPosSelected();
posx = pom[0];
return posx;
}
public int posy() {
int[] pom = b.lastPosSelected();
posy = pom[1];
return posy;
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
System.out.println("source hash: " + source.hashCode());
String action = e.getActionCommand();
if (action.equals("New Map")) {
createGui(null);
b.revalidate();
b.repaint();
c.repaint();
} else if (action.equals("Change XY to House 1")) {
b.changexy("house");
b.revalidate();
b.repaint();
c.repaint();
} else if (action.equals("Change XY to House 2")) {
b.changexy("house1");
b.revalidate();
b.repaint();
c.repaint();
} else if (action.equals("Change XY to Road 1")) {
b.changexy("road");
b.revalidate();
b.repaint();
c.repaint();
} else if (action.equals("Change XY to Road 2")) {
b.changexy("road1");
b.revalidate();
b.repaint();
c.repaint();
} else if (action.equals("Change XY to Road 3")) {
b.changexy("road2");
b.revalidate();
b.repaint();
c.repaint();
} else if (action.equals("Change XY to Grass")) {
b.changexy("grass");
b.revalidate();
b.repaint();
c.repaint();
} else if (action.equals("Select more = false")) {
b.selMore();
b.repaint();
selectMore = "Select more = true";
btns[9].setText(selectMore);
} else if (action.equals("Select more = true")) {
b.selMore();
b.repaint();
selectMore = "Select more = false";
btns[9].setText(selectMore);
} else if (action.equals("Get info of selected")) {
jt.setText(" Name: " + b.getSelected() + "\n Costs: "
+ b.getSelectedCost());
}
}
public static void main(String[] args) {
new Game(null);
}
}
class Board extends JPanel {
private Map map;
private JLabel xyLabel = new JLabel(" ");
public Board(Map map) {
this.map = map;
add(xyLabel);
}
public String getSelectedCost() {
return "getSelectedCose";
}
public String getSelected() {
return "getSelected";
}
public void selMore() {
}
public void changexy(String xy) {
xyLabel.setText(xy);
}
public int[] lastPosSelected() {
return new int[] { 1, 2, 3, 4 };
}
}
class Map {
}
Run Code Online (Sandbox Code Playgroud)
如果你运行它,你会从打印的哈希码中看到你的gui正在从创建的第一组按钮获得响应,而不是第二组,这就是你的GUI无法工作的原因.
例如,我的输出看起来像这样:
btns[1] hash: 17514905
source hash: 17514905
source hash: 17514905
source hash: 12934710
btns[1] hash: 23063136
source hash: 17514905
Run Code Online (Sandbox Code Playgroud)
再次,如果您遵循我的初步建议,这一切都可以解决:重置您的主板,不要更换它,当然不要替换所有菜单按钮.
pack()在设置之后,您还需要GUI,而不是设置任何尺寸.
| 归档时间: |
|
| 查看次数: |
1007 次 |
| 最近记录: |