使用Nimbus外观时无法在JTextArea背景上绘制图像 [英] Can not draw image on JTextArea background when using Nimbus Look And Feel
问题描述
我正在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屋!