JPanel 添加到 JFrame 后如何更改?
How can a JPanel be changed after added to JFrame?
我创建了一个 JPanel 的子类来显示图像。我在 JFrame 的构造函数中实例化它并将其添加到该 JFrame。这非常有效。然后我添加了一个带有 ActionListener 的按钮来更改该图像。我的问题是 JFrame 不会更新,尽管我已经尝试重新绘制等
JPanel的子类:
public class ImagePanel extends JPanel {
BufferedImage bf;
public ImagePanel(String dateiname)
{
try {
bf = ImageIO.read(new File(dateiname));
} catch (IOException e) {
e.printStackTrace();
}
}
public void paint(Graphics g)
{
g.drawImage(bf.getScaledInstance(300,200,1),0,0,null );
}
}
JFrame基本就是这样
public class Hauptfenster extends JFrame {
private JButton changeImage;
private JPanel buttonPanel;
private ImagePanel ip;
public Hauptfenster {
ip = new ImagePanel("first_image.jpg");
buttonPanel = new JPanel();
buttonPanel.add(changeImage);
changeImage.addActionListener((e) -> {
ip = new ImagePanel("new_image.jpg");
ip.setVisible(true);
});
this.add(buttonPanel);
this.add(ip);
this.setVisible(true);
}
}
为什么 ActionListener 中的方法不更新 JFrame Hauptfenster 中的 ip 组件?
当您执行 ip = new ImagePanel("new_image.jpg");
时,您正在创建一个与当前布局无关的全新 ImagePanel。你可以。
remove(ip);
ip = new ImagePanel("new_image.jpg");
add(ip);
repaint();
另一种方法是只更改缓冲图像。
将以下方法添加到您的图像面板。
public void loadImage(String dateiname) {
try {
bf = ImageIO.read(new File(dateiname));
} catch (IOException e) {
e.printStackTrace();
}
}
然后在你的动作侦听器中。
ip.loadNewImage("new_image.jpg");
ip.repaint();
虽然你的代码中有很多坏习惯。
例如,覆盖 paintComponent 而不是 paint,它应该看起来像。
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(bf.getScaledInstance(300,200,1),0,0,null );
}
这样透明度将得到正确处理。
您不应该扩展 JFrame,您应该只创建一个 JFrame。
添加组件时,会涉及布局管理器。意识到这一点并相应地处理事情是很好的。我会将您的构造函数更改为。
public Hauptfenster() {
JFrame frame = new JFrame();
ip = new ImagePanel("first_image.jpg");
buttonPanel = new JPanel();
changeImage = new JButton("change image");
buttonPanel.add(changeImage);
changeImage.addActionListener((e) -> {
frame.remove(ip);
ip = new ImagePanel("new_image.jpg");
frame.add(ip, BorderLayout.CENTER);
frame.repaint();
});
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.add(ip, BorderLayout.CENTER);
frame.setVisible(true);
}
如果您需要更多帮助,您需要实际使您的示例可编译。目前错误太多。
我创建了一个 JPanel 的子类来显示图像。我在 JFrame 的构造函数中实例化它并将其添加到该 JFrame。这非常有效。然后我添加了一个带有 ActionListener 的按钮来更改该图像。我的问题是 JFrame 不会更新,尽管我已经尝试重新绘制等
JPanel的子类:
public class ImagePanel extends JPanel {
BufferedImage bf;
public ImagePanel(String dateiname)
{
try {
bf = ImageIO.read(new File(dateiname));
} catch (IOException e) {
e.printStackTrace();
}
}
public void paint(Graphics g)
{
g.drawImage(bf.getScaledInstance(300,200,1),0,0,null );
}
}
JFrame基本就是这样
public class Hauptfenster extends JFrame {
private JButton changeImage;
private JPanel buttonPanel;
private ImagePanel ip;
public Hauptfenster {
ip = new ImagePanel("first_image.jpg");
buttonPanel = new JPanel();
buttonPanel.add(changeImage);
changeImage.addActionListener((e) -> {
ip = new ImagePanel("new_image.jpg");
ip.setVisible(true);
});
this.add(buttonPanel);
this.add(ip);
this.setVisible(true);
}
}
为什么 ActionListener 中的方法不更新 JFrame Hauptfenster 中的 ip 组件?
当您执行 ip = new ImagePanel("new_image.jpg");
时,您正在创建一个与当前布局无关的全新 ImagePanel。你可以。
remove(ip);
ip = new ImagePanel("new_image.jpg");
add(ip);
repaint();
另一种方法是只更改缓冲图像。
将以下方法添加到您的图像面板。
public void loadImage(String dateiname) {
try {
bf = ImageIO.read(new File(dateiname));
} catch (IOException e) {
e.printStackTrace();
}
}
然后在你的动作侦听器中。
ip.loadNewImage("new_image.jpg");
ip.repaint();
虽然你的代码中有很多坏习惯。
例如,覆盖 paintComponent 而不是 paint,它应该看起来像。
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(bf.getScaledInstance(300,200,1),0,0,null );
}
这样透明度将得到正确处理。
您不应该扩展 JFrame,您应该只创建一个 JFrame。
添加组件时,会涉及布局管理器。意识到这一点并相应地处理事情是很好的。我会将您的构造函数更改为。
public Hauptfenster() {
JFrame frame = new JFrame();
ip = new ImagePanel("first_image.jpg");
buttonPanel = new JPanel();
changeImage = new JButton("change image");
buttonPanel.add(changeImage);
changeImage.addActionListener((e) -> {
frame.remove(ip);
ip = new ImagePanel("new_image.jpg");
frame.add(ip, BorderLayout.CENTER);
frame.repaint();
});
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.add(ip, BorderLayout.CENTER);
frame.setVisible(true);
}
如果您需要更多帮助,您需要实际使您的示例可编译。目前错误太多。