gpt4 book ai didi

java - 尝试使用 GridLayout 在 JPanel 上移动 JLabels

转载 作者:行者123 更新时间:2023-12-02 04:03:51 24 4
gpt4 key购买 nike

我正在尝试让一些 JLabels 在 JPanel 上彼此交换位置,并按下按键上的 GridLayout。

到目前为止:
1. 我只能让它们对鼠标点击使用react。
2. 只能与上面和左边的交换位置。

注意:
1.如果我设置 movePlayer(1) 它就可以工作。并从网格 (8,7) 切换一个 JLabel,其中包含玩家的图像以及其中一个 JLabel 及其上方楼层的图像。然而我的问题是,当我设置 movePlayer(2) 时,它给了我和索引超出范围的异常。
2.这只是我认为与该问题相关的部分代码:

  JPanel myCentrePanel = new JPanel();

MapElement[][] myMap = new MapElement[8][7];



public TileSwitching(){
super("TileSwitching");
setSize(400,400);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
myCentrePanel.setLayout(new GridLayout(8,7));
myCentrePanel.setPreferredSize(new Dimension(5,5));
add(myCentrePanel);
loadMap(level1);
drawMap();
myCentrePanel.setFocusable(true);
myCentrePanel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {

movePlayer(1);
myCentrePanel.removeAll();
drawMap();
myCentrePanel.revalidate();

}
});

myCentrePanel.setBackground(Color.CYAN);
}
public void movePlayer(int dir){

if(dir == 1){

for(int i = 0; i<8; i++){
for(int j= 0; j<7; j++){
if (myMap[i][j].getClass() == wk.getClass()){
myMap[i-1][j] = new Player();
myMap[i][j] = new Floor();
}
else{
myMap[i][j] = myMap[i][j];
}
}}

if(dir == 2){

for(int i = 0; i<8; i++){
for(int j= 0; j<7; j++){
if (myMap[i][j].getClass() == wk.getClass()){
myMap[i+1][j] = new Player();
myMap[i][j] = new Floor();
}
else{
myMap[i][j] = myMap[i][j];
}
}}
}

public static void main(String[] args) {
TileSwitching tl = new TileSwitching();
TileSwitching.setVisible(true);
}

上面代码中未显示的内容:

1. MapElement是许多子类的父类(继承)。
2.loadMap()从字符数组中读出字符(例如 a,b,c...),用 MapElement 子类的新实例填充数组 myMap(例如 new Player(),new Floor(),new Tree() )。

3. drawMap()添加JLabelsJPanel根据类别 myMap[i][j]

4.(这两种方法都是通过双 For 循环 i<8, j<7(来填充
GridLayout(8,7) .

谢谢,对于糟糕的编码和新 watch 示歉意,希望这是清楚的。欢迎提出更好的移动玩家的方法 (JLabel)JPanel上与 GridLayout 。请记住,主要问题是:为什么 (dir == 1)工作和(dir == 2)不是吗?!

最佳答案

我不确定我完全理解你的问题,但是,你可以使用一些技巧来更改组件的渲染顺序,例如,你可以更改 componentZOrder,将更改组件的布局和渲染顺序。

如果您想包含键盘交互,我强烈建议使用 Key Bindings API ,例如...

Move

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class Test {

public static void main(String[] args) {
new Test();
}

public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel {

private JLabel player;
private List<JLabel> tiles;

public TestPane() {
setLayout(new GridLayout(3, 3));
player = makeLabel("P");
add(player);
tiles = new ArrayList<>(8);
for (int index = 0; index < 8; index++) {
JLabel tile = makeLabel(" ");
tiles.add(tile);
add(tile);
}

addKeyBinding("left", KeyEvent.VK_LEFT, new MoveAction(-1, 0));
addKeyBinding("right", KeyEvent.VK_RIGHT, new MoveAction(1, 0));
addKeyBinding("up", KeyEvent.VK_UP, new MoveAction(0, -1));
addKeyBinding("down", KeyEvent.VK_DOWN, new MoveAction(0, 1));
}

protected void addKeyBinding(String name, int keyCode, Action action) {
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = getActionMap();

inputMap.put(KeyStroke.getKeyStroke(keyCode, 0), name);
actionMap.put(name, action);
}

protected JLabel makeLabel(String text) {
JLabel label = new JLabel(text);
label.setBorder(new CompoundBorder(
new LineBorder(Color.GRAY),
new EmptyBorder(4, 4, 4, 4)));
return label;
}

public class MoveAction extends AbstractAction {
private final int xDelta, yDelta;

public MoveAction(int xDelta, int yDelta) {
this.xDelta = xDelta;
this.yDelta = yDelta;
}

@Override
public void actionPerformed(ActionEvent e) {
int index = getComponentZOrder(player);
index += xDelta;
index += (yDelta * 3);
if (index < 0) {
index = 0;
} else if (index >= getComponentCount()) {
index = getComponentCount() - 1;
}
setComponentZOrder(player, index);
revalidate();
repaint();
}

}

}

}

现在,我使用的 Action 可以处理垂直和水平变化,您可能需要考虑使用两个或多个,这可以更好地限制移动,因此如果用户尝试移动到超出开始或行尾,它会限制它们,就目前而言,它允许组件向上或向下流动到下一行

您可能还想查看How to Use Actions

关于java - 尝试使用 GridLayout 在 JPanel 上移动 JLabels,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34585343/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com