我从JPanel派生出一个自定义类,并重写了paintComponent方法,然后在JFrame里载入,但问题是程序在启动后并没有调用paintComponent方法,就算调用repaint方法也没用,只有在窗体的大小改变时才会调用,这是什么原因?我怎样才能在程序启动后让这个JPanel就自动重绘一下?

解决方案 »

  1.   

    如果你是不想让绘制jPanel跟隨下jFrame和jPanel 的大小變化而改變的話,你就把 
    draw()方法中的gc.fillRect(0, 0, this.panel.getWidth(), this.panel.getHeight())去掉, 
    因為第次jPanel變化時都會調draw()哦 
      

  2.   

    Java code import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; /** * 作者:李 世贵 * JDK: 1.6 * 来源: http://blog.csdn.net/lishigui * 欢迎转接,请保留作者和来源,谢谢! * 2009-4-24 上午11:30:15 */ public class FrameTest extends JFrame { private JPanel panel; private int width, height; public static void main(String args[]) { EventQueue.invokeLater(new Runnable() { public void run() { try { FrameTest frame = new FrameTest(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } public FrameTest() { super(); getContentPane().setLayout(null); addMouseListener(new MouseAdapter() { public void mouseClicked(final MouseEvent e) { } }); setBounds(100, 100, 500, 375); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); getContentPane().add(getPanel()); } private void out() { int width = this.getWidth() + 20; int height = this.getHeight() + 20; this.setSize(width, height); this.setPreferredSize(new Dimension(width, height)); this.panel.setSize(width, height); this.panel.setPreferredSize(new Dimension(width, height)); } private void draw(Graphics gc) { gc.setColor(Color.RED); gc.fillRect(0, 0, width, height); } protected JPanel getPanel() { if (panel == null) { panel = new JPanel() { public void paintComponent(Graphics gc) { draw(gc); } }; panel.setBounds(0, 0, 492, 348); panel.setLayout(null); width = 492; height = 348; panel.addMouseListener(new MouseAdapter() { public void mouseExited(final MouseEvent e) { out(); } }); final JButton button_1 = new JButton(); button_1.setBounds(137, 5, 106, 28); button_1.setText("New JButton"); panel.add(button_1); final JButton button = new JButton(); button.setBounds(248, 5, 106, 28); button.setText("New JButton"); panel.add(button); } return panel; } } 
      

  3.   

    在构造函数中添加下列事件就可以了,具体原因不祥: 
    this.addComponentListener(new ComponentAdapter() { 
    public void componentResized(final ComponentEvent e) { 
    super.componentResized(e); 

    }); 
      

  4.   

    我的意思是希望用JPanel派生出来的类被add到JFrame窗体后,能自动调用该派生类的paintComponent方法,而且该派生类的大小我没定义,是因为想让该类被add到JFrame后再得到大小,JFrame的布局是BorderLayout,我是想把派生类放在CENTER里的,但现在的问题是不但该派生类在加载后不会自动重绘,而且还得不到add后的大小
      

  5.   

    将validate()方法调用在repaint()方法之前看看能不能重绘
      

  6.   

    这个方法试了后有一个很奇怪的现象,即被派生自JPanel的那个类会在程序启动时调用重绘方法,但这是随机的,我关闭程序后再试了几次就再也没有出生重绘方法被调用迹象了,不知是什么原因
      

  7.   

    首先我照你的说的在repaint方法前加了validate方法,然后按调试,程序在启动时终于能重绘我自义的那个派生自JPanel的类里的paintComponent方法了,到此应该说问题解决了吧,然后我再关闭程序,再按调试就发生了派生类的paintComponent未调用的现象,这就又回到了问题之首,然后我又关闭程序反复重试了好几次就再也没出现paintComponent方法被调用的事了
      

  8.   

    你所说的关闭程序再调试是怎么的一个操作?
        别说我搞SWING这个东东还真不知道怎么去调试他
      

  9.   

    在Eclipse里编了代码按CTRL+F11啊
      

  10.   

    哎,我看是还是省点力气DEBUG调试SWING一般都不准确,除非你对多线程非常了解,还有就是对DEBUG的调试非常熟练,SWING很多地方涉及到多线程,用DEBUG来调试就我的感觉就是将你简单的代码调的都不知道怎么去运行的,所以我不建议去使用DEBUG调试,应该用validate没有什么问题的,我的项目就是那样做的没有说出现绘不出来的问题
      

  11.   

    我重写的paintComponent方法里有调用到图片的代码,我把与图片有关的代码全注解掉程序就一切正常了,难道图片的调用也和多线程有关吗
      

  12.   

    你不把代码贴出来我也不知道你是怎么运行的,还有出现了什么问题,你说关闭程序调试后不调用paintComponent?因为我不知道怎么调试?也不知道出现了什么样的效果
      

  13.   

    package UI;import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.RenderingHints;
    import java.awt.Toolkit;import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JMenu;
    import javax.swing.JMenuBar;
    import javax.swing.JPanel;public class WelcomePanel extends JPanel {

    private JFrame mainFrame;
    private Image[] img;

    public WelcomePanel(JFrame mainFrame)
    {
    this.mainFrame = mainFrame;
    img[0] = this.load("image/title.jpg");
    initUI();
    }

    public void initUI()
    {
    initMenu();
    }

    private void initMenu()
    {
    JMenuBar menuBar = this.mainFrame.getJMenuBar();
    menuBar.removeAll();
    JMenu mnuFile = new JMenu("退出");
    menuBar.add(mnuFile);
    this.mainFrame.setJMenuBar(menuBar);
    }

    private Image load(String filename)
    {
    return new ImageIcon(this.getClass().getClassLoader().getResource(filename)).getImage();
    }

    public void paintComponent(Graphics g)
    {
    Graphics2D g2d = (Graphics2D)g;
    g2d.drawImage(img[0], 0, 0, null);
    g2d.dispose();
    }
    }
      

  14.   

    问下,出现什么问题了?
       我这边运行的好好的,能够让Jpanel的图片画出来
      

  15.   


    public class WelcomePanel extends JPanel {
        
        private JFrame mainFrame;
        private Image img;
        
        public WelcomePanel(JFrame mainFrame)
        {
            this.mainFrame = mainFrame;
            img = this.load("image/title.jpg");
            mainFrame.add(this);
            mainFrame.validate();
            mainFrame.repaint();
        }
        
        private Image load(String filename)
        {
         return new ImageIcon(this.getClass().getResource(filename)).getImage();
        }
        
        public void paintComponent(Graphics g)
        {
            Graphics2D g2d = (Graphics2D)g;
            g2d.drawImage(img, 0, 0, null);
            g2d.dispose();
        }
        
        public static void main(String[] args) {
         JFrame frm=new JFrame();
    frm.setBounds(200, 200, 550, 330);
    frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frm.setVisible(true);
    WelcomePanel welcome=new WelcomePanel(frm);

    }
    }
    图片你随便放一张
      

  16.   

    图片没有问题,我这里就是没法显示图片,我把构造方法里关于图片的代码删了,然后在paintComponent方法里把关于图片的代码改为g2d.drawImage(this.load("image/title.jpg"), 0, 0, null);就又正常了
      

  17.   

    搞不懂,你不是重绘图片到JPanel中么?
       我的那个代码都已经实现了,什么构造方法里面的图片不懂,你想做个什么效果
    不说清楚我也不知道你想干什么,马上就下班过年了说清楚帮你在走人
      

  18.   

    我现在能运行是这样写代码的
    package UI;import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.RenderingHints;
    import java.awt.Toolkit;import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JMenu;
    import javax.swing.JMenuBar;
    import javax.swing.JPanel;public class WelcomePanel extends JPanel {

    private JFrame mainFrame;

    public WelcomePanel(JFrame mainFrame)
    {
    this.mainFrame = mainFrame;
    initUI();
    }

    public void initUI()
    {
    initMenu();
    }

    private void initMenu()
    {
    JMenuBar menuBar = this.mainFrame.getJMenuBar();
    menuBar.removeAll();
    JMenu mnuFile = new JMenu("退出");
    menuBar.add(mnuFile);
    this.mainFrame.setJMenuBar(menuBar);
    }

    private Image load(String filename)
    {
    return new ImageIcon(this.getClass().getClassLoader().getResource(filename)).getImage();
    }

    public void paintComponent(Graphics g)
    {
    Graphics2D g2d = (Graphics2D)g;
    g2d.drawImage(this.load("image/title.jpg"), 0, 0, null);
    g2d.dispose();
    }
    }