2016-11-26 2 views
0

のactionPerformed関数から呼び出されるメソッドの問題パック私のプログラムを複数回コンパイルし、実行している時にのみ、時には

、時々pack()作品やnewGamePanelの部品が圧縮され、そして時にはそれが動作しない、とnewGamePanelsetSize()で設定されたJFrameの値を埋めるように展開されます。どちらの結果も確実に再現することはできませんでした。本当にランダムなようです。

注:妥当な量のコードを確認するためにGUIの書式設定を減らしたので、GUIはかなりゴミ箱になっています。しかし、この問題はまだ識別が容易です。パックしようとしているJPanelCardLayoutで表示されている場合は、JFrameが「パックされた」サイズになることがあり、最初に設定したsetSize()の値と一致することがあります。 GUIを切り捨てたので、newGamePanelコンポーネントはコンテナを埋めるように移動しませんが、すべての制約値が削除されたからです。

疑惑やデザイン

私はActionListenerを実装するクラスTankEventからpack()を呼び出しています。ゲームは、TankEventコンストラクタのTankEventに渡されたTankApplicationオブジェクト(TankApplicationJFrame)がTankDisplay()となります。

JFrameインスタンスJPanelは、selfのインスタンスを渡します。 JPanelActionListenerをインスタンス化し、selfのインスタンスを渡します。 ActionListenerpack()を使用してJFrameを変更します。

以下は、ボタンを押したときに実行されるコードです。

CardLayout layOut = (CardLayout)(display.getLayout()); //display is an object of TankDisplay 
layOut.show(display, "newGamePanel"); 
game.pack(); //game is an object of TankApplication 
game.setResizable(false); 
break;  

私のデザインに問題があるのだろうか。 pack()JFrameを再描画するという巨大な前提があります(JFramesも再塗りつぶしですか?おそらく再検証/更新?)。しかし、私が完了したときにJFrameのサイズをリセットする限り、なぜそれが問題になるのかはわかりません。

(私はなぜdisplay.getLayout()をキャストする必要があるのか​​分かりませんCardLayout。これはdocs.oracleの推奨実装ですが、getLayout()は実際のLayoutManagerではなく、なぜLayoutManagerを返しますか?)

短縮関連するコード

タンク表示

package Tanks; 
import javax.swing.*; 
import java.awt.*; 
import java.awt.image.*; 
import java.io.*; 
import java.net.URL; 
import javax.imageio.*; 

public class TankDisplay extends JPanel{ 
    JCheckBox unlimitedAmmoCB, unlimitedTimeCB; 
    JTextField playerOneTF, playerTwoTF; 
    JPanel menuPanel, newGamePanel; 

