Java 如何在JFrame中组合图像?
我一直在从事一个项目,该项目显示的是一个16 x 16的网格图像,基于用户交互,该网格跟随用户在一个动态较大的基础上(例如,基础为50 x 50),而不是16 x 16的显示。 但是,我使用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网格内的部分,使该过程不再需要使用嵌套
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添加到列表。列表也可以配置为换行。本教程还有一节介绍如何使用列表。另一种方法是将图像用作平铺。以下是一个示例。