0

こんにちは、JPanelを非表示にしたいので、これらのコード行を記述しました

removeAll();
updateUI();
revalidate();

それだけでJComponentsとJButtonsが消えました。ペイント方式で表示した画像も消したいのですが。setVisible(false)を実行すると、その後ろに別のJPanelを追加できなくなります。

これは私のクラスです:

package screens;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
public class menuScreen extends JPanel implements MouseListener{
    private static final long serialVersionUID = 1L;

//-------------VARIABLES---------------//
    Image wallpaper = (Image)Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/wallpaper.jpg"));
    Image title_text = (Image)Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/title-text.png"));
    ImageIcon startGameimg = new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/startGame.png")));
    ImageIcon optionsimg = new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/options.png")));
    //JButton start = new JButton(basketball);
    JLabel options = new JLabel(optionsimg);
    JLabel startGame =  new JLabel(startGameimg);
    gameScreen gS = new gameScreen();
    CardLayout scenechange = new CardLayout();
    JPanel scenechange1 = new JPanel (scenechange);

//-------------PAINT FUNCTION----------//
    public void paintComponent(Graphics g){
    g.drawImage(wallpaper,0,0,this);
    g.drawImage(title_text,0,0,this);
    //g.drawImage(basketball1,110,180,this);

    }

//-------------CONSTRUCTOR-------------//
    public menuScreen(){

    scenechange.addLayoutComponent(this,"menuScreen");
    scenechange.addLayoutComponent(gS,"gameScreen");
    //scenechange.show(this,"menuScreen");

    this.setLayout(null);
    this.add(options);
    this.add(startGame);
    startGame.setBounds(110,180,110,110);
    options.setBounds(110,300,110,110);
    startGame.addMouseListener(this);
    options.addMouseListener(this);


    }


    public void mouseClicked(MouseEvent e) {
    if(e.getSource() ==  (startGame)){

        removeAll();

        revalidate();
        add(gS);
    }

    if(e.getSource() == (options)){
        setVisible(false);
    }


    }


    public void mousePressed(MouseEvent e) {
    // TODO Auto-generated method stub

    }


    public void mouseReleased(MouseEvent e) {
    // TODO Auto-generated method stub

    }


    public void mouseEntered(MouseEvent e) {
    // TODO Auto-generated method stub

    }


    public void mouseExited(MouseEvent e) {
    // TODO Auto-generated method stub

    }


}//END OF CLASS startingScreen

前もって感謝します。

4

2 に答える 2

2

まず、呼び出さないでくださいupdateUI。これはルックアンドフィールに関連しており、(直接)コンポーネントの更新には関連していません。

パネル内にカスタムペイントルーチンを提供している場合は、画像のペイントを停止する必要があります(独自のコンテンツのペイントを妨げることはありません)。 removeXxx以前にコンテナに追加した子コンポーネントを削除します。

もう少しコードが役立つでしょう

アップデート

最初に、あなたの絵があなたのコンテナのコンポーネントではなく、それらは「スタンプ」されています、あなたは画像をペイントしないようにコンポーネントに伝える何らかの方法が必要です

public void paintComponent(Graphics g){
    super.paintComponent(g); // this is super important
    if (paintImages){ // you need to define and set this flag
        g.drawImage(wallpaper,0,0,this);
        g.drawImage(title_text,0,0,this);
    }
}

これで、画像のペイントが停止します。

ただし、コンポーネントを使用する必要がなくなった場合(つまり、画面からコンポーネントを削除して、その場所の代わりに新しいコンポーネントを画面に配置できるようにする場合)、このコンポーネントをその親から削除する必要があります。 -達人は提案しました(だから私は彼の答えを盗むことはありません;))

アップデート

さて、あなたはアイデアの核心を持っていましたが、それを実装する方法を完全に知らなかったか、それを破棄することにしました。

基本的に、コードの見た目から、あなたは実装しようとしていたか、実装しようとしていましたがCardLayout、残念ながら、それについて間違った考えを持っていました。

を使用CardLayoutすると、画面の切り替えを担当するコンポーネントである「コントローラ」を使用する必要があります。

public class ScreenController extends JPanel {

