Почему установка макета в BorderLayout означает, что paintComponent никогда не вызывается - PullRequest
1 голос
/ 01 февраля 2011

В следующем примере программы, если для useBorderlayout задано значение true, метод paintComponent никогда не вызывается - почему?!

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

public class PaintComponentTest extends JPanel {
    private final boolean useBorderLayout;

    public PaintComponentTest(boolean useBorderLayout){
        this.useBorderLayout = useBorderLayout;
        initialiseComponents();
    }

    public void initialiseComponents(){
        setOpaque(true);
        setBackground(Color.RED);
        if(useBorderLayout){
            //this appears to be the offending line:
            setLayout(new BorderLayout());
        }
        final JPanel panel = new JPanel();
        panel.setOpaque(true);
        panel.setBackground(Color.GREEN);
        add(panel, BorderLayout.CENTER);

    }
    @Override
    public void paintComponent(Graphics g){
        System.out.println("PaintComponentTest.paintComponent");
        super.paintComponent(g);
    }

    public static void main(String [] args){
        final boolean useBorderLayout = (args.length == 1 && Boolean.parseBoolean(args[0]));

        System.out.println("Running with"+(useBorderLayout?"":"out")+" BorderLayout as layout manager...");

        SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                final JFrame frame = new JFrame("BorderLayout/PaintComponent test");
                frame.setPreferredSize(new Dimension(200, 200));
                frame.getContentPane().setLayout(new BorderLayout());
                final PaintComponentTest componentTest = new PaintComponentTest(useBorderLayout);
                frame.getContentPane().add(componentTest);
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

Ответы [ 2 ]

4 голосов
/ 01 февраля 2011

Потому что это не нужно.Класс PaintComponentTest - это JPanel, в качестве содержимого которого используется один зеленый JPanel.Когда BorderLayout установлен, зеленая панель занимает все пространство на панели, а метод PaintComponent не нужен.

Добавьте этот метод к своему коду, и вы увидите, что это произойдет:

    @Override
    public void paintChildren(Graphics g){
        System.out.println("PaintComponentTest.paintChildren");
        super.paintChildren(g);
    }
3 голосов
/ 01 февраля 2011

Поскольку вложенная панель покрывает все компоненты.Поврежденная область (подлежит перекрашиванию) остается за детьми, потому что границы ребенка охватывают всю поврежденную область.

...