【问题标题】:Java: Why validate don't workJava:为什么验证不起作用
【发布时间】:2014-07-03 08:00:26
【问题描述】:

我想动态更改面板,正如answer 所示,他们建议使用cardLayout。但我想更改整个 UI(没有旧按钮),而 cardLayout 似乎不太方便。所以我有以下代码:

 JFrame frame = new JFrame ("Key test");
    MyDrawPanel1 dp1 = new MyDrawPanel1(frame);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible (true);
    JPanel p = new JPanel ();
    p.setLayout(new BorderLayout());
    p.add(dp1,BorderLayout.CENTER);

    frame.getContentPane().add(p);
    frame.pack();
    frame.setVisible (true);

并且在 MyDrawPanel1 中有一个按钮可以改变面板:

  public MyDrawPanel1(final JFrame frame) {
    clickButton.addActionListener(new ActionListener(){

        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            frame.getContentPane().removeAll();
            //frame.validate();
            frame.getContentPane().add(new MyDrawPanel2());
            ((JPanel)frame.getContentPane()).revalidate();

        }

    });
    this.add(clickButton);

}

编辑:MyDrawPanel1 中还有一些代码。

  JButton clickButton  = new JButton("click");

Image image = new ImageIcon("D:/0.jpg").getImage();
public void paintComponent (Graphics g) {
    super.paintComponent(g);
    g.drawImage(image, 3, 40, null);
}
public Dimension getPreferredSize() {
    if (image != null) {
         return new Dimension(image.getWidth(null), image.getHeight(null));
      }
      return super.getPreferredSize(); // default
}

但是第一个面板并没有消失,我必须最小化它才能刷新它,这样我才能看到第二个面板。我的问题是为什么验证不起作用以及是否还有其他选择。谢谢。

编辑:这是我截取的关于面板的图片。(第一个面板):

(点击后):

编辑: madProgrammer 和 Adarsh Singhal 提供了两种解决问题的方法。第一个是面板不调用 super.paintComponent() 的第二个,所以添加它然后它就可以正常工作(就像 answer 说的那样,它是橡皮擦,所以第一个面板消失了)。第二个是调用frame.repaint(),但是我不明白为什么?

【问题讨论】:

  • 试试revalidate(),CardLayout有什么问题?
  • API 可能不认为面板处于无效状态。
  • 我认为你需要的是 invalidate(),而不是 validate()。
  • @MadProgrammer 对不起,我不明白你在说什么。哪个面板处于无效状态。
  • 实际上,从您的屏幕截图来看,您似乎因为不调用super.paintXxx 而破坏了绘制链。实际的runnable example that demonstrates your problem 将涉及更少的猜测工作和更好的响应

标签: java validation jpanel


【解决方案1】:

我们必须使用 repaint() 来告诉组件重新绘制自己。把它想象成你的情况。而 revalidate 用于更新布局。因此,每当您动态添加/删除组件时,都需要同时调用它们。

以下编写的代码显示了一个设置为 CardLayoutJFrame 来绘制红色 dp1(JPanel) 完全在 JFrame 上。在 dp1 上有一个 Jbutton。如果单击该按钮,将删除 dp1 并绘制 dp2(JPanel)。 dp2 为绿色以区分变化。您似乎忘记了 repaint()

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class MyFrame extends JFrame{
    JButton button;
    private static MyFrame frame;
    public MyFrame(){
        this.setSize(400, 400);
        this.setLayout(new CardLayout());
        this.setLocationRelativeTo(null);
        JPanel dp1 = new JPanel();
        dp1.setBackground(Color.RED);
        add(dp1);
        button  = new JButton("Click me to remove dp1 & draw dp2");
        dp1.add (button);
        JPanel dp2 = new JPanel ();
        dp2.setBackground(Color.GREEN);


        button.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent arg0) {
                frame.getContentPane().remove(dp1);
                frame.add(dp2);
                frame.revalidate();
                frame.repaint();

            }});

       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible (true);
    }

    public static void main(String[] args) {
        frame = new MyFrame();
    }
}

【讨论】:

    猜你喜欢
    • 2017-07-03
    • 2013-05-27
    • 2018-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 2012-02-02
    相关资源
    最近更新 更多