    private static final long serialVersionUID = 1L;
//-------------VARIABLES---------------//
    MenuScreen ms = new MenuScreen();
    GameScreen gs = new GameScreen();
    CardLayout sceneChange;

//-------------CONSTRUCTOR-------------//
    public ScreenController() {

        sceneChange = new CardLayout();

        this.setLayout(sceneChange);
        add(ms, "menuScreen");
        add(gs, "gameScreen");

        sceneChange.show(this, "menuScreen");

        ms.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getActionCommand().equalsIgnoreCase("startgame")) {
                    sceneChange.show(ScreenController.this, "gameScreen");
                }
            }
        });
    }

}//END OF CLASS startingScreen

次に、メニューとゲーム画面があります...

public class MenuScreen extends JPanel implements MouseListener {

    private static final long serialVersionUID = 1L;
//-------------VARIABLES---------------//
    //JButton start = new JButton(basketball);
    JLabel options = new JLabel("Options");
    JLabel startGame = new JLabel(" >> Start << ");
//    gameScreen gS = new gameScreen();
    BufferedImage wallpaper;

//-------------PAINT FUNCTION----------//
    @Override
    public void paintComponent(Graphics g) {
        System.out.println("paint");
        super.paintComponent(g);
        if (wallpaper != null) {
            g.drawImage(wallpaper, 0, 0, this);
        }
    }

//-------------CONSTRUCTOR-------------//
    public MenuScreen() {

        // Please handle your exceptions better
        try {
            wallpaper = ImageIO.read(getClass().getResource("/Menu.png"));
            setPreferredSize(new Dimension(wallpaper.getWidth(), wallpaper.getHeight()));
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        setLayout(new GridBagLayout());

        Cursor cusor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
        options.setCursor(cusor);
        startGame.setCursor(cusor);

        Font font = UIManager.getFont("Label.font").deriveFont(Font.BOLD, 48);
        options.setFont(font);
        startGame.setFont(font);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;

        this.add(options, gbc);
        gbc.gridy++;
        this.add(startGame, gbc);
        startGame.addMouseListener(this);
        options.addMouseListener(this);
    }

    public void mouseClicked(MouseEvent e) {
        if (e.getSource() == (startGame)) {
            fireActionPerformed("startGame");
        }
        if (e.getSource() == (options)) {
            fireActionPerformed("gameOptions");
        }
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void addActionListener(ActionListener listener) {
        listenerList.add(ActionListener.class, listener);
    }

    public void removeActionListener(ActionListener listener) {
        listenerList.remove(ActionListener.class, listener);
    }

    protected void fireActionPerformed(String cmd) {
        ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
        if (listeners != null && listeners.length > 0) {
            ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, cmd);
            for (ActionListener listener : listeners) {
                listener.actionPerformed(evt);
            }
        }
    }
}

メニュー画面...

メニュー画面

そして、スタートをクリックすると...ゲーム画面...

ここに画像の説明を入力してください

これが例です。先に進んで実装する前に、時間をかけてコードで何が起こっているのかを理解してください。私は自分の画像で使用しました、あなたはあなた自身のものを手に入れる必要があるでしょう。

于 2012-09-05T23:47:49.977 に答える
1

達成したいことによっては、JPanelが「表示」されないようにする方法がいくつかあります。1つは呼び出すことでしたsetOpaque(false);。ただし、これがカスタムペイントにどのように影響するかは完全にはわかりません。

別の可能性は

Container parent = getParent().remove(this);
parent.validate();

3番目の可能性は、JLabel(またはさらに良いのはJButton-以下のコメントを参照)をクリックしたときに設定されるフラグをクラスに追加することです。次に、paintComponent()メソッドでフラグを確認し、それに応じて描画できます。

ノート:

ユーザー入力に応答するためにJLabelおよびマウスイベントを誤って使用しています。通常、Swingアプリケーションでは、JButtonとActionListenersを使用して、ここで実行しようとしていることを実行します。これの利点の1つは、呼び出されるメソッドを1つだけ実装onActionPerformed()する必要があり、応答すらしたくないすべてのマウスイベントハンドラーを追加することを心配する必要がないことです。

于 2012-09-06T00:03:40.177 に答える