2 votes

Impossible de dessiner une image sur l'arrière-plan de JTextArea lors de l'utilisation de Nimbus Look And Feel

Je dessine une image sur JTextArea l'arrière-plan, il est dessiné en utilisant d'autres apparences (Metal, Windows, etc.), mais lorsque j'utilise la fonction Nimbus Look And Feel il ne dessine pas d'image Quel peut être le problème et comment le résoudre ? Voici le code que j'utilise

Classe Image TextArea

public class ImageTextArea extends JTextArea{
    File image;
    public ImageTextArea(File image)
    {
        setOpaque(false);
        this.image=image;
    }

    @Override
    public void paintComponent(final Graphics g)
    {
        try
        {
            // Scale the image to fit by specifying width,height
            g.drawImage(new ImageIcon(image.getAbsolutePath()).getImage(),0,0,getWidth(),getHeight(),this);
            super.paintComponent(g);
        }catch(Exception e){}
    }
}

Et la classe Test

public class TestImageTextArea extends javax.swing.JFrame {

    private ImageTextArea tx;

    public TestImageTextArea() {
        tx = new ImageTextArea(new File("img.jpg"));
        setTitle("this is a jtextarea with image");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        JPanel mainp = new JPanel(new BorderLayout());
        add(mainp);
        mainp.add(new JScrollPane(tx), BorderLayout.CENTER);
        setSize(400, 400);
    }

    public static void main(String args[]) {
/*
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (Exception ex) {
            System.out.println("Unable to use Nimbus LnF: "+ex);
        }
*/
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new TestImageTextArea().setVisible(true);
            }
        });
    }

}

Lorsque je supprime les commentaires, l'image ne se dessine pas.

6voto

MadProgrammer Points 161522

En principe, lorsque vous appelez super.paintComponent il appellera l'interface utilisateur delgate's update méthode. C'est ici que la magie opère.

Vous trouverez ci-dessous la fiche technique du Nimbus SynthTextAreaUI mise en œuvre

public void update(Graphics g, JComponent c) {
    SynthContext context = getContext(c);

    SynthLookAndFeel.update(context, g);
    context.getPainter().paintTextAreaBackground(context,
                      g, 0, 0, c.getWidth(), c.getHeight());
    paint(context, g);
    context.dispose();
}

Comme vous pouvez le voir, il peint l'arrière-plan, sans tenir compte de l'état opaque du composant, puis appelle la fonction paint qui appellera la fonction BasicTextUI.paint (via la méthode super.paint )

C'est important, car BasicTextUI.paint peint effectivement le texte.

En quoi cela nous aide-t-il ? Normalement, j'aurais crucifié quelqu'un pour ne pas avoir appelé super.paintComponent Mais c'est exactement ce que nous allons faire, mais nous allons le faire en sachant à l'avance quelle responsabilité nous prenons.

Tout d'abord, nous allons reprendre les responsabilités de l'Agence européenne pour la sécurité et la santé au travail. update remplir l'arrière-plan, peindre l'arrière-plan et appeler ensuite paint sur le délégué de l'interface utilisateur.

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class NimbusTest {

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

    public NimbusTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(new TestTextArea()));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestTextArea extends JTextArea {

        private BufferedImage bg;

        public TestTextArea() {
            try {
                bg = ImageIO.read(new File("C:\\Users\\swhitehead\\Documents\\My Dropbox\\Ponies\\Rainbow_Dash_flying_past_3_S2E16.png"));
            } catch (IOException ex) {
                Logger.getLogger(NimbusTest.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g.create();
            // Fill the background, this is VERY important
            // fail to do this and you will have major problems
            g2d.setColor(getBackground());
            g2d.fillRect(0, 0, getWidth(), getHeight());
            // Draw the background
            g2d.drawImage(bg, 0, 0, this);
            // Paint the component content, ie the text
            getUI().paint(g2d, this);
            g2d.dispose();
        }

    }
}

Ne vous y trompez pas. Si vous ne le faites pas correctement, vous allez bousiller non seulement ce composant, mais aussi la plupart des autres composants de votre écran.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X