我正在为测试目的创建一个简单的应用程序,它分别显示几个JFrame,每个都包含一个图像。
问题在于它根据列表中的图像数显示了预期的JFrame数,但只有最后一个显示图像。所有其他的都是空的。
我已经进行了调试,并检查Buffered Image
列表是否完全符合预期,所有对象都在那里,并且它们是彼此的副本,因为它是一个测试。
repaint
调用(已经在各种地方尝试过)或ImgPanel
子类有什么问题吗?这是我对可能出错的唯一猜测。
public class Main() extends JFrame{
BufferedImage I;
public void show(ArrayList<BufferedImage> images){
int i = 0;
for(BufferedImage b : images){
this.I = b;
Container c = getContentPane();
c.setLayout(null);
c.add(new ImgPanel());
JFrame frame = new JFrame();
frame.validate();
frame.repaint();
frame.setTitle("Execution: "+i);
frame.getContentPane().add(c);
frame.setSize(800,600);
frame.setVisible(true);
i++;
}
}
public class ImgPanel extends JPanel {
public imgPanel() {
setBounds(0, 0, 800,600);
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(I, 0, 0, this);
}
}
public static void main(String[] args){
//"d" is an Object Already declared
ArrayList<BufferedImage> images = d.getImages();
Main m = new Main();
m.show(images);
}
}
答案 0 :(得分:4)
由于您的代码无法编译,我不确定问题出在哪里。此代码可靠地工作(坚如磐石)。在此GUI中,我倾向于将ImgPanel
替换为JLabel
,YMMV。
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import java.net.URL;
public class Main {
public void show(ArrayList<BufferedImage> images){
int i = 0;
for(BufferedImage b : images){
JFrame frame = new JFrame("Execution: "+i);
frame.add(new ImgPanel(b));
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.setVisible(true);
i++;
}
}
public class ImgPanel extends JPanel {
BufferedImage i;
public ImgPanel(BufferedImage image) {
i = image;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(i.getWidth(), i.getHeight());
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(i, 0, 0, this);
}
}
public static void main(String[] args) throws Exception {
final ArrayList<BufferedImage> images = new ArrayList<BufferedImage>();
String[] urlStrings = {
"http://i.stack.imgur.com/XZ4V5.jpg",
"http://i.stack.imgur.com/7bI1Y.jpg",
"http://i.stack.imgur.com/OVOg3.jpg",
"http://i.stack.imgur.com/lxthA.jpg"
};
for (String s : urlStrings) {
URL url = new URL(s);
BufferedImage bi = ImageIO.read(url);
images.add(bi);
}
Runnable r = new Runnable() {
public void run() {
Main m = new Main();
m.show(images);
}
};
SwingUtilities.invokeLater(r);
}
}
答案 1 :(得分:4)
根据您的,不完整的代码示例和问题描述,我建议问题与您尝试将组件的单个实例添加到多个容器有关,例如......
Container c = getContentPane();
c.setLayout(null);
c.add(new ImgPanel());
//...
frame.getContentPane().add(c);
一个组件只能驻留在一个容器中,当一个组件被添加到一个新容器时,它首先从它的当前容器中移除(如果它有一个父容器)。
您可以通过将ImgPanel
背景颜色设置为其他内容来测试,例如setBackgroundColor(Color.RED)
,唯一显示为红色的帧应该是最后一个...
null
布局,在这种特定情况下,您可能不会考虑边框框架,这意味着内容区域将扩展到框架的可视区域之外。框架边框在不同的外观和感觉/平台上也有不同的尺寸paintComponent
使用paint
而不是JLabel
因为它可以减少怪异的风险,并可能打破油漆链答案 2 :(得分:1)
使用JPanel时,请使用paintComponent(Graphics)
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
}