如何在JFrame中合并图像?

问题描述 投票:1回答:1

我一直在研究一个显示16 x 16图像网格的项目,基于用户交互,该网格在比16动态更大的基础上跟随用户(例如,基础是50 x 50) x 16显示屏。但是,我使用JLabel组件显示这些图像,并且每次用户互动时,我都必须移动256个图像中的每一个并擦除不再位于16 x 16显示网格中的图像。这导致每次按键接近一秒钟的延迟,并且接近无功能。

[我正在尝试做的是将这些图像在地面的整个宽度上链接在一起,然后将焦点简单地移到16 x 16网格内的部分,从而使该过程不再需要使用嵌套循环显示。

是否可以动态存储和创建这些链接的图像以使用标签显示?如果还有其他方法可以显示Java中的.png文件,这些文件可以以类似的方式存储和使用?

我当前必须在每次用户交互时绘制每张图像的方法的一个示例:

User user = game.user;

int floorWidth = game.floorWidth;
int floorHeight = game.floorHeight;

int pX = user.getTile().getX();
int pY = user.getTile().getY();

int minX = Math.max(pX - GameConstants.USER_DRAW_DISTANCE, 0);
int maxX = Math.min(floorWidth, pX + GameConstants.USER_DRAW_DISTANCE);

int minY = Math.max(pY - GameConstants.USER_DRAW_DISTANCE, 0);
int maxY = Math.min(floorHeight, pY + GameConstants.USER_DRAW_DISTANCE);
for (int i = minY; i < maxY; i++)
{
  for (int x = minX; x < maxX; x++)
  {
    Tile tile = floor.getTile(x, i);
    if (tile.getHasSeen())
    {
      JLabel cLabel = tile.imageLabel;
      cLabel.setLocation(340 + x * 32, 140 + i * 32);
      cLabel.setSize(64, 64);
      cLabel.setVisible(true);
      panel.add(cLabel, 1);
    }
  }
}
java image swing nested-loops jlabel
1个回答
1
投票

原则上,您的想法应该可行。因此,您可能正在做其他错误的事情。

我已经举了一个例子,其中显示了256x256 JLabel中的16x16正方形JLabel。将鼠标移到面板上时,它会更改布局以显示一组新的16x16 JLabel。更改非常快捷,绝对不会延迟1秒。

import javax.swing.*;
import java.awt.EventQueue;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.event.*;
import java.util.*;

public class GridViewer{
    int x0, y0;
    int N = 256;
    int display = 16;
    int length = 32;
    List<JLabel> showing = new ArrayList<>();
    List<JLabel> available = new ArrayList<>();
    JPanel panel = new JPanel(){
        Dimension sz = new Dimension(length*display, length*display);
        @Override
        public Dimension getPreferredSize(){
            return sz;
        }
    };
    public void showGui(){
        JFrame frame = new JFrame();
        panel.setLayout(null);

        panel.addMouseMotionListener( new MouseAdapter(){
            Random r = new Random();
            @Override
            public void mouseMoved(MouseEvent evt){
                int x = evt.getX();
                int y = evt.getY();
                //map to position on the image to the position on the grid.
                x0 = x/2;
                x0 = Math.min(x0, N-display);

                y0 = y/2;
                y0 = Math.min(y0, N-display);
                updateLayout();
            }
        });

        for(int i = 0; i<N*N; i++){
            available.add(createItem(i));
        }

        updateLayout();

        frame.setContentPane(panel);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
    /**
     * Creates a solid color jlabel, could be used to load an image
     * as an icon.
     **/
    JLabel createItem(int i){
        JLabel l = new JLabel("");
        int r = (i/256);
        int g = (0)&255;
        int b = (i%256);
        int c = (r << 16 ) + ( g << 8 ) + b;
        l.setBackground(new Color(c));
        l.setOpaque(true);
        l.setSize(length, length);

        return l;
    }
    public void updateLayout(){
        for(JLabel l: showing){
            panel.remove(l);
        }

        for(int i = 0; i<display; i++){
            for(int j = 0; j<display; j++){
                JLabel l = available.get((i + x0) + (j+y0)*N);
                panel.add(l);
                l.setLocation( i*length, j*length);
                showing.add(l);
            }
        }        
    }
    public static void main(String[] args){
        EventQueue.invokeLater( () -> new GridViewer().showGui() );

    }
}

一些变化。

使用GridLayout

使用布局管理器有很多优点。特别是在使用不同的显示器,字体和平台时?添加和删​​除元素时,可能会使部分显示元素变得困难。

使用带有ScrollPane的大型JPanel

我们可以创建一个JPanel并向其中添加所有256x256组件,然后使用滚动窗格设置视图。这将具有将布局和视图完全分离的优势。有人想要一个更大的窗口,您不必更改布局,视图变大,您可以看到更多的布局。对于256x256的组件,它应该表现良好,但是如果组件太多,则可能需要重新考虑。

使用JPanel并覆盖paintComponent

[这将涉及将'png'文件作为awt Image(可能是BufferedImage s)加载,并使用图形对象进行绘制。您将需要处理所有布局和渲染。它为您提供了呈现组件的强大功能。

© www.soinside.com 2019 - 2024. All rights reserved.