gpt4 book ai didi

java - 使用 Java 将 Image 设置为 Button 并在 Puzzle Game 中处理 ActionListener

转载 作者:行者123 更新时间:2023-12-01 08:50:12 26 4
gpt4 key购买 nike

我只学习了 Java Swing 1 周,所以我尝试完成一些练习。这是我的代码。我将 9 图标设置为 9 按钮,但它没有显示在按钮上。

package mypack;

import java.awt.Color;

import javax.swing.*;

public class PuzzleGame extends JFrame{
static JButton bt1,bt2,bt3,bt4,bt5,bt6,bt7,bt8,bt9,btNew,btExit;
static JLabel move, moveNum, time, timeNum;
public PuzzleGame(){
createMyGUI();
}

public static void createMyGUI(){
JFrame jf = new JFrame("Game Puzzle Java");
JPanel jpl = new JPanel();
Icon icSpace = new ImageIcon("images/0.png");
Icon ic1 = new ImageIcon("images/1.png");
Icon ic2 = new ImageIcon("images/2.png");
Icon ic3 = new ImageIcon("images/3.png");
Icon ic4 = new ImageIcon("images/4.png");
Icon ic5 = new ImageIcon("images/5.png");
Icon ic6 = new ImageIcon("images/6.png");
Icon ic7 = new ImageIcon("images/7.png");
Icon ic8 = new ImageIcon("images/8.png");
jpl.setSize(100,100);
jpl.setBounds(480, 50, 200, 200);
jpl.setBackground(Color.BLUE);
move = new JLabel("Move:");
move.setBounds(480,10,50,20);
moveNum = new JLabel("0");
moveNum.setBounds(530, 10, 50, 20);
time = new JLabel("Time:");
time.setBounds(580, 10, 50, 20);
timeNum = new JLabel("0");
timeNum.setBounds(630,10,50,20);
btNew = new JButton("New Game");
btNew.setBounds(480, 270, 200, 80);
btExit = new JButton("Exit");
btExit.setBounds(480, 370, 200, 80);
jf.add(move);
jf.add(moveNum);
jf.add(time);
jf.add(timeNum);
jf.add(btNew);
jf.add(btExit);
jf.add(jpl);
jf.setSize(700, 500);
jf.setLocation(300,20);
jf.setLayout(null);
jf.setResizable(false);
jf.setVisible(true);
bt1 = new JButton();
bt1.setBounds(10, 10, 150, 150);
bt1.setIcon(ic1);
bt2 = new JButton();
bt2.setBounds(160, 10, 150, 150);
bt2.setIcon(ic2);
bt3 = new JButton();
bt3.setBounds(310, 10, 150, 150);
bt3.setIcon(ic3);
bt4 = new JButton();
bt4.setBounds(10, 160, 150, 150);
bt4.setIcon(ic4);
bt5 = new JButton();
bt5.setBounds(160, 160, 150, 150);
bt5.setIcon(ic5);
bt6 = new JButton();
bt6.setBounds(310, 160, 150, 150);
bt6.setIcon(ic6);
bt7 = new JButton();
bt7.setBounds(10, 310, 150, 150);
bt7.setIcon(ic7);
bt8 = new JButton();
bt8.setBounds(160, 310, 150, 150);
bt8.setIcon(ic8);
bt9 = new JButton();
bt9.setBounds(310, 310, 150, 150);
bt9.setIcon(icSpace);
jf.add(bt1);
jf.add(bt2);
jf.add(bt3);
jf.add(bt4);
jf.add(bt5);
jf.add(bt6);
jf.add(bt7);
jf.add(bt8);
jf.add(bt9);
}

public static void main(String[] args){
PuzzleGame.createMyGUI();
}
}

我认为 setIcon 方法不适用于 Button。另外,有人告诉我如何用我的代码在益智游戏中设置一个 Action 将困惑的图片排列成完整的图片。

最佳答案

