gpt4 book ai didi

java - 在 JPanel/JFrame 中动态显示 JLabels

转载 作者:行者123 更新时间:2023-12-02 06:30:01 28 4
gpt4 key购买 nike

我正在尝试以顺序方式显示图像,但在显示时遇到困难(只有最后一个图像显示在屏幕上)。我尝试使用 CardLayout 但由于我的 JLabels(包含 ImageIcon)数量很高,因此它给了我内存不足异常。这是我的代码:

我里面有 JFrame,我有 JPanel,我试图在其中一一显示 JLabel。

    public class ImageMain extends JFrame implements ActionListener{
private static final long serialVersionUID = 2916361361443483318L;
private JFileChooser fc = null;
private JMenuItem item1,item2;
private BufferedImage image = null;
private JPanel panel = null;
private int width = 0;
private int height = 0;
private BorderLayout card;
private Container contentPane;

public ImageMain() {
JFrame frame = new JFrame("Image Extraction Tool");
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = frame.getContentPane();
panel = new JPanel();
card = new BorderLayout();
panel.setLayout(card);
panel.setBackground(Color.white);

JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
menuBar.add(menu);
item1 = new JMenuItem("Browse an image");
item2 = new JMenuItem("Exit");

item1.addActionListener(this);
item2.addActionListener(this);

menu.add(item1);
menu.add(item2);
frame.setJMenuBar(menuBar);

contentPane.add(panel);
frame.pack();
frame.setVisible(true);
}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
ImageMain img = new ImageMain();
}
});
}

@Override
public void actionPerformed(ActionEvent e) {

if(e.getSource() == item1){
if(fc == null)
fc = new JFileChooser();
int retVal = fc.showOpenDialog(null);
if(retVal == JFileChooser.APPROVE_OPTION){
File file = fc.getSelectedFile();
try {
image = ImageIO.read(file);
height = image.getHeight();
width = image.getWidth();

int[][] pixelData = new int[height * width][3];

int[] rgb;

int counter = 0;
for(int i = 0; i < height; i++){
for(int j = 0; j < width; j++){
rgb = getPixelData(image, i, j);

for(int k = 0; k < rgb.length; k++){
pixelData[counter][k] = rgb[k];
}

counter++;
}
}

for(int m=pixelData.length-10; m < pixelData.length; m++){
System.out.println(m);
int[] pix = new int[width*height*3];

for(int i=0;i< width*height*3; i+=3){
pix[i] = pixelData[m][0];
pix[i+1] = pixelData[m][1];
pix[i+2] = pixelData[m][2];
}
JLabel createImageLabel = createImageLabel(pix);
panel.add(createImageLabel);
// panel.revalidate();panel.repaint();
contentPane.revalidate();contentPane.repaint();
Thread.sleep(2000);
}



} catch (IOException e1) {
System.out.println("IO::"+e1.getMessage());
}catch(Exception e1){
System.out.println("Exception::"+e1.getMessage());
}
}
}
if(e.getSource() == item2){
System.exit(0);
}
}


private int[] getPixelData(BufferedImage image, int x, int y) {
int argb = image.getRGB(y, x);

int rgb[] = new int[] {
(argb & 0x00ff0000) >> 16 , //red
(argb & 0x0000ff00) >> 8, //green
argb & 0x000000ff //blue
};

return rgb;
}

private JLabel createImageLabel(int[] pixels){
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
WritableRaster raster = image.getRaster();
raster.setPixels(0, 0, width, height, pixels);
JLabel label = new JLabel(new ImageIcon(image));
return label;
}



}

请指教。

提前致谢。

最佳答案

请检查此站点上有关不在 Swing 事件线程内调用 Thread.sleep(...) 的类似问题和解答。正如他们所说,调用此函数将使您的整个 Swing GUI 进入休眠状态,我确信这不是您的意图。由于您的问题与其他问题没有什么不同,因此解决方案也是相同的:使用 Swing Timer 执行间歇性操作,并使用后台线程(例如由 SwingWorker 生成的线程)执行长时间运行的后台操作(例如读取)在图像中。

此外,如果您所做的只是交换图像,那么一个 JLabel 应该可以正常工作。只需交换 Swing 计时器中显示的 ImageIcon。

<小时/>

编辑
您声明:

I am not sure how to iterate my 2D array with swing Timer, every 2 sec I want to iterate my array and perform some action.

建议:

  • 将计时器延迟 2000(毫秒)
  • 为计时器的 ActionListener 提供一或两个初始化为 0 的 int 计数器字段。
  • 在 actionPerformed 方法中,使用计数器获取感兴趣的项目,然后推进计数器。
  • 阅读Swing Timer Tutorial .

关于java - 在 JPanel/JFrame 中动态显示 JLabels,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20154658/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com