    public TankDisplay(TankApplication g){ 
     TankEvent listener = new TankEvent(this, g); //passing an instance of self and previously received instance of TankApplication to TankEvent 
     setLayout(new CardLayout()); //Hihghest level of GUI after JFrame. CardLayout for overall display JPanel, need for switching functionality in TankEvent 

     menuPanel = new JPanel(new GridBagLayout()); //Second highest level of GUI. Will eventually display a picture instead of a black JPanel. Has button "New Game" and "Load Game" 

     JPanel mainMenuImageP = new JPanel(); 
     GridBagConstraints conMainMenuImageP = new GridBagConstraints(); 
     mainMenuImageP.setBackground(Color.BLACK); 
     conMainMenuImageP.fill = GridBagConstraints.BOTH; 
     conMainMenuImageP.gridy = 0; 
     conMainMenuImageP.gridx = 0; 
     menuPanel.add(mainMenuImageP, conMainMenuImageP); //adding menuPanel components 

     JButton newGameB = new JButton("New Game"); 
     GridBagConstraints conNewGameB = new GridBagConstraints(); 
     conNewGameB.fill = GridBagConstraints.NONE; 
     conNewGameB.gridy = 1; 
     conNewGameB.gridx = 0; 
     menuPanel.add(newGameB, conNewGameB); //adding menuPanel components 

     JButton loadGameB = new JButton("Load Game"); 
     GridBagConstraints conLoadGameB = new GridBagConstraints(); 
     conLoadGameB.fill = GridBagConstraints.NONE; 
     conLoadGameB.gridy = 1; 
     conLoadGameB.gridx = 1; 
     menuPanel.add(loadGameB, conLoadGameB); //adding menuPanel components 

     //action listners for mainPenu panel components 
     newGameB.addActionListener(listener); 

     add(menuPanel, "menuPanel"); //menuPanel is added to higher display JPanel 

     newGamePanel = new JPanel(new GridBagLayout());      //creating second higher level container. To achieve certain functionality, 
                      //this panel contains four other panels, that each contain their own 
     JPanel playerOneSetUp = new JPanel(new GridBagLayout());   //components. newGamePanel uses GridBagLayout, and so do the panels 
      GridBagConstraints conPlayerOneSetUp = new GridBagConstraints();//that it's managing. GridBayLayout managaing GridBagLayout 
      conPlayerOneSetUp.fill = GridBagConstraints.BOTH; 
      conPlayerOneSetUp.gridy = 0; 
      conPlayerOneSetUp.gridx = 0; 

     JLabel playerOneL = new JLabel("Player One Name"); 
      GridBagConstraints conPlayerOneL = new GridBagConstraints(); 
      conPlayerOneL.fill = GridBagConstraints.HORIZONTAL; 
      conPlayerOneL.gridy = 0; 
      conPlayerOneL.gridx = 0; 
      playerOneSetUp.add(playerOneL, conPlayerOneL); 

     playerOneTF = new JTextField(); 
      GridBagConstraints conPlayerOneTF = new GridBagConstraints(); 
      conPlayerOneTF.fill = GridBagConstraints.HORIZONTAL; 
      conPlayerOneTF.gridy = 1; 
      conPlayerOneTF.gridx = 0; 
      playerOneSetUp.add(playerOneTF, conPlayerOneTF); 

     JButton playerOneJColorChooser = new JButton("Player One Color"); 
      GridBagConstraints conPlayerOneJColorChooser = new GridBagConstraints(); 
      conPlayerOneJColorChooser.fill = GridBagConstraints.HORIZONTAL; 
      conPlayerOneJColorChooser.gridy = 2; 
      conPlayerOneJColorChooser.gridx = 0; 
      playerOneSetUp.add(playerOneJColorChooser, conPlayerOneJColorChooser); 

     newGamePanel.add(playerOneSetUp, conPlayerOneSetUp); //adding newGamePanel components 

     JPanel playerTwoSetUp = new JPanel(new GridBagLayout()); 
      GridBagConstraints conPlayerTwoSetUp = new GridBagConstraints(); 
      conPlayerTwoSetUp.fill = GridBagConstraints.BOTH; 
      conPlayerTwoSetUp.gridy = 1; 
      conPlayerTwoSetUp.gridx = 0; 

     JLabel playerTwoL = new JLabel("Player Two Name"); 
      GridBagConstraints conPlayerTwoL = new GridBagConstraints(); 
      conPlayerTwoL.fill = GridBagConstraints.HORIZONTAL; 
      conPlayerTwoL.gridy = 0; 
      conPlayerTwoL.gridx = 0; 
      playerTwoSetUp.add(playerTwoL, conPlayerTwoL); 

     playerTwoTF = new JTextField(); 
      GridBagConstraints conPlayerTwoTF = new GridBagConstraints(); 
      conPlayerTwoTF.fill = GridBagConstraints.HORIZONTAL; 
      conPlayerTwoTF.gridy = 1; 
      conPlayerTwoTF.gridx = 0; 
      playerTwoSetUp.add(playerTwoTF, conPlayerTwoTF); 

     JButton playerTwoJColorChooser = new JButton("Player Two Color"); 
      GridBagConstraints conPlayerTwoJColorChooser = new GridBagConstraints(); 
      conPlayerTwoJColorChooser.fill = GridBagConstraints.HORIZONTAL; 
      conPlayerTwoJColorChooser.gridy = 2; 
      conPlayerTwoJColorChooser.gridx = 0; 
      playerTwoSetUp.add(playerTwoJColorChooser, conPlayerTwoJColorChooser); 

     newGamePanel.add(playerTwoSetUp, conPlayerTwoSetUp); //adding newGamePanel components 

     JPanel options = new JPanel(new GridBagLayout()); 
      GridBagConstraints conOptions = new GridBagConstraints(); 
      conOptions.fill = GridBagConstraints.BOTH; 
      conOptions.gridy = 0; 
      conOptions.gridx = 1; 

     JLabel optionsL = new JLabel("Game Options"); 
      GridBagConstraints conOptionsL = new GridBagConstraints(); 
      conOptionsL.fill = GridBagConstraints.HORIZONTAL; 
      conOptionsL.gridy = 0; 
      conOptionsL.gridx = 0; 
      options.add(optionsL, conOptionsL); 

     unlimitedAmmoCB = new JCheckBox("Unlimited Ammunition"); 
      GridBagConstraints conUnlimitedAmmoCB = new GridBagConstraints(); 
      conUnlimitedAmmoCB.fill = GridBagConstraints.HORIZONTAL; 
      conUnlimitedAmmoCB.gridy = 1; 
      conUnlimitedAmmoCB.gridx = 0; 
      options.add(unlimitedAmmoCB, conUnlimitedAmmoCB); 

     unlimitedTimeCB = new JCheckBox("Unlimited Time");   
      GridBagConstraints conUnlimitedTimeCB = new GridBagConstraints(); 
      conUnlimitedTimeCB.fill = GridBagConstraints.HORIZONTAL; 
      conUnlimitedTimeCB.gridy = 2; 
      conUnlimitedTimeCB.gridx = 0; 
      options.add(unlimitedTimeCB, conUnlimitedTimeCB); 

     newGamePanel.add(options, conOptions); //adding newGamePanel components 

     JButton startGameB = new JButton("START"); 
      GridBagConstraints conStartGameB = new GridBagConstraints(); 
      conStartGameB.fill = GridBagConstraints.BOTH; 
      conStartGameB.gridy = 1; 
      conStartGameB.gridx = 1; 

     newGamePanel.add(startGameB, conStartGameB); //adding newGamePanel components 

     add(newGamePanel, "newGamePanel"); //newGamePanel is added to higher level display JPanel 

    } 
} 

