如何正确更新JLabel中的图像?

时间:2012-05-24 22:15:12

标签: java image swing awt jlabel

我是法国人,所以我的英语很糟糕,但我对java有一个真正的问题: 我正在尝试使用一些fillRect&共

有效。接下来,我想根据我在文本字段中输入的文本更新此图像。还有一个问题:它没有改变任何东西,如果我手动重新缩放JFrame的窗口,图像显示完全变形或缩放严重。

我是初学者,我在使用GUI时遇到了困难,当我想将它与图像耦合时,我也会遇到困难。

你能帮帮我吗?为什么它不能按我的意愿工作?这是我下面的代码,有点长但实际上非常简单!谢谢:))


我稍微改了一下,这是2e VERSION。

现在问题是我无法改变条件以修改简单矩形的颜色,在输入字段中尝试“lol”!

CODE VERSION 2

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.ImageIcon;

public class Fenetre extends JFrame {
    private JFrame frame;
    private JPanel container = new JPanel();
    private JTextField jtf;
    private JLabel label = new JLabel("Commandes   ");
    private JButton b = new JButton ("OK");
    private Graphics graph;
    private Image img;
    private JLabel screen;
    private boolean color;

    /**
     * Constructeur de l'objet 
     */
    public Fenetre(){
        color = true;


        frame = new JFrame();
        frame.setTitle("Animation");
        frame.setSize(1000, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        container.setBackground(Color.white);
        container.setLayout(new BorderLayout());


        JPanel top = new JPanel();

        jtf = new JTextField();

        jtf.setPreferredSize(new Dimension(800, 30));

        b.addActionListener(new BoutonListener());

        frame.setContentPane(top);
        frame.setVisible(true); 

        paintComponent(graph);

        screen = new JLabel( new ImageIcon(img));

        top.add(screen);
        top.add(label);
        top.add(jtf);
        top.add(b);

        frame.setContentPane(top);
     }      


    class BoutonListener implements ActionListener{ 
        public void actionPerformed(ActionEvent e) {
                if(jtf.getText().equals("lol")) lol();
                System.out.println("Entry  : " + jtf.getText());
        }  
    }

    public void paintComponent(Graphics g)
    {
        if(img == null) {
            img = frame.createImage(1000,300);
            g = img.getGraphics();
        }
        g.setColor(Color.white);
        g.fillRect(0,0,1000,300);
        if(color) g.setColor(Color.orange); else g.setColor(Color.blue);
        g.fillRect(8,25,200,100);
        g.setColor(Color.green);
        g.drawString("Text",10,10);
    }

    public void lol()
    {
        if(color) color = false; else color = true;
    }
}

以前的代码

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.ImageIcon;

public class Fenetre extends JFrame {

    private JPanel container = new JPanel();
    private JTextField jtf;
    private JLabel label = new JLabel("Commandes   ");
    private JButton b = new JButton ("OK");
    private Graphics g;
    private Image img;
    private JLabel screen;

    /**
     * Constructeur de l'objet 
     */
    public Fenetre(){

        this.setTitle("Animation");
        this.setSize(1000, 400);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);

        container.setBackground(Color.white);
        container.setLayout(new BorderLayout());


        JPanel top = new JPanel();

        jtf = new JTextField();

        jtf.setPreferredSize(new Dimension(800, 30));

        b.addActionListener(new BoutonListener());

        this.setContentPane(top);
        this.setVisible(true); 

        paint(g);

        screen = new JLabel( new ImageIcon(img));

        top.add(screen);
        top.add(label);
        top.add(jtf);
        top.add(b);


        this.setContentPane(top);
     }      


    class BoutonListener implements ActionListener{ 
        public void actionPerformed(ActionEvent e) {
                System.out.println("Entry  : " + jtf.getText());
                if(jtf.getText().equals("lol")) lol();
        }  
    }

    @Override
    public void paint(Graphics g)
    {
        if(img == null) {
            img = createImage(1000,300);
            g = img.getGraphics();
        }
        g.setColor(Color.white);
        g.fillRect(0,0,1000,300);
        g.setColor(Color.orange);
        g.fillRect(8,25,200,100);
        g.setColor(Color.green);
        g.drawString("Text",10,10);
    }

    @Override
    public void update(Graphics g)
    {
        g.setColor(Color.blue);
        g.fillRect(8,25,300,100);
    }

    public void lol()
    {
        g.setColor(Color.blue);
        g.fillRect(8,25,200,100);
    }
}

2 个答案:

答案 0 :(得分:3)

我在您的代码中看到了几个问题:

  1. 您将g成员变量与g方法的paint参数混淆。调用lol后,gnull,您获得NullPointerException
  2. 你永远不应该抓住Graphics(仅在极少数情况下)。相反,您可以正确覆盖paintComponent()并使用Graphics参数绘制所需内容。如果要更新组件,请致电repaint()
  3. 请勿覆盖paint,但应覆盖paintComponent()
  4. 请勿覆盖paint的{​​{1}}。使用专用组件。不需要使用JLabel,简单的JFrame就足够了。
  5. 如果您没有扩展其功能,请不要扩展JComponent
  6. 将组件添加到组件层次结构后,请调用JFrame
  7. 修复这些问题,如果仍有问题,请回复另一个问题。

    您应该考虑阅读this tutorial以及接下来的几个步骤。它将向您展示与您尝试的内容类似的基本示例。

    编辑: 我拿了你的V2代码并尽可能修补它。这远非完美,但您应该了解如何做到这一点:

    revalidate()

答案 1 :(得分:3)

你的Swing图形编程有几个重大问题,我建议你仔细阅读教程,学习如何做得更好。例如,你是

  • 直接调用paint方法 - 除了在非常特殊的情况下(这不是其中之一),你几乎不应该做的事情。
  • 直接在JFrame的paint(...)方法中绘图。相反,您需要绘制从JComponent派生的类的paintComponent(...)方法覆盖,例如JPanel。
  • 不必要地调用更新,就好像这是一个AWT程序。你不要在Swing中这样做,除非你改变了Look&感觉。

再次,看一下这方面的教程 - 你不会后悔这样做,相信我。

编辑 - 太慢了! 1 +到纪尧姆