簡體   English   中英

repaint()的Java不穩定行為(JPanel,JFrame)

[英]java erratic behavior of repaint() (JPanel, JFrame)

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()並立即返回。 這可能與我的問題有關嗎?

總而言之,我的背景面板始終在顯示。 但是,最初運行程序時,“經銷商面板”的面板並不總是顯示。 經銷商面板不顯示的時間,我隱藏並彈出窗口,然后顯示面板。 有人知道這種不穩定行為的原因嗎?

  1. super.paintComponent(g); 通常應該首先調用它,而不管在paintComponent方法中可能要做什么
  2. 不要在繪畫方法中執行可能會很費時的操作,例如加載圖像。 預先加載這些圖像。 繪制方法可能被調用很多次,有時又被快速調用
  3. 避免調用setPreferred/Minimum/MaximumSize
  4. 您可能需要在頂層容器上調用revalidate (或invalidatevalidateJFrame上進行validate ),以便將容器層次結構標記為需要重新布局,而repaint則不會這樣做。
  5. 您應該在EDT的上下文中啟動UI,有關更多詳細信息,請參見初始線程

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM