使用Nimbus外观时无法在JTextArea背景上绘制图像 [英] Can not draw image on JTextArea background when using Nimbus Look And Feel

查看:92
本文介绍了使用Nimbus外观时无法在JTextArea背景上绘制图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在JTextArea背景上绘制图像,它是使用其他外观(金属,Windows等)绘制的,但是当我使用Nimbus外观时,它不会绘制图像.可能是可能的问题,并且如何解决? 这是我正在使用的代码

I am drawing an image on JTextArea background, it is drawn using other look and feels (Metal, Windows etc) but when I use Nimbus Look And Feel it does not draw image What can be the possible problem and how to fix that? Here is the code I am using

图像TextArea类

Image TextArea Class

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){}
    }
}

和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);
            }
        });
    }

}

当我删除评论时,它不会绘制图像.

When I remove the comments it does not draw image.

推荐答案

基本上,当您调用super.paintComponent时,它将调用UI delgate的update方法.这就是魔术发生的地方.

Basically, when you call super.paintComponent, it will call the UI delgate's update method. This is where the magic happens.

以下是Nimbus的SynthTextAreaUI实现

Below is the Nimbus's SynthTextAreaUI implementation

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();
}

如您所见,它实际上是在不考虑组件的不透明状态的情况下绘制背景,然后调用paint,这将调用BasicTextUI.paint方法(通过super.paint)

As you can see, it actually paints the background, with out regard for the opaque state of the component, then calls paint, which will call the BasicTextUI.paint method (via super.paint)

这很重要,因为BasicTextUI.paint实际上是绘制文本.

This is important, as BasicTextUI.paint actually paints the text.

那么,这对我们有什么帮助?通常,我会将没有打电话给super.paintComponent的人钉死在十字架上,但这正是我们要做的事情,但是我们要事先知道我们要承担什么责任来做到这一点.

So, how does that help us? Normally, I'd crucify someone for not calling super.paintComponent, but this is exactly what we're going to do, but we're going to do it knowing in advance what responsibility we're taking on.

首先,我们要接管update的职责,填充背景,绘制背景,然后在UI委托上调用paint.

First, we're going to take over the responsibilities of update, fill the background, paint our background and then call paint on the UI delegate.

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();
        }

    }
}

不要误会.如果操作不正确,它将不仅会拧紧该组件,还会拧紧屏幕上的大多数其他组件.

Make no mistake. If you don't do this right, it will screw not only this component but probably most of the other components on your screen.

这篇关于使用Nimbus外观时无法在JTextArea背景上绘制图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