0

学校の最終プロジェクトをやっていますが、私のコードは本当に奇妙なことをしています。クラス内で関数を呼び出すと、jpanelが表示されますが、別のクラスからこの関数を呼び出すと、表示されません。

解決策を見つけました。

メソッドrepaint();を呼び出す 2jpanelsを作成した後。それを解決します。

今...この質問を閉じる、または解決済みとしてマークするにはどうすればよいですか?これを読んだすべての人にたくさんのthx。

これがクラスです。

メインクラス

  public class Main {
  public static void main(String[] args) {
  new GameFrame();}
  }

GameFrameクラス

  public class GameFrame extends JFrame {
  private static final long serialVersionUID = 1L;
  private static final int baseWidth=192,baseHeight=352;
  private JPanel panel;
  private GamePanel gamePanel;

  public GameFrame() {
    panel = (JPanel) this.getContentPane();
    Dimension d = new Dimension(baseWidth, baseHeight);
    panel.setPreferredSize(new Dimension(d));
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.pack();
    this.setTitle("test game..");
    this.setResizable(false);
    this.setLocationRelativeTo(null);
    this.setVisible(true);
    init_panelGame();//this will content the real game panel.
}

private void init_panelGame() {
    gamePanel = new GamePanel(this,scale);
    gamePanel.setVisible(true);
    panel.add(gamePanel);
    this.revalidate();}
     }

GamePanelクラス

    public class GamePanel extends JPanel {
private static final long serialVersionUID = 1L;
private int imgSize = 32;
    public String gameState ="create_row";
private ImagePanel[][] mat_pos = new ImagePanel[6][11];
private Timer tiempo;//changed to a swing timer..

public GamePanel(GameFrame gp,int scale) {
this.setLayout(null);
createRow();//works fine if i call this method from here.
tiempo=new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
    gameFlow();
}});
timerStart();
}

public void gameFlow() {//this is the method call by my timer
if (gameState.equals("create_row"))
    {createRow(); //it doesnt render the created row!! this is my problem!!
     gameState = "move_squares";
 return;}
if (gameState.equals("move_squares"))
    {moveSquares();return;}
}

private void moveSquares() {
int runningSquares = 0;
for (int col=0;col<6;col++)
for(int ren=10;ren>=0;ren--)
    {if (mat_pos[col][ren]!=null)
     if (mat_pos[col][ren].state.equals("running"))
     {runningSquares++;
      mat_pos[col][ren+1]=mat_pos[col][ren];
      mat_pos[col][ren]=null;
      if (ren+1==10 || mat_pos[col][ren+2]!=null)
         mat_pos[col][ren+1].state = "stopped";
      int newX,newY;
      newX = imgSize * col;
      newY = imgSize * (ren+1);
      mat_pos[col][ren+1].setBounds(newX,newY, imgSize,imgSize);
     }
}
if (runningSquares==0)
   {gameState="create_row";
   createRow();}
}
public void createRow() {//create 2 panels and add them to this jpanel.
gameState = "move_squares";
int colorRandom1 = (int) (Math.random()*5);
int colorRandom2 = (int) (Math.random()*5);
ImagePanel t1 = new ImagePanel(colorRandom1);
ImagePanel t2 = new ImagePanel(colorRandom2);
int columna = (int) (Math.random()*5);
mat_pos[columna][0] = t1;
mat_pos[columna+1][0] = t2;
t1.setBounds(columna*imgSize,0,32, 32);
t2.setBounds((columna+1)*imgSize,0,32, 32);
this.add(t1);
this.add(t2);
this.revalidate();
}
public void timerStart(){
    tiempo.start();
}
public void timerStop(){
    tiempo.stop();
}
    }

//最後に、画像パネルクラスは、背景としてimgを持つ単純なパネルのみを作成します

    public class ImagePanel extends JPanel {
private static final long serialVersionUID = 1L;
public String state = "running";
private Image img;
    private size = 1;

    public ImagePanel(int color) {
    String cad=null;
    this.setVisible(true);
cad = "assets/blue.png";
    this.img = new ImageIcon(cad).getImage();
    crearFondo();
    }

    public void crearFondo() {
    Dimension size = new Dimension(32,32);
    setPreferredSize(size);
    setMinimumSize(size);
    setMaximumSize(size);
    setSize(size);
    setLayout(null);
    }

    public void paintComponent(Graphics g) {
    g.drawImage(img, 0,0, null);
    }
    }
4

1 に答える 1

0

まず、コンテナがすでにコンポーネント階層にアタッチされており、表示されている場合は、通常、コンテナに何かを追加した後に再検証する必要があります。

createRow メソッドで this.add() 呼び出しの後に this.revalidate() を呼び出してみてください。

次に、java.util.Timer を使用しているようです。これは EDT であなたを呼び出すことはありません。代わりに javax.swing.Timer を使用するか、createRow が EDT に戻るようにします。これは SwingUtilities.invokeLater(new Runnable() {...}) で実行できます。私の最初の提案が機能するかどうかに関係なく、これを修正する必要があります!

それでもうまくいかない場合は、SSCCEを提供してください。理想的には、コピーして貼り付けて自分で試すことができるものです。

于 2012-12-03T00:30:04.703 に答える