我是JFrames的新手。所以我真的不知道如何在JFrame中绘制/绘制/显示所有内容。我正在做一个记忆游戏。目前我正在以第一种形式工作,这个表格必须显示背景图像,欢迎文本,带有记忆游戏卡数量的下拉列表以及应该开始游戏的按钮。我成功地显示了背景图像和欢迎文本。添加JButton和combobox后,我的表格搞砸了(我只看到蓝色背景)。我不知道我做错了什么,我也不知道如何将按钮和下拉按钮放在正确的x和y位置。我想将下拉框放在欢迎文本下方,按钮放在下拉框右侧。
这是我的代码:
主:
package Memory;
public class Main {
public static Memory memory;
public static void main(String[] args) {
memory = new Memory();
}
}
渲染器:
package Memory;
import javax.swing.*;
import java.awt.*;
public class Renderer extends JPanel {
private static final long serialVersionUID = 1L;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Memory.backImage = new ImageIcon("Memory/memoryGame.jpg");
Main.memory.repaint(g);
}
}
内存:
package Memory;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.*;
import javax.imageio.*;
import java.awt.FlowLayout;
public class Memory implements ActionListener {
public String[] amountOfCards = {"8","16","32"};
private JButton startButton;
public Renderer renderer;
public static ImageIcon backImage;
public boolean screen1;
public static final int WORLD_WIDTH=1250, WORLD_HEIGHT=800;
public Memory() {
JComboBox comboBox = new JComboBox(amountOfCards);
comboBox.setSelectedIndex(1);
startButton = new JButton("Start game");
JFrame jframe = new JFrame();
Timer timer = new Timer(20,this);
renderer = new Renderer();
jframe.add(renderer);
jframe.setTitle("Memory game");
jframe.setSize(WORLD_WIDTH,WORLD_HEIGHT);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setResizable(false);jframe.add(startButton);
jframe.add(comboBox);
jframe.setVisible(true);
screen1=true;
timer.start();
}
@Override
public void actionPerformed(ActionEvent e) {
renderer.repaint();
}
public void repaint(Graphics g) {
//welcome screen
if(screen1) {
BufferedImage scaledImage = getScaledImage();
g.drawImage(scaledImage, 0, 0, null);
g.setColor(new Color(150, 196, 100));
g.setFont(new Font("TimesRoman", Font.PLAIN, 75));
g.drawString("MEMORY GAME", WORLD_WIDTH / 2 - 275, 100);
g.setFont(new Font("TimesRoman", Font.PLAIN, 25));
g.drawString("Please select the amount of cards u want to play with and start the game!", WORLD_WIDTH / 2 -400, 200);
}
}
public BufferedImage getScaledImage() {
BufferedImage image = new BufferedImage(WORLD_WIDTH,WORLD_HEIGHT, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) image.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(backImage.getImage(), 0, 0,WORLD_WIDTH,WORLD_HEIGHT, null);
return image;
}
}
答案 0 :(得分:2)
好吧,代码的第一个视图中存在多个错误
public static Memory memory;
:拥有static
并且成为public
成员的那一行会伤害你很多!为什么?因为您创建的所有实例的memory
变量都相同,因为它是"类变量"不是"实例变量",而public
是违反惯例和安全原因的。有关参考,请参阅:What does the 'static' keyword do in a class?和Why use getters and setters?
从上述观点来看,static
不是"魔术十字方法/类"允许您通过类或主要方法和其他方法使用变量的单词...因此,这一行public static ImageIcon backImage;
和这一行:Memory.backImage = new ImageIcon("Memory/memoryGame.jpg");
不应该存在。对于这一个也是如此:Main.memory.repaint(g);
话虽如此,你应该永远不要永远!!! 覆盖repaint()
方法,所有代码都应该进入paintComponent(...)
mehtod!< / p>
将图像视为嵌入资源也是明智之举,因为一旦您将程序导出为JAR文件,它们就会成为嵌入式资源,最好像对待它们一样对待它们, here您可以找到有关如何相应更改计划的信息。
答案 1 :(得分:1)
尝试将ImageIcon BackImage从public static设置为public。另外,尝试在timer.start()
之后编写 jframe.setVisible(true); 命令注意在完成每次初始化之前将JFrame设置为可见,可能会导致程序出现意外行为。
要在屏幕上设置按钮的位置,将JButton添加到JFrame后,您可以使用:startButton.setLocation(x,y);
在您使用窗口坐标稍微玩一下后,您将获得JButton所需的位置。请记住,(0,0)通常是JFrame的左上角。
在程序中使用静态变量时要小心。似乎没有理由将Memory类,宽度和高度变量设置为静态。
有关此问题的详情,请查看此信息:Why are static variables considered evil?