Как обеспечить отрисовку под JInternalFrame?

У меня есть установка, в которой есть несколько JInternalFrames в основном JFrame. Что я хочу сделать, так это нарисовать некоторые вещи на основном JFrame, но под JInternalFrame. Если я настрою код как

public void paint(Graphics graphics){
    try{
        Graphics2D g = (Graphics2D) s.getDrawGraphics();
        super.paint(g);
        super.paintComponents(g);

        //Insert Paint Code Here

        s.show();
        super.repaint();
    }catch(Exception ex){}
}

окрашенное содержимое отображается над JInternalFrames (которые являются компонентами JDesktopFrame). Если я попытаюсь поместить код рисования перед super.paint(g) или super.paintComponents(g), нарисованное содержимое вообще не появится. Как сделать так, чтобы отображалось нарисованное содержимое, но под внутренними рамками?

Примечание. s — это BufferStrategy, и этот класс наследуется от абстрактного класса JFrame.


person user2950265    schedule 01.11.2015    source источник
comment
Не переопределяйте paint, дочерние компоненты могут быть прорисованы независимо от их родителей, которые могут делать всевозможные странные вещи. Не вызывайте show или repaint, на самом деле, не делайте ничего, что может вызвать перерисовку. paint должен рисовать текущее состояние, не более того. Звонить super.paintComponents бессмысленно, paint уже сделал это. s.getDrawGraphics также пугает меня до чертиков, так как вы, кажется, игнорируете систему, поставляемую Graphics, поэтому я понятия не имею, куда вы на самом деле рисуете.   -  person MadProgrammer    schedule 02.11.2015
comment
super.paintComponents(g); Почему этот код включен? ЭТО, кажется, прервало цепочку покраски ..   -  person Andrew Thompson    schedule 02.11.2015
comment
Чтобы быстрее получить помощь, опубликуйте минимально воспроизводимый пример или Короткий, автономный, правильный пример.   -  person Andrew Thompson    schedule 02.11.2015
comment
Более простым решением было бы создать пользовательский компонент, простирающийся от JPanel (или JDesktopPane в вашем случае), и переопределить его paintComponent и выполнить там свою пользовательскую отрисовку, в основном игнорируя все остальное, что может быть добавлено к нему, таким образом, что бы вы ни рисовали. будет гарантированно окрашен ниже JInternalFrames   -  person MadProgrammer    schedule 02.11.2015


Ответы (1)


Вы, кажется, не понимаете, как работает рисование в Swing, взгляните на Рисование в AWT и Swing и Выполнение пользовательского рисования Больше подробностей.

По сути, если вы хотите нарисовать что-то под JInternalFrame, нужно начать с переопределения метода paintComponent для JDesktopPane. Метод paintComponent — это самый нижний виртуальный уровень в цепочке рисования, поверх которого нарисованы paintBorder и paintChildren.

Панель рабочего стола

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                CustomDesktopPane pane = new CustomDesktopPane();
                JInternalFrame inFrm = new JInternalFrame("Ontop", true, true, true, true);
                inFrm.setSize(100, 100);
                inFrm.setLocation(150, 150);
                inFrm.setVisible(true);
                pane.add(inFrm);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(pane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class CustomDesktopPane extends JDesktopPane {

        public CustomDesktopPane() {
            setFont(UIManager.getFont("Label.font").deriveFont(24f));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            String text = "All your base are belong to us";
            Font font = g2d.getFont();
            FontMetrics fm = g2d.getFontMetrics();
            int x = (getWidth() - fm.stringWidth(text)) / 2;
            int y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
            g2d.setColor(Color.WHITE);
            g2d.drawString(text, x, y);
            g2d.dispose();
        }

    }


}
person MadProgrammer    schedule 01.11.2015