gpt4 book ai didi

java - 重置按钮阵列后无法更改 java 按钮颜色

转载 作者:行者123 更新时间:2023-11-30 07:49:06 26 4
gpt4 key购买 nike

我正在创建一个程序,我必须不时地在其中重置按钮数组并将其显示在 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

最佳答案

I invoke .revalidate in the fourth line of the method.

这没有做任何事情,因为面板上没有添加任何组件。 revalidate() 需要在添加组件后完成。

The displayed panel is not jpanel, the displayed panel is jpanel2, thats why I assign jpanel2 to the value of jpanel in the end of the method.

您不能只更改引用并期望组件从一个面板移动到另一个面板。

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

编辑:

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

问题是您的 LAF:

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

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

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

这应该很容易测试。创建图形用户界面:

//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);
}
}

关于java - 重置按钮阵列后无法更改 java 按钮颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48713609/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com