重置按钮数组

时间:2018-02-09 20:27:17

标签: java swing jbutton

我正在创建一个程序,我必须不时重置一个按钮Array并将其显示在jPanel上。下面的函数将jButtons添加到我的面板并在第一次调用它时完美地显示它们,但从那时起,每次调用它(在清空jButton数组并将.removeAll()应用到面板之后)它都不会让我改变了jButton的背景颜色。一些帮助,以帮助我找出为什么这将是伟大的,谢谢。

import java.awt.*;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import javafx.scene.layout.Border;
import javax.swing.*;

/**
 *
 * @author Luis
 */
public class MineSweeper extends JFrame implements ActionListener {

    int int_dim = 11;
    int int_cellsShown = 0;
    JButton[][] arr_btnField = new JButton[int_dim][int_dim];
    int[][] arr_solution = new int[int_dim][int_dim];
    Color[] clr_palette = {Color.white, new Color(0X00, 0X94, 0XFF), new Color(0X00, 0X26, 0XFF), new Color(0X00, 0XAA, 0X0A), Color.red, Color.MAGENTA, new Color(0XFF, 0X00, 0X00), new Color(0X9B, 0X00, 0X00)};
    boolean bool_change = false;
    boolean bool_won = false;
    boolean bool_firstround = false;

javax.swing.border.Border border = BorderFactory.createLineBorder(Color.darkGray, 1, true);

MenuBar menu_bar;
Menu menu;
MenuItem optionNew;
//boolean[][] arr_boolShowed=new boolean[int_dim][int_dim];
int int_mines = 8;
ArrayList<Integer> arl_field = new ArrayList<Integer>();
JPanel jpanel = new JPanel();
JPanel jpanel2 = new JPanel();

//ArrayList<Boolean> arl_boolShowed = new ArrayList<Boolean>();
/**
 * @param args the command line arguments
 */
public MineSweeper() throws FontFormatException, IOException {

    resetGame();

    //JFrame frame = new JFrame("");
    this.getContentPane().add(jpanel);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setResizable(true);
    this.setTitle("Minesweeper");
    this.pack();
    this.setLocationRelativeTo(null);
    this.setVisible(true);
    this.setSize(500, 500);

    menu_bar = new MenuBar();
    menu = new Menu("File");
    optionNew = new MenuItem("Win");
    optionNew.addActionListener(this);
    menu.add(optionNew);
    menu_bar.add(menu);
    this.setMenuBar(menu_bar);
}

public void resetGame() {
    jpanel.removeAll();
    arl_field.clear();

    arr_btnField = new JButton[int_dim][int_dim];
    arr_solution = new int[int_dim][int_dim];
    bool_change = false;
    bool_won = false;
    //arl_field = new ArrayList<Integer>();

    for (int i = 0; i < arr_solution.length; i++) {
        for (int j = 0; j < arr_solution[i].length; j++) {
            arr_solution[i][j] = 1;
        }
    }

    jpanel.setLayout(new GridLayout(0, int_dim));//if(bool_firstround==false)jpanel.setLayout(new GridLayout(0,int_dim));

    for (int i = 0; i < arr_btnField.length; i++) {
        for (int j = 0; j < arr_btnField[i].length; j++) {
            arr_btnField[i][j] = new JButton();////if(bool_firstround==false)arr_btnField[i][j] = new JButton();//arl_field.get(i*int_dim+j)+"");
            arr_btnField[i][j].setText("");
            arr_btnField[i][j].setBackground(new Color(0X00, 0X94, 0XFF));
            arr_btnField[i][j].setBorder(border);
            arr_btnField[i][j].setForeground(clr_palette[1]);
            arr_btnField[i][j].addMouseListener(listener);
            arr_btnField[i][j].setFocusable(false);
            jpanel.add(arr_btnField[i][j]);
        }
    }

    jpanel.revalidate();
    jpanel.repaint();
}

public static void main(String[] args) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                new MineSweeper();
                UIManager.setLookAndFeel(
                        UIManager.getSystemLookAndFeelClassName());
            } catch (Exception ex) {
            }
        }
    });
}

