为了账号安全,请及时绑定邮箱和手机立即绑定

创建多个 JButton(数百个)会在创建它们时产生巨大的延迟

创建多个 JButton(数百个)会在创建它们时产生巨大的延迟

有只小跳蛙 2022-10-12 09:59:41
当我创建 JButtons 时,我得到了很大的延迟。这是我如何创建按钮的一些示例代码:import javax.imageio.ImageIO;import javax.swing.*;import java.awt.*;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;public class Scratch {public static void main(String[] args) {    Runnable r = () -> {        JOptionPane.showMessageDialog(                null, new Scratch().getUI(new TileSet("Content/Graphics/tileSets/12x12x3 - tileSet.png", 12, 12, 3)));        JOptionPane.showMessageDialog(                null, new Scratch().getUI(new TileSet("Content/Graphics/tileSets/16x16x0 - tileSetItems.png", 12, 12, 3)));        JOptionPane.showMessageDialog(                null, new Scratch().getUI(new TileSet("Content/Graphics/tileSets/29x18x1 - roguelikeDungeon_transparent.png", 12, 12, 3)));    };    SwingUtilities.invokeLater(r);}public final JComponent getUI(TileSet tileSet) {    JPanel ui = new JPanel();    JPanel tilePanel = new JPanel();    tilePanel.setLayout(new GridLayout(12, 12, 5, 5));    long t1 = System.currentTimeMillis();    TileButton tileMenuButtons[] = new TileButton[tileSet.tileSet.length];    long tot = 0;    for (int i = 0; i < tileMenuButtons.length; i++) {        long t2 = System.currentTimeMillis();        tileMenuButtons[i] = new TileButton(i,tileSet);        long t3 = System.currentTimeMillis();        tot += (t3-t2);        System.out.println(String.format("It took : "+ tot +"ms for loading "+i+ ". Button "));        tilePanel.add(tileMenuButtons[i]);    }    long t4 = System.currentTimeMillis();    JScrollPane scrollPane = new JScrollPane();    scrollPane.getVerticalScrollBar().setUnitIncrement(16);    scrollPane.setOpaque(true);    scrollPane.setViewportView(tilePanel);    ui.add(scrollPane);    System.out.println(String.format("It took in total : "+ (t4-t1) +"ms for loading "+tileMenuButtons.length+ " TileButtons"));    return ui;}我可以过滤问题是由我的按钮类引起的,但我不明白在哪里以及为什么?
查看完整描述

2 回答

?
繁星coding

TA贡献1797条经验 获得超4个赞

这是一个从 100 个按钮到6,400个按钮添加到 GUI 的 MCVE / SSCCE ,每个按钮都有自己的图标。


这里的典型输出:


It took 14 milliseconds for 100 buttons.

It took 110 milliseconds for 1600 buttons.

It took 138 milliseconds for 6400 buttons.

它可能看起来像一个框架。

//img1.sycdn.imooc.com//63461fbd00013cd105370408.jpg

import java.awt.*;

import java.awt.image.*;

import java.io.IOException;

import java.net.*;

import javax.swing.*;

import javax.imageio.*;


public class LotsOfButtons {


    public final JComponent getUI(int pts) {

        JComponent ui = new JPanel(new GridLayout(0, pts));

        try {

            BufferedImage image = ImageIO.read(new URL(

                    "https://i.stack.imgur.com/OVOg3.jpg"));


            int wT = image.getWidth() / pts;

            int hT = image.getHeight() / pts;

            Insets insets = new Insets(0, 0, 0, 0);


            long t1 = System.currentTimeMillis();

            for (int jj = 0; jj < pts; jj++) {

                for (int ii = 0; ii < pts; ii++) {

                    int x = ii * wT;

                    int y = jj * hT;

                    JButton b = new JButton(new ImageIcon(

                            image.getSubimage(x, y, wT, hT)));

                    b.setMargin(insets);

                    ui.add(b);

                }

            }

            long t2 = System.currentTimeMillis();


            System.out.println(String.format(

                    "It took %1s milliseconds for %1s buttons.",

                    (t2 - t1), pts*pts));

        } catch (IOException ex) {

            ex.printStackTrace();

        }

        return ui;

    }


    public static void main(String[] args) {

        Runnable r = () -> {

            JOptionPane.showMessageDialog(

                    null, new LotsOfButtons().getUI(10));

            JOptionPane.showMessageDialog(

                    null, new LotsOfButtons().getUI(40));

            JOptionPane.showMessageDialog(

                    null, new LotsOfButtons().getUI(80));

        };

        SwingUtilities.invokeLater(r);

    }

}

因此,鉴于“(> 30秒)”14 milliseconds附近没有任何地方,我猜您会这样做..不同。除非该源(以上)可以帮助您解决问题,否则我建议准备并发布一个热链接到图像的 MCVE / SSCCE,就像上面的源代码一样,将是解决问题的最佳举措。


查看完整回答
反对 回复 2022-10-12
?
UYOU

TA贡献1878条经验 获得超4个赞

您的问题可能出在 TileButton 类中:


class TileButton extends JButton {

    private int id;

    private TileSet ts = new TileSet("Content/Graphics/tileSets/12x12x3 - tileSet.png", 12, 12, 3);

    private int size = 50;

    public TileButton(int id, TileSet tileSet) {

        super();

        this.ts = tileSet;

        this.id = id;

        loadImage(id);

    }

为每个 TileButton 创建新的 TileSet。此图块集从文件中读取 - 这可能会导致相当大的延迟。然后你忽略这个瓦片集并使用在构造函数中传递的瓦片集。


因此,您不应该每次都创建新的 TileSet:


class TileButton extends JButton {

    private int id;

    private final TileSet ts;

    private int size = 50;

    public TileButton(int id, TileSet tileSet) {

        super();

        this.ts = tileSet;

        this.id = id;

        loadImage(id);

    }


查看完整回答
反对 回复 2022-10-12
  • 2 回答
  • 0 关注
  • 84 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信