JPanel Obscures BufferedImage

时间:2011-07-04 06:13:31

标签: java image swing

我无法找到导致以下问题的原因:在使用“extends Frame”创建窗口的程序中,我可以使用BufferedImage绘制到Frame的图形上下文(而不是JFrame) ,它看起来很好。但是,当我声明JPanel时,BufferedImage绘制的所有文本都变得模糊(不完全,但是半透明且难以阅读),即使我没有添加JPanel 1}}到JFrame

以下是代码的简化版本:

import java.awt.*;
import java.awt.event.*;
import javax.swing.Timer;
import java.awt.image.*;
import javax.swing.*;

public class MyProgram extends Frame {

    static Frame f;
    static Timer timer;

    public static void main(String[] args) {

        f = new Frame();
        f.setSize(400, 200);
        f.setResizable(false);
        f.setVisible(true);

        f.addKeyListener(new KeyAdapter() {

        public void keyPressed(KeyEvent e) {

            drawScreen();
        }
    });

    drawScreen();
}

public static void drawScreen() {

    BufferedImage off_i = new BufferedImage(f.getWidth(), f.getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics g = off_i.createGraphics();

    g.setColor(new Color(50, 50, 50));
    g.drawString("Hit any key; why does this text change?", 15, f.getHeight() - 10);

    Graphics off_g = f.getGraphics();
    off_g.drawImage(off_i, 0, 0, null);

    JPanel panel = new JPanel();
    }
}

如果我将JPanel添加到JFrame并且未对其可见性设置任何界限,我可能会理解看到问题出现,但即使创建JPanel也会问题,这对我来说似乎很奇怪。

基本上,我在这里要做的是拿一个我没有JPanel运行的现有程序,并且我想添加JTextArea以便我可以接受复制/粘贴文本以修改程序的显示。

我对Java的理解有点不稳定,因为我主要是通过业余爱好而不是正式学习它,但我总是希望能够学到更多东西。谢谢你的帮助!

更新:我发现只有在声明JPanel之后再次调用draw函数时才会出现此问题,但我仍然不明白为什么会这样做或如何解决它。

4 个答案:

答案 0 :(得分:3)

最好将图片放到JLabelhow ot use Icon

请阅读Using Swing Components以及如何LayoutManagers工作

<{3}}

上的

吨示例

答案 1 :(得分:2)

  1. 不要将AWT组件与Swing组件混合使用。那就是你应该使用JFrame而不是框架。

  2. 不要使用getGraphics()。 Custom Painting是通过覆盖JPanel(或JComponent)的paintComponent()方法完成的。您只需使用传递给该方法的Graphics对象。然后将面板添加到框架中。

  3. 如前所述,使用JLabel更简单,因为您不必进行任何自定义绘制。本教程还有一个关于“如何使用图标”的部分。

答案 2 :(得分:1)

我试图运行你的代码。虽然你所描述的效果不会发生在我的系统上,但我可以向你推荐一些东西。

首先尝试在可视化之前创建面板。在这种情况下,java不必重新排列已经在屏幕上的组件。

其次,如果你在完成后在容器的可见框架调用validate()上绘制东西。这使得java重新安排了东西。

第三,当您使用drawXXX()方法时,创建自己的类,扩展Component,JComponent,Canvas并覆盖其`paint(Graphics)方法。在这种情况下,系统将在每次需要时调用此方法(例如,调整窗口大小时),并再次绘制UI。

BTW我有两个问题:

  1. 为什么使用drawText()代替 Label或JLabel?使用它们 避免这种问题。

  2. 为什么要从Frame扩展你的类并且不使用这个事实但是创建另一个Frame实例?

答案 3 :(得分:1)

作为我原来问题的答案:

似乎初始化 JPanel 和awt draw()命令导致文本被抗锯齿,这使文本看起来更难阅读,部分模糊,更薄等等虽然我尝试使用VALUE_TEXT_ANTIALIAS_OFF的setRenderingHint(),但它没有解决问题。但正如其他海报所指出的那样,将两种成分混合起来并非最佳做法。

虽然这并没有完全解决我的问题,但它确实回答了正在发生什么的问题,即文本抗锯齿是JPanel的一些结果(听起来不错吗?)。理想情况下,我不想重写所有代码只是为了将一个JTextArea添加到已经存在的代码库中。但也许不时会重新审视旧代码并在可能出错的地方进行修改。

感谢大家的评论,信息和资源链接!