Java 摇摇欲坠的GUI,使用绝对定位随机地将图像翻转过来
所以,首先我知道绝对定位对于GUI来说并不理想。。。然而,我必须构建4种不同类型的窗口,以及1个完整的游戏窗口,所有这些都带有内置的runner。我有一天半的时间来做这件事,按照学生们的日程安排(尤其是一个没有编写GUI的经验和禁止使用JOptionPane的学生),我做得又快又乱。这就是问题所在 运行GUI时,一切都按计划进行。然而,在游戏中运行大约1/4次时,一个随机图像会被翻转过来。它并不总是相同的图像,也不是每次都出现。我让图像出现,但直接在JFrame上绘制(没有面板,是的,我知道它的编程很糟糕)。谢谢你提供的任何信息,我在网上找不到这样的信息。我发现最好的建议是当同一个图像总是颠倒的时候,但事实并非如此。 代码:Java 摇摇欲坠的GUI,使用绝对定位随机地将图像翻转过来,java,image,swing,user-interface,position,Java,Image,Swing,User Interface,Position,所以,首先我知道绝对定位对于GUI来说并不理想。。。然而,我必须构建4种不同类型的窗口,以及1个完整的游戏窗口,所有这些都带有内置的runner。我有一天半的时间来做这件事,按照学生们的日程安排(尤其是一个没有编写GUI的经验和禁止使用JOptionPane的学生),我做得又快又乱。这就是问题所在 运行GUI时,一切都按计划进行。然而,在游戏中运行大约1/4次时,一个随机图像会被翻转过来。它并不总是相同的图像,也不是每次都出现。我让图像出现,但直接在JFrame上绘制(没有面板,是的,我知道它的
您正在覆盖JFrame的绘制方法:
public void paint(Graphics g) {
switch (screenIndex) {
case 0:
img = null;
try {
img = ImageIO.read(new File("map.png"));
} catch (IOException e) {
}
break;
case 1:
img = null;
try {
img = ImageIO.read(new File("IMG_6009.JPG"));
} catch (IOException e) {
}
break;
case 2:
img = null;
try{
img = ImageIO.read(new File("IMG_6010.JPG"));
}
catch (IOException e) {}
break;
case 3:
img = null;
try {
img = ImageIO.read(new File("IMG_6011.jpg"));
} catch (IOException e) {
}
break;
case 4:
img = null;
try {
img = ImageIO.read(new File("IMG_6013.jpg"));
} catch (IOException e) {
}
break;
case 5:
img = null;
try {
img = ImageIO.read(new File("IMG_5994.jpg"));
} catch (IOException e) {
}
break;
case 6:
img = null;
try {
img = ImageIO.read(new File("IMG_5992.jpg"));
} catch (IOException e) {
}
break;
case 7:
img = null;
try {
img = ImageIO.read(new File("IMG_5991.jpg"));
} catch (IOException e) {
}
break;
}
g.drawImage(img, 0, 0, width, height, null);
}
在里面做了一些坏事:
- 您不应该在JFrame中绘制,因为您可能会弄乱整个应用程序的绘制,包括子组件、边框、glasspane、contentPane等
- 你从来没有调用过super paint方法——这可能是你最大的错误
- 实际上,您正在从该方法中读取一个文件,将其速度减慢到爬行速度。切勿从绘图中执行文件I/O李>
- 您忽略了
的异常,这是一种非常危险的做法,编码相当于闭着眼睛驾驶catch(IOException e){}
- 首先,也最重要的是按照教程中告诉你的,我们已经告诉无数来到这里的人:不要在顶级窗口中绘制。在JPanel的paintComponent方法中绘制
- 一定要称之为超级绘画方法李>
- 在一次中读取图像,比如在构造函数中,将图像存储到变量中,并且永远不要在绘制方法中读取图像或执行文件i/o
- 至少在catch块中打印异常的stacktrace
- 您的代码在while循环中进行了大量轮询,这表明您希望将程序更改为更“事件驱动”
- 您的代码看起来除了轮询其他类的状态之外什么也不做,并根据这些结果更改显示的图像。如果是这样,那么更好的办法是:
- 摆脱轮询,而是使用观察者模式通知图像显示类更改其图像。这可以使用PropertyChangeListener或简单的ChangeListener来完成
- 在程序启动时再次读取所有图像,并将其存储到变量中。图像的ArrayList或者更好的,
可以很好地实现这一点ArrayList
- 在JLabel中将图像显示为图像图标
- 当状态发生变化时,只需使用JLabel的
方法交换图像。这将使您的程序更加简单和防弹setIcon(…)
import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
// this is a JPanel and can be displayed in a JFrame
// a JDialog, or in another JPanel
public class GamePanel extends JPanel {
public static final String[] IMG_PATHS = {
"map.png",
"IMG_6009.JPG",
"IMG_6010.JPG",
"IMG_6011.JPG",
"IMG_6013.JPG",
"IMG_5994.JPG",
"IMG_5992.JPG",
"IMG_5991.JPG"
};
private JLabel imageLabel = new JLabel();
private List<Icon> icons = new ArrayList<>();
private int iconIndex = 0;
public GamePanel() {
try {
// read in the images once and only
// once
for (String imagePath : IMG_PATHS) {
// actually better to use resources
// instead of Files here
File file = new File(imagePath);
BufferedImage img = ImageIO.read(file);
Icon icon = new ImageIcon(img);
icons.add(icon);
}
} catch (IOException e) {
// never ignore the exceptions
e.printStackTrace();
}
imageLabel.setIcon(icons.get(iconIndex));
setLayout(new BorderLayout());
add(imageLabel, BorderLayout.CENTER);
}
// let outside classes easily change what image is displayed
public void viewImage(int iconIndex) {
if (iconIndex < 0 || iconIndex >= icons.size()) {
throw new IllegalArgumentException("iconIndex: " + iconIndex);
} else {
this.iconIndex = iconIndex;
imageLabel.setIcon(icons.get(iconIndex));
}
}
}
导入java.awt.BorderLayout;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入java.util.ArrayList;
导入java.util.List;
导入javax.imageio.imageio;
导入javax.swing.Icon;
导入javax.swing.ImageIcon;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
//这是一个JPanel,可以在JFrame中显示
//JDialog或另一个JPanel
公共类游戏面板扩展了JPanel{
公共静态最终字符串[]IMG\u路径={
“map.png”,
“IMG_6009.JPG”,
“IMG_6010.JPG”,
“IMG_6011.JPG”,
“IMG_6013.JPG”,
“IMG_5994.JPG”,
“IMG_5992.JPG”,
“img5991.JPG”
};
私有JLabel imageLabel=新的JLabel();
私有列表图标=新的ArrayList();
私有整数指数=0;
公共游戏小组(){
试一试{
//只阅读一次图片
//一次
对于(字符串imagePath:IMG_路径){
//实际上更好地利用资源
//而不是这里的文件
文件文件=新文件(imagePath);
BuffereImage img=ImageIO.read(文件);
图标图标=新图像图标(img);
图标。添加(图标);
}
}捕获(IOE异常){
//永远不要忽视例外情况
e、 printStackTrace();
}
imageLabel.setIcon(icons.get(iconIndex));
setLayout(新的BorderLayout());
添加(imageLabel、BorderLayout.CENTER);
}
//让外部类轻松更改显示的图像
公共无效视图图像(int图标索引){
如果(iconIndex<0 | | iconIndex>=icons.size()){
抛出新的IllegalArgumentException(“iconIndex:+iconIndex”);
}否则{
this.iconIndex=iconIndex;
imageLabel.setIcon(icons.get(iconIndex));
}
}
}
“我认为发布我的代码没有用……”
——真的吗?我们应该猜猜你的程序为什么会有奇怪的异常行为如何?请向上看。你有很多公认的糟糕的编程正在进行。既然你知道它不好,为什么不修呢?是的,你不应该直接在JFrame上画画,所以不要这样做。好吧,我找到了一个好方法来失去声誉。。。我这么说的主要原因是因为我调用了几个文件,大约9个其他类,以及它的200行。我会马上把它寄出去。我知道我的编程很糟糕,但是除了这个错误,这个项目还在进行中,我班上还有14个学生在使用这个代码。在这一点上,它的任何更改都只能是很小的,比如一个bug修复。在发布之前,请再次阅读链接。在尝试隔离问题之前,您发布问题的时间太早了
import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
// this is a JPanel and can be displayed in a JFrame
// a JDialog, or in another JPanel
public class GamePanel extends JPanel {
public static final String[] IMG_PATHS = {
"map.png",
"IMG_6009.JPG",
"IMG_6010.JPG",
"IMG_6011.JPG",
"IMG_6013.JPG",
"IMG_5994.JPG",
"IMG_5992.JPG",
"IMG_5991.JPG"
};
private JLabel imageLabel = new JLabel();
private List<Icon> icons = new ArrayList<>();
private int iconIndex = 0;
public GamePanel() {
try {
// read in the images once and only
// once
for (String imagePath : IMG_PATHS) {
// actually better to use resources
// instead of Files here
File file = new File(imagePath);
BufferedImage img = ImageIO.read(file);
Icon icon = new ImageIcon(img);
icons.add(icon);
}
} catch (IOException e) {
// never ignore the exceptions
e.printStackTrace();
}
imageLabel.setIcon(icons.get(iconIndex));
setLayout(new BorderLayout());
add(imageLabel, BorderLayout.CENTER);
}
// let outside classes easily change what image is displayed
public void viewImage(int iconIndex) {
if (iconIndex < 0 || iconIndex >= icons.size()) {
throw new IllegalArgumentException("iconIndex: " + iconIndex);
} else {
this.iconIndex = iconIndex;
imageLabel.setIcon(icons.get(iconIndex));
}
}
}