繁体   English   中英

在JPanel / JFrame中动态显示JLabel

[英]display JLabels dynamically in JPanel/JFrame

我正在尝试以顺序方式显示图像,但是在显示方面有困难(只有最后一张图像显示在屏幕上)。 我尝试使用CardLayout,但因为我的JLabel(包含ImageIcon)的数量很高所以它给了我outofmemory异常。 这是我的代码:

我有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 Timer中显示的ImageIcon。


编辑
你说:

我不知道如何使用swing Timer迭代我的2D数组,每2秒我想迭代我的数组并执行一些操作。

建议:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM