java的不稳定行为的重绘()(JPanel,JFrame)

时间:2014-03-21 05:22:39

标签: java swing jframe jpanel repaint

package BlackjackPanels;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;

public class MainPanel extends JFrame implements ActionListener {

    private JPanel background;

    public MainPanel() {    
        super("Alan's Blackjack");
        setDefaultCloseOperation(EXIT_ON_CLOSE);        
        background = new JPanel() 
        {   
            @Override
            protected void paintComponent(Graphics g)
            {       
                try 
                {
                    BufferedImage image = ImageIO.read(new File("C:/Users/Ssangwook/Desktop/programming/javafiles/Blackjack/src/BlackjackImages/blackjackTableResized.jpg"));
                    super.paintComponent(g);
                    g.drawImage(image, 0, 0, this);
                } 
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        };

        background.setPreferredSize(new Dimension(1000,500));
        add(background);
        pack();
        setLocationRelativeTo(null);
        setResizable(false);
        //isRunning();
        setVisible(true);
    }

    public void isRunning() {
        background.setLayout(new BorderLayout(10, 10));
        DealerPanel dealer=new DealerPanel();
        background.add(dealer, BorderLayout.LINE_START);
        repaint();
    }

    @Override
    public void actionPerformed(ActionEvent a) {
    }

    public static void main(String [] args) {
        MainPanel game=new MainPanel(); 
        game.isRunning();
    }
}

DealerPanel

package BlackjackPanels;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;

public class DealerPanel extends JPanel {

    private JButton hit = new JButton("Hit");
    public DealerPanel() {
        super();
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        setPreferredSize(new Dimension(100,100));
        setOpaque(false);
        setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.DARK_GRAY), "DEALER"));

    }

    protected void askBets() {

    }

    public void addListener(ActionListener a) {
        hit.addActionListener(a);
    }
}

您好,我刚开始用GUI制作二十一点。但是,我遇到了一个问题,我真的希望有人可以解释一下。

问题似乎是isRunning()方法中的repaint()。每当我在Eclipse上运行程序时,我只在后台获得DealerPanel面板的一半时间。另外一半没有显示面板,我必须最小化JFrame窗口并再次将其重新启动,并且DealerPanel的面板以某种方式再次显示。

我自己做了一点搜索,发现repaint()只是请求AWT线程调用update()然后调用paint(),因此不是直接调用paint。此外,repaint()可能会有问题,因为repaint()仅调度paint()并立即返回。这可能与我的问题有关吗?

总结一下,我的面板背景总是显示出来。但是,我最初运行程序时,我的Dealer Panel面板并不总是显示。经销商面板未显示的时间,我隐藏并调出窗口并显示面板。有人知道这种不稳定行为背后的原因吗?

1 个答案:

答案 0 :(得分:2)

    应始终首先调用
  1. super.paintComponent(g);,无论您在paintComponent方法中执行的其他操作是什么
  2. 不要在绘制方法中执行可能很耗时的操作,例如加载图像。提前加载这些图像。油漆方法可能会多次调用,有时会快速连续调用
  3. 避免致电setPreferred/Minimum/MaximumSize
  4. 您可能需要在顶级容器上调用revalidate(或invalidatevalidate JFrame),以便将容器层次结构标记为需要重新启动out,repaint不会这样做。
  5. 您应该在EDT的上下文中启动您的用户界面,有关详细信息,请参阅Initial Threads