戦車アプリケーション

package Tanks; 
import javax.swing.*; 
import java.awt.*; 
public class TankApplication extends JFrame{ 
    public static void main (String args[]){  
     TankApplication GUI = new TankApplication();    
    } 

    public TankApplication(){ 
     super("Tanks"); 
     add(new TankDisplay(this)); 
     setSize(800, 600); 
     setVisible(true); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setLocationRelativeTo(null); 
    } 
} 

戦車イベント

package Tanks; 
import java.awt.*; 
import java.awt.event.*; 

import javax.swing.JColorChooser; 
public class TankEvent implements ActionListener{ 

    TankApplication game; 
    TankDisplay display; 

    public TankEvent(TankDisplay d, TankApplication g){ //I found this was necesarry because I didn't want to call the constructors of panels 
     display = d;         //and frames. I'm not sure why that caused errors, but it does. And when I tried to 
     game = g;          //create overloaded constructors for TankApplication and TankDisplay, their references 
    }             //didn't have the information I needed. This is likely because I kept most of the components 
                 //as local variables in the constructors, instead of creating variables in their respective classes, and using 
    public void actionPerformed(ActionEvent e){   //the constructors to modify them 
     CardLayout layOut = (CardLayout)(display.getLayout()); //<---Why do I need to do this? 
     switch(e.getActionCommand()){ 
      case "New Game": 
       layOut.show(display, "newGamePanel"); 
       game.pack(); //<<<---Root problem. Sometimes newGamePanel is packed, the JFrame is smaller, sometimes newGameaPanel is not packed. Seems random 
       game.setResizable(false); //for this JPanel only, I don't want to be able to resize the window. I will change this when the user flips 
       break;     //to another JPanel  
     } 
    } 
} 

ロバートはsimilar questionと尋ねたようですが、満足のいく答えを得られなかったようです。なぜスレッドはこれと関連がありますか?

+0

* "関連コード:" *コードの問題は実際にはアプリの全く異なる部分にあることがよくあります。私たちが期待しているところよりも。もっと早く助けを求めるには、[MCVE]または[短く、自己完結型の正しい例](http://www.sscce.org/)を投稿してください。 –

+0

私はそれらの記事を読んでいますが、確認してみましょう。基本的には、私は問題を再現する必要がないので、コードからすべての超過をカットする必要があります。これは私が問題を切り離すのを助けるだけでなく、みんなに管理可能な量のコードを見せるでしょうか? – ulw1

+0

私は編集しました。私はそれがMCVだと確信しています。 – ulw1

答えて

1

CardLayoutは正しく使用されていません。

パネルでCardLayoutを使用する場合、パネルの適切なサイズは、CardLayoutに追加される最大の子パネルのサイズです。

1つのパネルから別のパネルにスワップしても、パネルの適切なサイズ、したがってフレームは変更されません。 pack()メソッドは効果がありません。

フレームを梱包する心配はありません。コンポーネントを中央に配置するように「メニューパネル」を作成するだけです。その後、ゲームを開始すると、そのすべての変更は、 "ゲームパネル"を表示することです。

+0

これは優れた解決策ですが、なぜpack()が動作するのか、時にはうまくいかないのかという疑問に答えることができません。私は今なぜそれがうまくいかないのか理解していますが、pack()が効果を持たないのは事実ではありません。 – ulw1

+0

@ ulw1、適切な 'MCVE 'を投稿していないと言ったように、あなたのコードをテストして、あなたが何をしているのかを理解しようとすることはできません。 – camickr

関連する問題