如何正确地更新在JLabel的图像?(How to correctly update an Imag

2019-09-17 11:30发布

我是法国人,所以我的英语很糟糕,但我用java一个真正的问题:我试图表现出一些手工生成的映像fillRect &CO。

有用。 接下来,我要更新这个形象,我在文本字段中输入文本的功能。 还有的问题是:它不会改变任何东西,如果我手动重新调整窗口JFrame ,图像显示完全畸形或严重缩放。

我是一个初学者,我有一个GUI困难,moreso当我想用图片夫妇它。

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


我已经改变了这一点,这就是2E版本。

现在暴露出的问题,我不能为了修改一个简单的矩形的颜色发生变化的条件,尝试“笑”在输入字段!

代码版本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);
    }
}

Answer 1:

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

  1. 你是在混淆g与成员变量g的参数paint方法。 当lol叫, gnull ,你会得到一个NullPointerException
  2. 你不应该抢在保持Graphics (只在真正的极少数情况下)。 相反,你正确地重写paintComponent()并使用Graphics参数绘制你想要什么。 当你要更新的组件,你可以调用repaint()
  3. 不要覆盖paint ,但覆盖paintComponent()
  4. 不要覆盖paintJFrame 。 使用组件奉献为。 没必要用一个JLabel为,一个简单JComponent就足够了。
  5. 不要延长JFrame ,如果你不扩展其功能。
  6. 将组件添加到组件层次结构后,调用revalidate()

解决这些问题,并与另一个问题回来,如果你还有问题。

你或许应该考虑阅读本教程和一些后续步骤。 它会告诉你的事情类似于您正在尝试做的基本的例子。

编辑:我把你V2代码,并修补它,因为我可以。 这是远非完美,但你应该得到的你如何能做到这一点要点:

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


Answer 2:

你的挥杆图形编程有几个显著的问题,我劝你去通过教程来学习如何做到这一点更好。 例如,你是

  • 直接调用paint方法 - 你应该几乎从不除非在非常特殊的情况下做的(这是不是其中之一)
  • 直接在Jframe的绘画paint(...)方法。 相反,你会想在画paintComponent(...)从JComponent中衍生而来,例如JPanel的一类方法重写。
  • 调用更新不必要仿佛这是一个AWT程序。 除非你改变了外观和感觉你不是在Swing做到这一点。

再次,看看这个教程 - 你不会后悔这样做,相信我。

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



文章来源: How to correctly update an Image in a JLabel?