Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在JFrame中组合图像?_Java_Image_Swing_Nested Loops_Jlabel - Fatal编程技术网

Java 如何在JFrame中组合图像?

Java 如何在JFrame中组合图像?,java,image,swing,nested-loops,jlabel,Java,Image,Swing,Nested Loops,Jlabel,我一直在从事一个项目,该项目显示的是一个16 x 16的网格图像,基于用户交互,该网格跟随用户在一个动态较大的基础上(例如,基础为50 x 50),而不是16 x 16的显示。 但是,我使用JLabel组件来显示这些图像,每次用户交互时,我都必须移动256个图像中的每一个,并删除那些不再在16 x 16显示网格中的图像。这会导致每次按键的滞后时间接近1秒,接近于不起作用 我希望尝试做的是将这些图像在地面的总宽度上链接在一起,并简单地将焦点移动到16 x 16网格内的部分,使该过程不再需要使用嵌套

我一直在从事一个项目,该项目显示的是一个16 x 16的网格图像,基于用户交互,该网格跟随用户在一个动态较大的基础上(例如,基础为50 x 50),而不是16 x 16的显示。 但是,我使用
JLabel
组件来显示这些图像,每次用户交互时,我都必须移动256个图像中的每一个,并删除那些不再在16 x 16显示网格中的图像。这会导致每次按键的滞后时间接近1秒,接近于不起作用

我希望尝试做的是将这些图像在地面的总宽度上链接在一起,并简单地将焦点移动到16 x 16网格内的部分,使该过程不再需要使用嵌套for循环进行显示

是否可以使用标签动态存储和创建这些链接图像以供显示?是否有其他方法可以以类似的方式存储和使用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);
    }
  }
}
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-gamestants.USER\u DRAW\u DISTANCE,0);
int maxX=Math.min(地板宽度,pX+GameConstants.USER\u DRAW\u DISTANCE);
int minY=Math.max(pY-gamestants.USER\u DRAW\u DISTANCE,0);
int maxY=Math.min(地板光线,pY+GameConstants.USER\u DRAW\u DISTANCE);
for(int i=minY;i
原则上你的想法应该可行。所以你可能在做别的错事

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

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() );

    }
}
import javax.swing.*;
导入java.awt.EventQueue;
导入java.awt.Dimension;
导入java.awt.Color;
导入java.awt.event.*;
导入java.util.*;
公共类GridViewer{
int x0,y0;
int N=256;
整数显示=16;
整数长度=32;
列表显示=新建ArrayList();
列表可用=新建ArrayList();
JPanel面板=新的JPanel(){
尺寸sz=新尺寸(长度*显示,长度*显示);
@凌驾
公共维度getPreferredSize(){
返回sz;
}
};
公共void showGui(){
JFrame=新JFrame();
panel.setLayout(空);
panel.addMouseMotionListener(新的MouseAdapter(){
随机r=新随机();
@凌驾
public void mouseMoved(MouseEvent evt){
int x=evt.getX();
int y=evt.getY();
//映射到图像上的位置到栅格上的位置。
x0=x/2;
x0=数学最小值(x0,N-显示);
y0=y/2;
y0=数学最小值(y0,N-显示);
updateLayout();
}
});

对于(In i=0;我避免创建和添加新的J标签,而只是改变当前J标签中出现的图像图标。如果您一直在图像文件中读取,请避免这样做,相反,如果可能的话,将您的图像读取到图像图标中并保存一次。为了获得更多的帮助,请考虑用问题来创建和发布程序。压缩
JScrollPane
在这里是合适的。创建一个大的
JPanel
并将所有的
JLabel
放在上面。然后使该
JPanel
成为
JScrollPane
的可滚动客户端,并将
JScrollPane
的首选大小设置为足以显示16x16网格。此外要使用JScrollPane进行滚动,您可以使用带有
GridLayout
的JPanel,您可以将网格配置为自动换行16个图像。请阅读上的Swing教程。不要尝试设置组件的大小/位置。设置大小/位置是布局管理器的工作。另一个选项是使用JList并添加ImageIcons添加到列表。列表也可以配置为换行。本教程还有一节介绍如何使用列表。另一种方法是将图像用作平铺。以下是一个示例。