1

我在禁用 JPanel 以使其内部调用任何方法时遇到问题。我设置了一个带有 2 个 JPanel 的框架来控制框架的图形。问题是,如果我在 Frame 中添加了一个新的 JPanel,并且我还删除了以前存在的旧 JPanel,那么旧 JPanel 中的绘制方法仍然会被调用。

这是我用来测试的代码:

开始类:

    import java.awt.Frame;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.event.WindowEvent;
    import java.awt.event.WindowListener;

    public class Start implements WindowListener, KeyListener{
        public static void main(String[] args) {
            new Start();
        }

        Frame frame = new Frame("Frame");

        TestPanel P1 = new TestPanel();
        TestPanel P2 = new TestPanel();

        static boolean active = true;

        public Start() {
            frame.setSize(500,500);
            frame.setLocationRelativeTo(null);
            frame.addWindowListener(this);
            frame.addKeyListener(this);
            frame.setVisible(true);
            frame.add(P1);
            for (Object c : frame.getComponents()){
                System.out.println(c.toString());
            }
        }

        @Override
        public void keyPressed(KeyEvent e) {
            if (active){
                frame.remove(P1);
                    frame.add(P2);
            }else{
                frame.remove(P2);
                frame.add(P1);
            }
            active = !active;
            for (Object c : frame.getComponents()){
                System.out.println(c.toString());
            }
        }

        @Override
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }

        public void windowOpened(WindowEvent e) {}
        public void windowClosed(WindowEvent e) {}
        public void windowIconified(WindowEvent e) {}
        public void windowDeiconified(WindowEvent e) {}
        public void windowActivated(WindowEvent e) {}
        public void windowDeactivated(WindowEvent e) {}
        public void keyTyped(KeyEvent e) {}
        public void keyReleased(KeyEvent e) {}
    }

测试面板类:

    import java.awt.Graphics;
    import javax.swing.JPanel;


    public class TestPanel extends JPanel{
        boolean active = Start.active;

        @Override
        public void paint(Graphics g) {
            System.out.println(active);
        }
    }

这个程序总是打印“真”,告诉我只有对象 P1 处于活动状态,而 P2 什么也不做,即使它显示在屏幕上。

所以我要问的是如何让 P1 对象在它不在屏幕上时停止调用绘制方法,并让 P2 对象在显示时调用它的绘制方法。

4

3 回答 3

2

让我们从

TestPanel P1 = new TestPanel();
TestPanel P2 = new TestPanel();

P1并且P2是同一类的单独实例。

看着

static boolean active = true;

// From TestPane
public void paint(Graphics g) {
    System.out.println(active);
}

因此,无论屏幕上的哪个面板,它都会始终显示任何值active

您没有提供任何方法来实际识别对象的不同实例,那么,您怎么知道P1实际开始调用?

于 2012-12-19T23:30:57.743 回答
1

每个面板中的局部变量“活动”不是参考,而是原始变量。它的值设置为创建面板时在“开始”类中设置的任何静态值。对于两个 Panel 实例,您显示的代码中的哪个都是“真”。这解释了为什么您的代码总是打印“true”。

至于显示问题,请注意删除功能的 JavaDoc:

注意:如果组件已从已显示的容器中删除,则必须在该容器上调用 validate() 以反映更改。如果要删除多个组件,您可以通过在所有组件都已删除后仅调用一次 validate() 来提高效率。

于 2012-12-19T23:40:57.280 回答
1

可能是因为 Frame 的 remove 方法是针对 MenuComponent 的。http://docs.oracle.com/javase/6/docs/api/java/awt/Frame.html#remove%28java.awt.MenuComponent%29 ...正确的方法是使用 frame.getContentPane 添加组件().add(P1)。尝试使用 frame.getContentPane().remove(P1) 看看它是否有效。

于 2012-12-19T23:44:35.157 回答