我在您的代码中发现了一些问题:

  1. 您正在扩展 JFrame 并在类中创建一个新的 JFrame 对象。您永远不会使用您的类(扩展类)的 JFrame。因此,明智的做法是删除它。

    您应该避免扩展JFrame,因为这意味着您的类JFrameJFrame是一个刚性的容器,而不是让您的程序基于 JPanel 并将它们添加到其他容器。引用:Using extends JFrame vs calling it inside of class .

  2. 您已经不再使用 static 关键字。 static不是跨方法传字,它会对你造成很大的伤害,不要再使用它了。相反,创建类的实例并以这种方式调用您的方法。

  3. 您有多个执行相同操作的对象:

    Icon ic1 = new ImageIcon("images/1.png");
    Icon ic2 = new ImageIcon("images/2.png");
    ...

    为什么不使用 Icon[] 图标并对其进行迭代?

  4. 您正在使用邪恶的 null 布局setBounds(...),停止使用它,而使用 layout managers以及EmptyBorder s 用于组件之间的额外间距。

    虽然像素完美定位可能是 Swing 新手创建复杂 GUI 的最简单方法,但您使用它的次数越多,您会发现与此相关的问题就越多。 Swing 必须处理不同的平台、屏幕尺寸、分辨率、PLAF 等。这就是为什么像素完美的 GUI 只是一种幻想。引用见Null layout is evil以及 this question 中的答案进一步解释为什么应该避免空布局

  5. 在添加所有组件之前,您要使 JFrame 可见,这可能会导致 GUI 在显示之前无法完全绘制,并可能导致出现“错误”组件只有在将鼠标悬停在其应在的位置时才会显示。 JFrame#setVisible(...)应该是最后调用的行之一。

  6. 您正在调用JFrame#setSize(...) ,您应该覆盖 getPreferredSize您的内部 JPanel ,然后调用 JFrame#pack() ,因此您的 JFrame 将其尺寸减小到所有组件都以其首选尺寸可见的最小尺寸。请参阅Should I avoid the use of setPreferred|Maximum|MinimumSize in Java Swing? (普遍共识是"is")。

  7. 您没有将程序放在 Event Dispatch Thread (EDT) 上,Swing 不是线程安全的,这可能会使您的程序有时卡住,您可以通过更改 main(...) 方法来解决此问题,如下所示:

    public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    //Your constructor here
    }
    });
    }
<小时/>

您的图像可能没有被定位,但是一旦您将程序打包为 JAR 文件,它们就会成为嵌入式资源,因此,明智的做法是开始将文件(或图像)视为已经存在的文件(或图像)。

您可以更改例如:

Icon ic1 = new ImageIcon("images/1.png");

对此:

Icon ic1 = null;
try {
ic1 = new ImageIcon(ImageIO.read(Thread.currentThread().getContextClassLoader().getResourceAsStream("images/1.png")));
} catch (IOException e) {
e.printStackTrace();
}

这将使您的图像被加载。看这个question以及接受的答案供引用。

这应该可以解决您的问题,并且您的 GUI(我用 2 个图标完成)应该如下所示:

enter image description here

但是如果您想遵循我的上述建议,您可以尝试此代码,它使用布局管理器、空边框、覆盖 getPreferredSize() 方法并使用 pack()等,并生成一个与您已有的非常相似的 GUI:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ImagesInResourcesExample {

private JFrame frame;

private JPanel buttonsPane;
private JPanel rightPane;
private JPanel scorePanel;
private JPanel colorPanel;

private BufferedImage img;

private JButton[][] buttons;

private JLabel moveLabel;
private JLabel timeLabel;

private JButton newGameButton;
private JButton exitButton;

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

@SuppressWarnings("serial")
public void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
buttons = new JButton[3][3];
moveLabel = new JLabel("Move: 0");
timeLabel = new JLabel("Time: 0");
colorPanel = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
};
colorPanel.setBackground(Color.BLUE);
colorPanel.setOpaque(true);

newGameButton = new JButton("New Game");
exitButton = new JButton("Exit");

try {
img = ImageIO.read(Thread.currentThread().getContextClassLoader().getResourceAsStream("images/arrow.png"));
} catch (IOException e) {
e.printStackTrace();
}

buttonsPane = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
};
buttonsPane.setLayout(new GridLayout(3, 3));
buttonsPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

for (int i = 0; i < buttons.length; i++) {
for (int j = 0; j < buttons.length; j++) {
buttons[i][j] = new JButton(new ImageIcon(img));
buttonsPane.add(buttons[i][j]);
}
}

rightPane = new JPanel();
rightPane.setLayout(new GridBagLayout());

scorePanel = new JPanel();
scorePanel.setLayout(new GridLayout(1, 2, 10, 10));

scorePanel.add(moveLabel);
scorePanel.add(timeLabel);

GridBagConstraints gbc = new GridBagConstraints();

gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(10, 10, 10, 10);

rightPane.add(scorePanel, gbc);

gbc.gridx = 0;
gbc.gridy = 1;

rightPane.add(colorPanel, gbc);

gbc.gridy = 2;
gbc.ipadx = 30;
gbc.ipady = 80;

rightPane.add(newGameButton, gbc);

gbc.gridy = 3;

rightPane.add(exitButton, gbc);

rightPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

frame.add(buttonsPane, BorderLayout.CENTER);
frame.add(rightPane, BorderLayout.EAST);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

enter image description here

正如你所看到的,代码最多比你已有的代码长 20 行,但是如果你继续向两个程序添加元素,我所做的代码将来会比你的代码短。最终将使用空布局

我希望您遵循上述建议并以这个例子为例并尝试理解它并改进它。

关于java - 使用 Java 将 Image 设置为 Button 并在 Puzzle Game 中处理 ActionListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42443759/

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