MouseListener listener = new MouseListener() {
    @Override
    public void mouseClicked(MouseEvent e) {

    }

    @Override
    public void mousePressed(MouseEvent e) {
        outerloop:
        for (int i = 0; i < arr_btnField.length; i++) {
            for (int j = 0; j < arr_btnField[i].length; j++) {
                if (e.getSource() == arr_btnField[i][j]) {
                    if (SwingUtilities.isLeftMouseButton(e)) {
                        labelText(i, j);
                    }
                    if (SwingUtilities.isRightMouseButton(e)) {
                        arr_btnField[i][j].setBackground(Color.red);
                    }
                    //bool_won=false;
                    break outerloop;
                }
            }
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        if (bool_won == true)
            gameWon();
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

};

public void labelText(int i, int j) {
    if (bool_won == false) {
        arr_btnField[i][j].setText("1");
        arr_btnField[i][j].setBackground(Color.white);
        if (arr_btnField[i][j].getBorder() == border) {
            int_cellsShown++;
            System.out.println("Cells shown: " + int_cellsShown);
            if (int_cellsShown >= (int_dim * int_dim - int_mines)) {
                bool_won = true;
            }
        }
        if (bool_won == false)
            arr_btnField[i][j].setBorder(BorderFactory.createLineBorder(Color.darkGray, 1, true));
    }
}

public void gameWon() {
    int dialogResult = JOptionPane.showConfirmDialog(null, "You Won! Do you want to start a new game?", "Congratulations!", JOptionPane.YES_NO_OPTION);
    if (dialogResult == JOptionPane.YES_OPTION) {
        bool_won = false;
        int_cellsShown = 0;
        resetGame();
    }
}

@Override
public void actionPerformed(ActionEvent e) {
    int_cellsShown = 0;
    int_dim++;
    resetGame();


     for (int i = 0; i < arr_btnField.length; i++) {
            for (int j = 0; j < arr_btnField[i].length; j++) {
                arr_btnField[i][j].setBackground(Color.red);
            }
        }
    }
}

第一次显示:
Display after the first time

第二次显示:
Display after the second time

2 个答案:

答案 0 :(得分:2)

  

我在方法的第四行调用.revalidate。

由于没有添加任何组件到面板,所以没有做任何事情。 revalidate()需要在添加组件后完成。

  

显示的面板不是jpanel,显示的面板是jpanel2,这就是为什么我将jpanel2指定给方法末尾的jpanel值。

您不仅可以更改参考,还希望将组件从一个面板移动到另一个面板。

需要将组件添加到添加到GUI的面板中。

编辑:

首先,Swing组件以“J”开头。不要在Swing应用程序中使用AWT组件(MenuBar,Menu,MenuItem)。

问题是你的LAF:

new MineSweeper();
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

使用当前的LAF创建组件。首次创建游戏时,默认LAF用于创建所有按钮(和其他组件)。此LAF允许您更改按钮的背景颜色。

然而,你改变了LAF。因此,当您重置游戏板时,现在使用System LAF创建按钮。这个LAF显然不允许你改变按钮的背景颜色。

这应该很容易测试。创建GUI:

//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

JButton button = new JButton("testing");
button.setBackground(Color.RED);

JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( button );
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );

首先测试上面的代码,看看按钮的背景是否发生变化。

然后取消注释LAF的变化并重新测试。

一种可能的解决方案,因此您不依赖于LAF是使用图标来表示按钮的背景颜色。然后,您可以将任何文本居中放置在图标上方。类似的东西:

import java.awt.*;
import javax.swing.*;

public class ColorIcon implements Icon
{
    private Color color;
    private int width;
    private int height;

    public ColorIcon(Color color, int width, int height)
    {
        this.color = color;
        this.width = width;
        this.height = height;
    }

    public int getIconWidth()
    {
        return width;
    }

    public int getIconHeight()
    {
        return height;
    }

    public void paintIcon(Component c, Graphics g, int x, int y)
    {
        g.setColor(color);
        g.fillRect(x, y, width, height);
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    public static void createAndShowGUI()
    {
        JPanel panel = new JPanel( new GridLayout(2, 2) );

        for (int i = 0; i < 4; i++)
        {
            Icon icon = new ColorIcon(Color.RED, 50, 50);
            JLabel label = new JLabel( icon );
            label.setText("" + i);
            label.setHorizontalTextPosition(JLabel.CENTER);
            label.setVerticalTextPosition(JLabel.CENTER);
            panel.add(label);
        }

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(panel);
        f.setSize(200, 200);
        f.setLocationRelativeTo( null );
        f.setVisible(true);
    }
}

答案 1 :(得分:1)

是的,我也注意到,问题出在这里:

public static void main(String[] args) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                new MineSweeper();
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception ex) {
            }
        }
    });
}

如果你注释掉UIManager行,你的代码就可以了。此行仅在创建GUI后有效,因此在创建新组件之前不会生效。请注意,我正在努力最小化您的代码以发现这一点,并且正在删除代码以查看导致问题的原因,直到剩下这一切。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.UIManager;

@SuppressWarnings("serial")
public class MineSweeper extends JFrame implements ActionListener {
    private static final Color BTN_COLOR = new Color(0X00, 0X94, 0XFF);
    int int_dim = 11;
    JButton[][] arr_btnField = new JButton[int_dim][int_dim];

    JMenuBar menu_bar;
    JMenu menu;
    JMenuItem optionNew;
    JPanel jpanel = new JPanel();

    public MineSweeper() {
        resetGame();
        this.getContentPane().add(jpanel);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(true);
        this.setTitle("Minesweeper");

        menu_bar = new JMenuBar();
        menu = new JMenu("File");
        menu.setMnemonic(KeyEvent.VK_F);

        optionNew = new JMenuItem("Win");
        optionNew.setMnemonic(KeyEvent.VK_W);
        optionNew.addActionListener(this);
        menu.add(optionNew);
        menu_bar.add(menu);
        this.setJMenuBar(menu_bar);
        this.setPreferredSize(new Dimension(500, 500));
        this.pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    public void resetGame() {
        jpanel.removeAll();
        arr_btnField = new JButton[int_dim][int_dim];
        jpanel.setLayout(new GridLayout(0, int_dim));
        for (int i = 0; i < arr_btnField.length; i++) {
            for (int j = 0; j < arr_btnField[i].length; j++) {
                arr_btnField[i][j] = new JButton();
                arr_btnField[i][j].setBackground(BTN_COLOR);
                jpanel.add(arr_btnField[i][j]);
            }
        }
        jpanel.revalidate();
        jpanel.repaint();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        resetGame();
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    new MineSweeper();
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }
            }
        });
    }

}