English 中文(简体)
如何正确更新 JLabel 中的图像?
原标题:How to correctly update an Image in a JLabel?

I m French so my English is quite bad but I have a real problem with java: I m trying to show an Image built manually with some fillRect & co.

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

我是一个初学者,我对GUI有困难, 更像是我想和图像公司合并的时候。

你能帮我吗?为什么它不能按我的要求工作?这是我下面的代码,有点长,但其实很简单!谢谢。


<强 > 我稍稍改变了一下, 这是 2e VERSION.

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

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

PREVIOUS CODE

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);
    }
}
最佳回答

我看到你的代码里有几个问题:

  1. You are confusing your g member variable with the g parameter of the paint method. When lol is called, g is null and you get a NullPointerException
  2. You should never grab a hold on Graphics (only in really rare cases). Instead you override properly paintComponent() and you use the Graphics parameter to draw what you want. When you want to update the component, you call repaint()
  3. Don t override paint, but override paintComponent()
  4. Don t override paint of JFrame. Use a dedicate component for that. No need to use a JLabel for that, a simple JComponent is enough.
  5. Don t extend JFrame if you are not extending its functionality.
  6. After adding components to the component hierarchy, call revalidate()

解决那些问题,再回答另一个问题 如果你还有问题的话。

您也许应该考虑阅读 < a href=> http://docs.oracle.com/javase/tuative/uiswing/painting/step1.html" rel = “ no follow” > this traitoral 和接下来的几个步骤。 它会向您展示类似您试图做的事情的基本例子 。

EDIT: I took your V2 code and patched it as I could. This is very far from perfect but you should get the gist of how you can do this:

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

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Fenetre extends JComponent {

    private boolean color;

    /**
     * Constructeur de l objet
     */
    public Fenetre() {
        color = true;
        setPreferredSize(new Dimension(1000, 300));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        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;
        }
        repaint();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                initUI();
            }
        });
    }

    protected static void initUI() {
        JFrame frame = new JFrame();
        frame.setTitle("Animation");
        frame.setSize(1000, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        JPanel container = new JPanel();
        final JTextField jtf = new JTextField();
        final Fenetre fenetre = new Fenetre();
        JLabel label = new JLabel("Commandes   ");
        JButton b = new JButton("OK");
        container.setBackground(Color.white);
        container.setLayout(new BorderLayout());

        JPanel top = new JPanel();
        jtf.setPreferredSize(new Dimension(800, 30));
        class BoutonListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (jtf.getText().equals("lol")) {
                    fenetre.lol();
                }
                System.out.println("Entry  : " + jtf.getText());
            }
        }
        b.addActionListener(new BoutonListener());

        top.add(fenetre);
        top.add(label);
        top.add(jtf);
        top.add(b);
        top.revalidate();
        frame.setContentPane(top);
        frame.setVisible(true);
    }
}
问题回答

您的滚动图形编程有几个重大问题,我敦促您通过辅导课程学习如何做得更好。例如,您是

  • calling the paint method directly -- something you should almost never do except in very special situations (this is not one of them)
  • Drawing directly in the JFrame s paint(...) method. Instead you will want to draw in the paintComponent(...) method override of a class derived from JComponent such as JPanel.
  • Calling update unnecessarily as if this were an AWT program. You don t do this in Swing unless you re changing the Look & Feel.

再说一遍,看看这个教程-- 你不会后悔的,相信我。

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





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签