以编程方式在JFrame中交换两个JPanel

我正在努力完成上述function,但收效甚微。 我正在使用带有2列和2行的GridLayout来向用户显示类似拼图的游戏,其中有4个(200×200像素)JPanels(3个彩色,1个默认bgColor),它们填充整个contentPane。 如果面板位于灰色面板旁边,则单击彩色面板将在评估中解析。 如果是这样,他们应该交换。 我完成了最后一步的每一步,他们交换了。 这是代码:

public class MainClass extends JFrame { //Generated private static final long serialVersionUID = 4710628273679698058L; private SpecialPanel redPanel; private SpecialPanel greenPanel; private SpecialPanel yellowPanel; private SpecialPanel grayPanel; public MainClass() { super("Puzzle"); initPanels(); setSize(410, 410); setLayout(new GridLayout(2, 2)); this.add(redPanel); this.add(greenPanel); this.add(grayPanel); this.add(yellowPanel); } private void initPanels() { redPanel = new SpecialPanel(); greenPanel = new SpecialPanel(); yellowPanel = new SpecialPanel(); grayPanel = new SpecialPanel(); grayPanel.setGreyPanel(true); redPanel.setBackground(Color.RED); greenPanel.setBackground(Color.GREEN); yellowPanel.setBackground(Color.YELLOW); grayPanel.setBackground(this.getBackground()); redPanel.setSize(200, 200); greenPanel.setSize(200, 200); yellowPanel.setSize(200, 200); grayPanel.setSize(200, 200); MouseAdapter ma = new MouseAdapter() { @Override public void mouseClicked(MouseEvent arg0) { super.mouseClicked(arg0); SpecialPanel sp = (SpecialPanel) arg0.getComponent(); if (sp.getIsGray()) { //Do nothing } else if (checkIfNeighbourToGray(sp, grayPanel)) { //Swap them System.out.println("Swap notification"); swap(sp, grayPanel); //Update UI } else { //Again, do nothing for the clicked panel is diagonal to the gray panel } } private boolean checkIfNeighbourToGray(SpecialPanel sp, SpecialPanel grayPanel) { Point startPointSp = sp.getLocation(); double x = startPointSp.getX(); double y = startPointSp.getY(); double width = sp.getWidth(); double height = sp.getHeight(); Point grayPoint = grayPanel.getLocation(); double xG = grayPanel.getX(); double yG = grayPanel.getY(); double widthG = grayPanel.getWidth(); double heightG = grayPanel.getHeight(); //Gray panel is RIGHT of clicked one if (x + width == xG && y + height == yG + heightG) { return true; } //Gray panel is LEFT of clicked one else if (x - width == xG && y + height == yG + heightG) { return true; } //Gray panel is ABOVE of clicked one else if (x == xG && x + width == xG + widthG) { return true; } //Gray panel is UNDER of clicked one else if (xG == x && yG + widthG == x + width) { return true; } return false; } private void swap(SpecialPanel sp, SpecialPanel grayPanel) { //Swap logic } }; redPanel.addMouseListener(ma); greenPanel.addMouseListener(ma); yellowPanel.addMouseListener(ma); grayPanel.addMouseListener(ma); } public static void main(String[] args) { MainClass mc = new MainClass(); mc.setVisible(true); } } 

类SpecialPanel正在扩展JPanel,只有一个新的布尔属性IsGrayPanel最初设置为false + getter和setter。 注意:这是以“我有基本的Swing技巧”的方式完成的,虽然我在此期间学到了更多关于java swing的知识,但我当时只是受限于基本的swingfunction,所以我应该保持这种方式。 因此我的问题是如何正确交换彼此相邻的两个面板,包括UI更新?

  • 不需要将JPanels移动到容器中,否则你需要使用大量无用的代码从contianer中删除两个JPanels ,然后使用两个indexes从布局回到具有swaping indexes容器,

  • (如果只是关于Color )只在两个JPanels之间交换setBackground(Color.Xxx)

  • puzzle-like game是关于Images ,拼图或minesweaper的,(不清楚你的…)

    1. Images作为Icon/ImageIcons放到JLabel而不是JPanel并在Mouse Events上切换( setIcon() )使用Icons之间的JLabels ,将Icons加载到局部变量

    2. (最简单的方法) JToggleButton和Icon ,有关于JLabel逻辑类似,但关于在setPressedIcon()上显示Icon

我不确定这是否有效。 看起来太容易了。

 JPanel tempPanel = sp; sp = grayPanel; grayPanel = tempPanel; this.setVisible(false); this.setVisible(true); this.validate(); //try this first this.repaint(); // if it doesnt work, add this function.