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

当我创建 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;

}


我可以过滤问题是由我的按钮类引起的,但我不明白在哪里以及为什么?


有只小跳蛙
浏览 85回答 2
2回答

繁星coding

这是一个从 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.它可能看起来像一个框架。import java.awt.*;import java.awt.image.*;import java.io.IOException;import java.net.*;import javax.swing.*;import javax.imageio.*;public class LotsOfButtons {&nbsp; &nbsp; public final JComponent getUI(int pts) {&nbsp; &nbsp; &nbsp; &nbsp; JComponent ui = new JPanel(new GridLayout(0, pts));&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BufferedImage image = ImageIO.read(new URL(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "https://i.stack.imgur.com/OVOg3.jpg"));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int wT = image.getWidth() / pts;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int hT = image.getHeight() / pts;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Insets insets = new Insets(0, 0, 0, 0);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; long t1 = System.currentTimeMillis();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int jj = 0; jj < pts; jj++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int ii = 0; ii < pts; ii++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int x = ii * wT;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int y = jj * hT;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; JButton b = new JButton(new ImageIcon(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; image.getSubimage(x, y, wT, hT)));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b.setMargin(insets);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ui.add(b);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; long t2 = System.currentTimeMillis();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(String.format(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "It took %1s milliseconds for %1s buttons.",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (t2 - t1), pts*pts));&nbsp; &nbsp; &nbsp; &nbsp; } catch (IOException ex) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ex.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return ui;&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; Runnable r = () -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; JOptionPane.showMessageDialog(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; null, new LotsOfButtons().getUI(10));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; JOptionPane.showMessageDialog(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; null, new LotsOfButtons().getUI(40));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; JOptionPane.showMessageDialog(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; null, new LotsOfButtons().getUI(80));&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; SwingUtilities.invokeLater(r);&nbsp; &nbsp; }}因此,鉴于“(> 30秒)”14 milliseconds附近没有任何地方,我猜您会这样做..不同。除非该源(以上)可以帮助您解决问题,否则我建议准备并发布一个热链接到图像的 MCVE / SSCCE,就像上面的源代码一样,将是解决问题的最佳举措。

UYOU

您的问题可能出在 TileButton 类中:class TileButton extends JButton {&nbsp; &nbsp; private int id;&nbsp; &nbsp; private TileSet ts = new TileSet("Content/Graphics/tileSets/12x12x3 - tileSet.png", 12, 12, 3);&nbsp; &nbsp; private int size = 50;&nbsp; &nbsp; public TileButton(int id, TileSet tileSet) {&nbsp; &nbsp; &nbsp; &nbsp; super();&nbsp; &nbsp; &nbsp; &nbsp; this.ts = tileSet;&nbsp; &nbsp; &nbsp; &nbsp; this.id = id;&nbsp; &nbsp; &nbsp; &nbsp; loadImage(id);&nbsp; &nbsp; }为每个 TileButton 创建新的 TileSet。此图块集从文件中读取 - 这可能会导致相当大的延迟。然后你忽略这个瓦片集并使用在构造函数中传递的瓦片集。因此,您不应该每次都创建新的 TileSet:class TileButton extends JButton {&nbsp; &nbsp; private int id;&nbsp; &nbsp; private final TileSet ts;&nbsp; &nbsp; private int size = 50;&nbsp; &nbsp; public TileButton(int id, TileSet tileSet) {&nbsp; &nbsp; &nbsp; &nbsp; super();&nbsp; &nbsp; &nbsp; &nbsp; this.ts = tileSet;&nbsp; &nbsp; &nbsp; &nbsp; this.id = id;&nbsp; &nbsp; &nbsp; &nbsp; loadImage(id);&nbsp; &nbsp; }
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java