【问题标题】:Java - How to make the images disappearJava - 如何使图像消失
【发布时间】:2012-08-30 18:01:57
【问题描述】:

嗨,我想让我的 JPanel 消失,所以我写了这些代码行

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

这只会让 JComponents 和 JButtons 消失。我想让我用paint方法显示的图像也消失。如果我做 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

提前致谢。

【问题讨论】:

    标签: java swing awt visibility layout-manager


    【解决方案1】:

    首先,不要调用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);
        }
    }
    

    现在,这将停止绘制图像。

    但是,如果您不再想使用该组件(即,您想将其从屏幕上移除,以便在屏幕上放置一个新组件),则需要将该组件从其父组件中移除,这是 Code-Guru 建议的(所以我不会窃取他的答案;))

    更新

    好的,你有一个想法的核心,但要么不太知道如何实现它,要么决定放弃它。

    基本上,从您的代码的外观来看,您要么尝试,要么已经实现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);
                }
            }
        }
    }
    

    菜单屏幕...

    当你点击开始时……游戏画面……

    现在这是一个示例。请尝试并花时间了解它在代码中发生的事情,然后再继续执行并实施它。我用的是自己的图片,你需要自己的..

    【讨论】:

    • 那是因为它是所有可用删除方法的标记,remove(int)、remove(Component)、removeAll,而不是一个独立的方法;)
    • 确实偷了我的答案(回复:添加在paintComponent() 中使用的标志)......虽然我没有那么明确。 =p
    • @Code-Guru 对不起,我的意思是parent.remove(this):P
    • @user1650271 我已经“修改”了您的代码以正确使用CardLayout,请阅读:P
    • @MadProgrammer 也许网络丢弃了一个“开玩笑的数据包”。
    【解决方案2】:

    有几种方法可以阻止 JPanel “出现”,具体取决于您想要完成的任务。一是打电话给setOpaque(false);。不过,我不完全确定这会如何影响自定义绘画。

    另一种可能性是

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

    第三种可能性是在您的类中添加一个标志,该标志在您单击 JLabel(或者更好的是 JButton - 请参见下面的 cmets)时设置。然后在您的paintComponent() 方法中,您可以检查标志并相应地绘制。

    注意:

    您错误地使用 JLabel 和鼠标事件来响应用户输入。通常在 Swing 应用程序中,我们使用 JButton 和 ActionListener 来完成您在此处尝试执行的操作。这样做的一个好处是您只需要实现一种称为onActionPerformed() 的方法,而不必担心添加所有您甚至不想响应的鼠标事件处理程序。

    【讨论】:

    • 这些都不起作用。第二种可能性是它无法识别 getParent。
    • @user1650271 什么不能准确识别getParent?请发布您使用的确切代码以及针对我的每条建议收到的错误消息。
    猜你喜欢
    • 2021-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 2011-11-20
    • 1970-01-01
    相关资源
    最近更新 更多