Ramshackle GUI,使用绝对定位随机翻转图像

时间:2016-06-01 18:05:22

标签: java image swing user-interface position

所以,首先我知道绝对定位对于GUI来说并不理想...但是,我必须构建4种不同类型的窗口,以及1个整体游戏窗口,所有这些都有内置的跑步者。我有一天半的时间来做这个,并且根据学生的日程安排(特别是没有经验编写GUI和禁止JOptionPane的人),我做得快而且凌乱。这就是问题所在。

运行GUI时,一切都按计划进行。但是,大约1/4次在游戏中运行一个随机图像,将颠倒翻转。它并不总是相同的图像,并且不会每次都出现。我有图像出现,但直接在JFrame上绘画(没有面板,是的,我知道它编程错误)。感谢您提供的任何输入,无法在网上找到这样的任何内容。我发现最好的建议是当相同的图像总是颠倒时,但事实并非如此。 代码:

import javax.swing.JFrame;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;


public class game extends JFrame implements Runnable {

  private boolean running = false;
  private Image dbImage = null;
  private Dimension screenSize;
  private int width;
  private int height;
  private int screenIndex = 0;
  private BufferedImage img = null;
  private dialog d = new dialog();
  private boolean a = false;
  private Room1 room1 = new Room1();
  private Room2 room2 = new Room2();
  private Room3 room3 = new Room3();
  private Room4 room4 = new Room4();
  private Room5 room5 = new Room5();
  private Room6 room6 = new Room6();
  private Toilet toilet = new Toilet();
  private final boolean UNLOCK = true;

  public game()
  {
    super("Game");
    setExtendedState(JFrame.MAXIMIZED_BOTH);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();
    setVisible(true);
    setIconImage(new ImageIcon("pencil-icon.png").getImage());
    screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    width = (int)screenSize.getWidth();
    height = (int)screenSize.getHeight();

    (new Thread(this)).start();
  }

  public void update(Graphics g) {
    paint(g);
  }

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

  public static void main(String[] args) {
    new game();
  }

  public void run() {
    running = true;

    while(running) {
      repaint();
      process();

      try {
        Thread.sleep(20);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

  public int isScreenIndex() {
    return screenIndex;
  }
//SI 1 and 2 are working
  public void setScreenIndex(int s) {
    this.screenIndex = s;
  }
  public void process() {
    if (screenIndex==0)
    {
      try{
        Thread.sleep(2000);
      }
      catch (Exception e){}
      int a = -1;
      a = d.map();
      while (a==-1){
        try {
        Thread.sleep(200);
        }
        catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      if (a==1 && ((room5.isDone() && !room1.isDone()) || UNLOCK)){
        setScreenIndex(1);
        return;
      }
      if (a==2 && (!room2.isDone() || UNLOCK)){
        setScreenIndex(2);
        return;
      }
      if (a==3 && (!room3.isDone() || UNLOCK)){
        setScreenIndex(3);
        return;
      }
      if (a == 4 && ((!room4.isDone() && room3.isDone())||UNLOCK)){
        setScreenIndex(4);
        return;
      }
      if (a == 5 && ((room4.isDone() && room6.isDone() && !room5.isDone())||UNLOCK)){
        setScreenIndex(5);
        return;
      }
      if (a == 6 && ((room2.isDone() && !room6.isDone())||UNLOCK)){
        setScreenIndex(6);
        return;
      }
      if (a == 7){
        d.showString("Progress",room1.getRoomName()  + "\t\t" + room1.getScore() + "\n" +
                     room2.getRoomName()  + "\t\t" + room2.getScore() + "\n" +
                     room3.getRoomName()  + "\t\t" + room3.getScore() + "\n" +
                     room4.getRoomName()  + "\t\t" + room4.getScore() + "\n" +
                     room5.getRoomName()  + "\t\t" + room5.getScore() + "\n" +
                     room6.getRoomName()  + "\t\t" + room6.getScore());
      }
      if (a == 8 && (!toilet.isDone() || UNLOCK)){
        setScreenIndex(7);
        return;
      }
    }
    if (screenIndex == 1){
      room1.play();
      setScreenIndex(0);
      return;
    }
    if (screenIndex == 2){
      room2.play();
      setScreenIndex(0);
      return;
    }
    if (screenIndex==3){
      //boolean a = false;
      room3.play();
      //while(!a){
      //  try {
      //    Thread.sleep(200);
      //  } catch(InterruptedException e) {
      //  }
      //}
      setScreenIndex(0);
      return;
    }
    if (screenIndex==4){
      room4.play();
      setScreenIndex(0);
      return;
    }
    if (screenIndex == 5){
      room5.play();
      setScreenIndex(0);
      return;
    }
    if (screenIndex == 6){
      room6.play();
      setScreenIndex(0);
      return;
    }
    if (screenIndex == 7){
      toilet.play();
      setScreenIndex(0);
      return;
    }
  }
}

1 个答案:

答案 0 :(得分:1)

你在这里覆盖了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等......
  • 你永远不会称超级油漆方法 - 可能是你最大的错误
  • 您实际上正在从此方法中读取文件,将其放慢速度。永远不要从绘画中提取文件I / O.
  • 你忽略catch (IOException e) {}的例外情况,这是一种非常危险的做法,而且编码相当于闭着眼睛开车。

建议:

  • 首先要做的是教程告诉你的内容,我们告诉无数的人来到这里:不在顶级窗口中绘制。在JPanel的paintComponent方法中绘制。
  • 请调用超级绘画方法。
  • 一次读取图像,比如说在构造函数中,将图像存储到变量中,从不读取它们或者在绘制方法中执行文件i / o。
  • 至少在catch块中打印异常的堆栈跟踪。

其他问题:

  • 您的代码在while循环中进行了大量的轮询,表明您希望将程序更改为更多"事件驱动"。
  • 您的代码看起来什么都不做,只是轮询其他类的状态,并根据这些结果更改显示的图像。如果是这样,那就更好了:
    • 摆脱轮询,而是使用观察者模式通知图像显示类更改其图像。这可以使用PropertyChangeListener或简单的ChangeListener来完成。
    • 在程序启动时再次读取所有图像,并将它们存储到变量中。 Image的ArrayList或者更好,ArrayList<Icon>可以很好地适用于此。
    • 在JLabel
    • 中将图像显示为ImageIcons
    • 当状态发生变化时,只需使用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));
        }
    }
}