简体   繁体   English

重新验证和重新绘制不起作用

[英]Revalidate and Repaint not Working

import java.awt.*;
import javax.swing.*;

public class Class4 {

    public static final long serialVersionUID = 1L;

    public void mainMethod(int event){
        JFrame f = new JFrame("Love Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(500,200);     
        f.setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();

        if(event == 0){




            JPanel p = new JPanel();
            p.setLayout(new BoxLayout(p,BoxLayout.Y_AXIS));
            p.setBounds(150, 0, 500, 75);
            p.setPreferredSize(new Dimension(150,75));
            JTextField boy = new JTextField();
            boy.setMaximumSize(new Dimension(200,40));
            JTextField girl = new JTextField();
            girl.setMaximumSize(new Dimension(200,40));
            p.add(boy);
            p.add(girl);
            gbc.insets = new Insets(-90,310,0,0);
            gbc.gridx = 0;
            gbc.gridy = 0;
            f.add(p,gbc);

            JPanel p3 = new JPanel(new BorderLayout());
            p3.setBounds(0, 0, 150, 75);
            p3.setPreferredSize(new Dimension(150,75));
            Class5 c5o = new Class5();
            c5o.setPreferredSize(new Dimension(150,75));
            p3.add(c5o);
            gbc.insets = new Insets(0,0,90,330);
            gbc.gridx = 0;
            gbc.gridy = 0;
            f.add(p3,gbc);

            JPanel p2 = new JPanel(new FlowLayout());
            Class7 c7o = new Class7();
            p2.add(c7o);
            p2.setPreferredSize(new Dimension(300,40));
            gbc.insets = new Insets(0,0,-20,0);
            gbc.gridx = 0;
            gbc.gridy = 0;
            f.add(p2,gbc);

            f.setVisible(true);

            //1st
            JOptionPane.showMessageDialog(null,f.isVisible());


        }

        if(event == 5){

            JPanel p4 = new JPanel(new BorderLayout());
            p4.setBounds(0,140,500,55);
            Class2 c2o = new Class2();
            Dimension d2 = new Dimension(500,55);
            c2o.setPreferredSize(d2);
            p4.setPreferredSize(d2);
            p4.add(c2o);
            gbc.insets = new Insets(0,0,-130,0);
            gbc.gridx = 0;
            gbc.gridy = 0;  
            f.add(p4,gbc);

            f.invalidate();
            f.validate();
            f.repaint();

            //2nd
            JOptionPane.showMessageDialog(null,f.isVisible());
        }

    }

}

The revalidate and repaint doesn't work. 重新验证和重新绘制不起作用。 I have an layout manager, so I suspect the problem is with the if statements. 我有一个布局管理器,所以我怀疑问题出在if语句上。 The 1st time I test the visibility of f, it returned true. 我第一次测试f的可见性时,它返回true。 The second time I tested the same thing, it returned false. 我第二次测试相同的东西,它返回false。 Why doesn't my revalidate and repaint work? 为什么我的重新验证和重新粉刷不起作用? How I need to do to get it to work? 我需要怎么做才能使其正常工作?

 if(event == 5){

        JPanel p4 = new JPanel(new BorderLayout());
        p4.setBounds(0,140,500,55);
        Class2 c2o = new Class2();
        Dimension d2 = new Dimension(500,55);
        c2o.setPreferredSize(d2);
        p4.setPreferredSize(d2);
        p4.add(c2o);
        gbc.insets = new Insets(0,0,-130,0);
        gbc.gridx = 0;
        gbc.gridy = 0;  
        f.add(p4,gbc);

        f.invalidate();
        f.validate();
        f.repaint();

        //2nd
        JOptionPane.showMessageDialog(null,f.isVisible());
    }

The frame f it isn't visible(missing the f.setVisible(true); ), so not need to be revalidated and repainted in this case, it will not be visible for user. 框架f是不可见的(缺少f.setVisible(true); ),因此在这种情况下无需重新验证和重新绘制,对于用户而言它将是不可见的。 Also use a logger or a breakpoint to test f.isVisible() because that will block the ui. 还要使用记录器或断点来测试f.isVisible()因为这会阻止ui。

There are some issues with this code, but the major one is the scope of your JFrame reference f . 此代码存在一些问题,但主要的问题是JFrame参考f的范围。

Assumed that you are calling the method somehow like in this main sample: 假设您正在以某种方式调用此方法,如以下main示例所示:

public static void main(String[] args) {
  Class4 c = new Class4();
  c.mainMethod(0);
  c.mainMethod(5);
}

Then, your code is creating a second JFrame during the second call. 然后,您的代码将在第二次调用期间创建第二个JFrame

Move the JFrame creation into the constructor and make f a member variable: 将JFrame创建移动到构造函数中,并使f为成员变量:

public class Class4 {

