Java - 当我想调用它时 Repaint() 不工作

Java -Repaint() not working when i want to call it

我想知道为什么 repiant() 方法没有按预期工作。我的代码:

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

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;

public class RightPanel extends JPanel implements ActionListener{
    JButton buttono;
    JButton buttonu;
    MyFrame frame;
    ButtomPanel s;
    
    public RightPanel(MyFrame frame){
        super();
        this.frame=frame;
         s= new ButtomPanel(frame);
        this.setPreferredSize(new Dimension((frame.getWidth()/3),frame.getHeight()));
        setBackground(Color.green);
        setLayout(new BorderLayout());
        
        buttono = new JButton ("up");
        buttonu = new JButton ("down");
        buttono .addActionListener(this);
        buttonu .addActionListener(this);
        add(buttono , BorderLayout.NORTH);
        add(buttonu , BorderLayout.SOUTH);
        
        setVisible(true);
    }
    


    @Override
    public void actionPerformed(ActionEvent e) {
        
        
        if (e.getSource()==buttono) {
            System.out.println("Up");
        s.x=s.x+10;
        s.repaint();
        
        
    }
}

我想重绘以下 class:

import java.awt.Color;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class ButtomPanel extends JPanel {
    MyFrame frame;

    
     BufferedImage image;
     boolean geklickt=false;
     
     public static int x=0;;
    public ButtomPanel(MyFrame frame) {
        super();
        this.frame=frame;
        this.setPreferredSize(new Dimension(((frame.getWidth()/3)*2),585));     
        setBackground(Color.blue); 
        
        
        
        java.net.URL resource = getClass().getResource("/resources/siegel.jpg");
        try {
            image = ImageIO.read(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
    
        setVisible(true);
        
    }

    public void paint(Graphics g) {
        super.paint(g);       
        g.drawImage(image, 150+x, 150+x, 150, 150, null);}
 
 }
}

我想用 RightPanel 中的 ActionListener Class 更改 BottomPanel Class 中的 x,然后重新绘制它,但它不起作用。我可以提高 x,但是 s.repaint() 不调用 paint-Method。

s 永远不会添加到任何东西,所以它永远不会被绘制。

this.setPreferredSize(new Dimension((frame.getWidth()/3),frame.getHeight())); 是一个非常糟糕的主意。 window 应该符合组件的大小,而不是相反。事实上,以这种方式将 MyFrame 暴露给组件从来没有真正的充分理由,它使这些组件可以控制 MyFrame 他们不应该拥有的。

java.net.URL resource = getClass().getResource("/resources/siegel.jpg");
try {
    image = ImageIO.read(resource);
} catch (IOException e) {
    e.printStackTrace();
}

是个坏主意。 class 应该向使用它的人抛出异常,以便他们知道出了什么问题。这样做不仅会以一种难以追踪的方式消耗错误,而且还会在您调用 g.drawImage(image, 150+x, 150+x, 150, 150, null)

时为您设置 NullPointerException

不要覆盖 paint

public void paint(Graphics g) {
    super.paint(g);       
    g.drawImage(image, 150+x, 150+x, 150, 150, null);
}

更喜欢 paintComponentpaint其实是一个很复杂的方法。有关详细信息,请参阅 Painting in AWT and Swing and Performing Custom Painting

public static int x=0; 是个坏主意,原因有以下三个:

  1. static 不是你的朋友。当您有多个 ButtomPanel 实例时会发生什么?一般来说,当你这样使用static时,它是一个红旗,告诉你你的设计是错误的。
  2. public 正在提供对 属性 的不受控制的访问。通常不鼓励这样做,您可能更愿意使用 setter 和 getter 与 属性.
  3. 进行交互
  4. JPanel 已经有一个 x 属性,这可能会使它变得混乱(即,如果有人使用 getX 而不是 x)。最好将其重命名为 imageX of imageXOffset.

可运行示例...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public final class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.add(new RightPanel());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class RightPanel extends JPanel implements ActionListener {
        JButton buttono;
        JButton buttonu;
        ButtomPanel s;

        public RightPanel() throws IOException {
            super();
            s = new ButtomPanel();
            setBackground(Color.green);
            setLayout(new BorderLayout());

            buttono = new JButton("up");
            buttonu = new JButton("down");
            buttono.addActionListener(this);
            buttonu.addActionListener(this);
            add(buttono, BorderLayout.NORTH);
            add(buttonu, BorderLayout.SOUTH);

            add(s);

            setVisible(true);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == buttono) {
                System.out.println("Up");
                s.addToImageXOffset(10);
            }
        }
    }

    public class ButtomPanel extends JPanel {
        private BufferedImage image;
        private int imageXOffset = 0;

        public ButtomPanel() throws IOException {
            super();
            setBackground(Color.blue);
            image = ImageIO.read(getClass().getResource("/images/Heart.png"));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        public void addToImageXOffset(int delta) {
            setImageXOffset(getImageXOffset() + delta);
        }

        public void setImageXOffset(int imageXOffset) {
            this.imageXOffset = imageXOffset;
            repaint();
        }

        public int getImageXOffset() {
            return imageXOffset;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
            g.drawImage(image, 150 + imageXOffset, 150 + imageXOffset, this);
        }

    }
}