2016-06-01 4 views
-3

まず、絶対ポジショニングはGUIには理想的ではないことを知っています...しかし、4種類のウィンドウと1つのゲームウィンドウ、すべてがランナーを内蔵しています。私はこれを行うには1日半を持っていました。学生のスケジュール(特に、GUIの作成やJOptionPaneの禁止についての事前の経験がないもの)で、私は速くて面倒でした。それでここに問題があります。アブソリュートポジショニングを使用したRamshackle GUIは画像をランダムに回転させます。

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; 
    } 
    } 
} 
+0

の線に沿って何か '' "私は...私のコードを投稿することが有用であるとは思わない" - 真剣に?そして、あなたのプログラムがどうしておかしなことをしているのかを推測する必要があります。 [mcve]を参照してください。 –

+0

そして、あなたは間違っていることは間違いありません。あなたはそれが悪いことを知っているので、それを修正してみませんか?はい、JFrameに直接描画しないでください。そうしないでください。 –

+0

まあ、評判を失う良い方法を見つけました...主な理由は、これは私がいくつかのファイル、約9の他のクラス、そしてその200行をそのまま呼び出しているからです。すぐに投稿します。私は悪いプログラミングが続いていると認識していますが、プロジェクトはこのエラーのほかに働いています。私はクラス内の他の14人の学生がこのコードを処理しています。バグ修正など、この時点での変更はごくわずかです。 –

答えて

1

あなたがここのJFrameのpaintメソッドをオーバーライドしている:

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

そして、それの内側にいくつかの悪いことやって:あなたはAでペイントをしてはならない

  • をJFrameは、子コンポーネント、枠線、glasspane、contentPaneなどのアプリケーション全体のペインティングを危険にさらす危険性があるため、
  • 恐らくスーパーペイントメソッドを呼び出すことはありません。おそらくあなたの最大のバグ
  • 実際にこのメソッド内からファイルを読み込み、クロールを遅らせます。塗装からファイルI/Oをしないでください。
  • catch (IOException e) {}で例外を無視しています。これは非常に危険な習慣で、目を閉じて運転することに相当します。

提案:はトップレベルウィンドウ内描画しない:

  • まず第一には、チュートリアルは、私たちがここに来る無数の人々に語っているもの、あなたを教えて何をすべきか。 JPanelのpaintComponentメソッド内に描画します。
  • スーパーペイントメソッドを呼び出します。
  • イメージを一度に読み込み、コンストラクタでイメージを変数に格納し、ペイント方法でイメージを読み込んだり、ファイルI/Oを実行したりしないでください。
  • 少なくとも、例外のスタックトレースをキャッチブロック内に表示します。

その他の問題:

  • あなたのコードは、あなたがより多くの「イベント駆動型」するプログラムを変更することを示唆しているwhileループ内のポーリングをたくさんやっています。
  • あなたのコードは、他のクラスの状態をポーリングする以外には何もしないように見えます。これらの結果に基づいて、表示される画像が変更されます。そうであれば、はるかに良いでしょう:
    • ポーリングを取り除き、オブザーバーパターンを使用して、イメージを表示するクラスをイメージ表示クラスに通知します。これは、PropertyChangeListenerまたは単純なChangeListenerを使用して行うことができます。
    • もう一度、プログラムの起動時にすべての画像を読み込み、変数に格納します。イメージのArrayList、またはおそらくより良い、ArrayList<Icon>これのためにうまくいくでしょう。
    • イメージをImageIconとして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)); 
     } 
    } 
} 
+0

しかし、これらのいずれかが、上記のバグの原因になりますか?私はそれが悪い習慣であることを知っているが、私が以前に言ったように、それはその問題を除いて働く。私はPaintメソッドの内部でファイルを読むことについては心配していません。なぜなら、実際にはほとんど実行されないからです。新しい部屋に移動するときのみ。スーパーペイントメソッドは私が気づいていなかったバグです.JFrameにコンポーネントを追加することは決してないので、JFrameのペイントはうまくいきます。後でプログラムした別のクラスダイアログを使ってすべてをポップアップで処理しています良い。 –

+0

@ R.Thom:掲示なしに私たちが実行することができ、リンクではないことを知る方法はありません。 –

+0

問題の原因はわかりませんが、それが現在の問題です。私がそれを引き起こしているものを特定できれば、私はそれを修正するだろう。私が使用しているすべての画像のコピーをあなたに与えて、ゲームのすべてのコード行を削除してから、あなたのための方法を書いていれば、私は最小限で完全で検証可能な例を作成することができます。画像から画像への移行。それが問題だけを再現しないかもしれない何かのための仕事の時間である以上にあなたが質問に答える必要があるすべてが私が原因について私は全く考えていないならば。 –

関連する問題