    private JFrame f;

    public Class4() {
       f = new JFrame("Love Test");
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       f.setSize(500,200);     
       f.setLayout(new GridBagLayout());
    }

    // ...
}

You can then modify the JFrame in subsequent calls of the mainMethod() . 然后,您可以在mainMethod()后续调用中修改JFrame。

Some additional notes: 一些附加说明:

  • Avoid reusing GridBagConstraints . 避免重用GridBagConstraints Create them through the constructor. 通过构造函数创建它们。 This makes the code much more robust. 这使代码更加健壮。
  • You do not need to get the contentPane from the JFrame anymore (as suggested in an other answer). 您不再需要从JFrame获取contentPane (如其他答案中所建议)。 As of Java 1.5, the add() methods of JFrame directly delegate to the content pane. 从Java 1.5开始, JFrameadd()方法直接委托给内容窗格。
  • There is no need to do invalidate() or repaint() when adding components to the JFrame . 将组件添加到JFrame时,无需执行invalidate()repaint() add() already invalidates the component hierarchy. add()已经使组件层次结构无效。 However, you need to call validate() when the component has already been shown (as in your case). 但是,当组件已经显示时(如您的情况),您需要调用validate() )。 See java.awt.Container.add() for more information. 有关更多信息,请参见java.awt.Container.add()

I'm having trouble seeing exactly what you're looking for. 我无法准确查看您要寻找的内容。 An SSCCE would really help. SSCCE确实会有所帮助。 Is this what you're looking for? 这是您要找的东西吗?

import java.awt.*;
import javax.swing.*;

class Canv extends JComponent {

    GridBagConstraints gbc;

    public Canv (int event) {

        gbc = new GridBagConstraints();

        switch(event)
        {
            case 0:
                this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
                this.setBounds(150, 0, 500, 75);
                this.setPreferredSize(new Dimension(150,75));
                JTextField boy = new JTextField();
                boy.setMaximumSize(new Dimension(200,40));
                JTextField girl = new JTextField();
                girl.setMaximumSize(new Dimension(200,40));
                this.add(boy);
                this.add(girl);
                gbc.insets = new Insets(-90,310,0,0);
                gbc.gridx = 0;
                gbc.gridy = 0;
                this.add(this,gbc);

                JPanel p3 = new JPanel(new BorderLayout());
                p3.setBounds(0, 0, 150, 75);
                p3.setPreferredSize(new Dimension(150,75));
                //Class5 c5o = new Class5();
                //c5o.setPreferredSize(new Dimension(150,75));
                //p3.add(c5o);
                gbc.insets = new Insets(0,0,90,330);
                gbc.gridx = 0;
                gbc.gridy = 0;
                this.add(p3,gbc);

                JPanel p2 = new JPanel(new FlowLayout());
                //Class7 c7o = new Class7();
                //p2.add(c7o);
                p2.setPreferredSize(new Dimension(300,40));
                gbc.insets = new Insets(0,0,-20,0);
                gbc.gridx = 0;
                gbc.gridy = 0;
                this.add(p2,gbc);
                break;
            case 5:
                JPanel p4 = new JPanel(new BorderLayout());
                p4.setBounds(0,140,500,55);
                //Class2 c2o = new Class2();
                Dimension d2 = new Dimension(500,55);
                //c2o.setPreferredSize(d2);
                p4.setPreferredSize(d2);
                //p4.add(c2o);
                gbc.insets = new Insets(0,0,-130,0);
                gbc.gridx = 0;
                gbc.gridy = 0;  
                this.add(p4,gbc);

                //this.invalidate();
                this.validate();
                this.repaint();

                JOptionPane.showMessageDialog(null,this.isVisible());
                break;
            default:
                break;
        }
    }

    public void paintComponent(){

    }


}

public class Class4 {

    static int event;
    static JFrame frame;
    static Canv canvas;

    public static void main(String[] args)
    {
        frame = new JFrame("Love Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,200);     
        frame.setLayout(new GridBagLayout());
        //event = Integer.parseInt(args[0]);
        event = 5;
        canvas = new Canv(event);
        frame.add(canvas);
        frame.setVisible(true);
    }
}

Running the above code would return true in the dialog box. 运行上面的代码将在对话框中返回true。 In order to change between events, just add another method in Class4 to reset Canv, by calling its constructor with a different event number. 为了在事件之间进行切换,只需在Class4中添加另一个方法来重置Canv,方法是使用不同的事件编号调用其构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM