Когда я создаю JButton, я получаю очень большую задержку. Вот пример кода того, как я создаю свои кнопки:
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;
}
Распечатка дала мне следующий результат:
It took in total : 9661ms for loading the TileSet (144 Buttons)
It took in total : 13806ms for loading the TileSet (256 Buttons)
It took in total : 27745ms for loading the TileSet (522 Buttons)
После измерения времени создания каждой кнопки вся задержка вызывается кнопками:
It took 30915ms for loading the 521st Button
It took in total : 30979ms for loading the TileSet
Я мог бы отфильтровать, что проблема вызвана моим классом кнопок, но я не понимаю, где и почему?
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);
}
public void loadImage(int imageno) {
this.setBorder(null);
try {
Image img = ts.tileSet[imageno].tileImage;
img = img.getScaledInstance(size, size, Image.SCALE_SMOOTH);
ImageIcon icon = new ImageIcon(img);
this.setIcon(icon);
} catch (Exception e) {
System.out.println("Fehler beim Laden von Bild");
}
}
}
static class TileSet{
private String tileSetImagePath;
private int numberOfTilesX, numberOfTilesY;
private BufferedImage tileSetImage;
public Tile[] tileSet;
private int width = Tile.TILEWIDTH, height = Tile.TILEHEIGHT;
private int border;
public TileSet(String pTileSetImagePath, int pNumberOfTilesX, int pNumberOfTilesY, int pBorder){
tileSetImagePath = pTileSetImagePath;
numberOfTilesX = pNumberOfTilesX;
numberOfTilesY = pNumberOfTilesY;
border = pBorder;
tileSet = new Tile[numberOfTilesX * numberOfTilesY];
createTileSetImages();
}
public void createTileSetImages(){
try {
tileSetImage = ImageIO.read(new File(tileSetImagePath));
width = tileSetImage.getWidth() / numberOfTilesX - border;
height = tileSetImage.getHeight() / numberOfTilesY - border;
} catch (IOException e) {
e.printStackTrace();
}
int i = 0;
for(int y = 0; y < numberOfTilesY; y++) {
for(int x = 0; x < numberOfTilesX; x++) {
BufferedImage bi = tileSetImage.getSubimage(x * (width + border), y * (height + border), width, height);
bi.getScaledInstance(Tile.TILEWIDTH, Tile.TILEHEIGHT, Image.SCALE_SMOOTH);
tileSet[i++] = new Tile(bi);
}
}
}
}
}
class Tile extends JPanel{
public Image tileImage;
public Tile(Image pTileImage) {
super();
setOpaque(true);
tileImage = pTileImage;
}
}
Как предположил Эндрю, возможно, ScaledInstance вызывает задержку. Есть ли другой способ масштабирования изображения без такой большой задержки? РЕДАКТИРОВАТЬ: масштабирование не вызывает задержки: создание одной кнопки с масштабированием занимает 1 мс.
(Извините за длинный код, но он необходим, потому что, если я просто использую (упрощенные) значки и кнопки, это не относится к моей проблеме и, следовательно, не поможет)
После попытки создания кнопок без ScaledInstance задержка все еще существует.