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);
}
更喜欢 paintComponent
。 paint
其实是一个很复杂的方法。有关详细信息,请参阅 Painting in AWT and Swing and Performing Custom Painting
public static int x=0;
是个坏主意,原因有以下三个:
static
不是你的朋友。当您有多个 ButtomPanel
实例时会发生什么?一般来说,当你这样使用static
时,它是一个红旗,告诉你你的设计是错误的。
public
正在提供对 属性 的不受控制的访问。通常不鼓励这样做,您可能更愿意使用 setter 和 getter 与 属性. 进行交互
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);
}
}
}
我想知道为什么 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);
}
更喜欢 paintComponent
。 paint
其实是一个很复杂的方法。有关详细信息,请参阅 Painting in AWT and Swing and Performing Custom Painting
public static int x=0;
是个坏主意,原因有以下三个:
static
不是你的朋友。当您有多个ButtomPanel
实例时会发生什么?一般来说,当你这样使用static
时,它是一个红旗,告诉你你的设计是错误的。public
正在提供对 属性 的不受控制的访问。通常不鼓励这样做,您可能更愿意使用 setter 和 getter 与 属性. 进行交互
JPanel
已经有一个x
属性,这可能会使它变得混乱(即,如果有人使用getX
而不是x
)。最好将其重命名为imageX
ofimageXOffset
.
可运行示例...
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);
}
}
}