更换面板中的组件而没有结束?

Replacing component in panel without it going to the end?

我正在开发一个在编译时没有错误的程序,并且逻辑运行良好(我正在 GUI 中制作一个基本的 Penny Pitch 程序)。棋盘上充满了图像图标,其中包含玩家登陆时将获得的点数,当他们登陆一个地点时,图像图标应该切换到同一地点的图片,上面有一分钱。但是,当删除前一个图标并分配新的 "occupied" 图标时,它会分配在面板的末尾,而不是之前 "empty" 图标所在的位置。

为了显示: 这是正常的布局, before "tossing" a penny, 这是移动后的布局, after "tossing" a penny。

我找不到任何资源来解释如何将组件添加到面板中以前被移除的组件占据的位置。如果有人知道怎么做,那将是很大的帮助!

--------------------------------编辑-------- ------------------------------

新图片:,

我现在正在使用 GridBagLayout,由于我仍然不确定新添加的组件没有占用已删除组件的 space 的原因是什么,我将整个程序缩减为说明它的方面:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class PennyPitch extends JFrame implements ItemListener{

    //variables
    int aa=0, thrown=0, place=0, illit=1, illit2=1;
    Random pitch = new Random();
    private ImageIcon full = new ImageIcon("pitchFull.png");
    //map
    private Map tossing;
    //jbuttons            
    private JButton confirm = new JButton (new ImageIcon("pitchPenny.png"));  
    //map
    private Map<Integer, ColorPanel> spot = new HashMap<Integer, ColorPanel>();
    //declared icon to use when button is pushed
    private ColorPanel rSet = new ColorPanel(Color.white, full);
    //panel
    private JPanel input = new JPanel(new GridBagLayout ());
    private GridBagConstraints c = new GridBagConstraints();
public PennyPitch(){
    prepareGUI();
    }
public static void main(String[] args){
  PennyPitch pitch = new PennyPitch();      }

private void prepareGUI(){
   //background
    input.setBackground(Color.WHITE);
    //button design
    confirm.setBorder(BorderFactory.createEmptyBorder());
    confirm.setContentAreaFilled(false);
    //icon for use
    ImageIcon one = new ImageIcon("pitchOne.png");
//components for map
    ColorPanel i1 = new ColorPanel(Color.white, one);
    ColorPanel i2 = new ColorPanel(Color.white, one);
    ColorPanel i3 = new ColorPanel(Color.white, one);   

//MAP FOR THE STATS
    spot.put(1, i1);
    spot.put(2, i2);
    spot.put(3, i3);
//PANEL
            c.ipady = 50;
            c.ipadx = 50;
            c.gridx = 1;
            c.gridy = 1;
            c.gridwidth = 1;
        input.add(spot.get(1),c);
            c.ipady = 50;
            c.ipadx = 50;
            c.gridx = 2;
            c.gridy = 1;
            c.gridwidth = 1;
        input.add(spot.get(2),c);
            c.ipady = 50;
            c.ipadx = 50;
            c.gridx = 3;
            c.gridy = 1;
            c.gridwidth = 1;
        input.add(spot.get(3),c);
            c.ipady = 50;
            c.ipadx = 50;
            c.gridx = 4;
            c.gridy = 1;
            c.gridwidth = 2; 
        input.add(confirm,c);

//listener for button        
confirm.addActionListener (new AddListener());

//CONTAINER
Container container = getContentPane();
container.add(input);

//frame information 
    Toolkit tk = Toolkit.getDefaultToolkit();
    setSize(600, 600);
    setTitle("PENNY PITCH");
    setMinimumSize(new Dimension(600,600));
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack ();
    setVisible(true);
}
private class AddListener implements ActionListener {
public void actionPerformed(ActionEvent a){
    if (a.getSource()== confirm) {
                //generates number to land on
                thrown = pitch.nextInt(3) + 1;
                System.out.println(thrown);

            place=illit;
            spot.put(place, rSet);
            Component old = input.getComponent(thrown);
            Component newn = input.getComponent(place);
            Component[] compSet=input.getComponents();
                for(int i=0; i<compSet.length; i++){
                    if(old.equals(compSet[i])) {
                        input.remove(old);
                            c.ipady = 50;
                            c.ipadx = 50;
                            c.gridwidth = 1;
                        input.add(newn, i);
                        }
                }
            illit++;
            repaint();
        }
    }
}   
public void itemStateChanged(ItemEvent e) {
    System.out.println (aa);
}
}
class ImageLabel extends JLabel {
public ImageLabel (String img){
    this (new ImageIcon (img));
}
public ImageLabel (ImageIcon icon){
    setIcon(icon);
    setIconTextGap(0);
    setBorder(null);
    setText(null);
    setSize(icon.getImage().getWidth(null),icon.getImage().getHeight(null));
}
}

容器有一个方法 getComponents()。 JPanel 是一个后代,希望能拥有它。要检查给定的组件,您可以执行以下操作:

Component[] cmp=myPanel.getComponents();
for(int i=0; i<cmp.length; i++)
  if(myComponent.equals(cmp[i])) {
    myPanel.remove(myComponent);
    myPanel.add(myNewComponent, i);
  }

其中 myComponent 是您要删除的组件,myNewComponent 是您要添加的组件。

--

好的,您的代码使用了一些我不熟悉的 ColorPanel,但让我们假设它类似于 JLabel。

我了解到您实际上(在完整代码中)添加了与图像中的硬币一样多的颜色面板。

GridBag 不在我的考虑范围之内——但也许你应该跳过 ipadx 等而只 remove/add。最好使用一些 /normal/ 布局,例如 GridLayout 甚至 FlowLayout 来进行测试。

建议:使用带有 GridLayout(5, 5) 的 JPanel(输入),您可以在其中仅添加颜色面板(数字)。有另一个 JPanel (jp2),您可以在其中添加先前的 JPanel(输入)和按钮(确认)- 此 jp2 已添加到 jframe。您应该 add/remove 输入。

for(i=0; i<25; i++) input.add(new ColorPanel(...));


      thrown = pitch.nextInt(25);
            System.out.println(thrown);

      place=illit;
      spot.put(place, rSet);
      input.remove(thrown);
      Component newn = input.getComponent(place);
      input.add(newn, thrown);

还要确保在每个 removal/addition:

之后调用验证
input.validate();

总而言之,以下是您要执行的操作的简化工作程序:

class T extends Frame {
  public T() {
    setSize(500, 500);
    setLayout(new GridLayout(5, 5));
    for(int i=0; i<25; i++) add(new Label(""+i));
    setVisible(true);
  }
  public static void main(String args[]) {
    T t=new T();
    for(int i=0; i<5; i++) {
      int r=(int)(Math.random()*25);
      t.remove(r);
      t.add(new Label(""+(i+1)), r);
      t.validate();
      t.repaint();
      try { Thread.sleep(5000); } catch(InterruptedException ie) {}
    }
  }
}