2

我是法国人,所以我的英语很糟糕,但我对 java 有一个真正的问题:我正在尝试显示一个使用 some fillRect& co 手动构建的图像。

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

我是一个初学者,我在使用 GUI 时遇到了困难,所以当我想将它与图像结合时。

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


我已经改变了一点,这是 2e VERSION。

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

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

2 回答 2

3

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

  1. 您将g成员变量与方法的g参数混淆了paint。当lol被调用时,gnull会得到一个NullPointerException
  2. 你永远不应该抓住Graphics(仅在非常罕见的情况下)。相反,您可以正确覆盖paintComponent()并使用Graphics参数来绘制您想要的内容。当你想更新组件时,你调用repaint()
  3. 不要覆盖paint,而是覆盖paintComponent()
  4. 不要覆盖paint. JFrame为此使用专用组件。不需要为此使用 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);
    }
}
于 2012-05-24T23:13:02.200 回答
3

您的 Swing 图形编程有几个重大问题,我强烈建议您阅读教程以了解如何更好地做到这一点。例如,你是

  • 直接调用paint方法——除非在非常特殊的情况下,你几乎不应该这样做(这不是其中之一)
  • 直接在 JFrame 的paint(...)方法中绘制。相反,您将希望绘制paintComponent(...)从 JComponent 派生的类(例如 JPanel)的方法覆盖。
  • 不必要地调用更新,就好像这是一个 AWT 程序。除非您更改外观和感觉,否则不要在 Swing 中执行此操作。

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

编辑——太慢了!1+ 给纪尧姆

于 2012-05-24T23:14:43.370 回答