我正在编写一个程序,在编译时没有错误,逻辑运行正常(我在GUI中制作一个基本的Penny Pitch程序)。该板上装有图像图标,其中包含玩家落在其上的点数,当他们落在一个点上时,图像图标可以切换到同一点的图片,上面有一分钱。但是,当删除前一个图标并分配新的“已占用”图标时,会在面板的末尾分配它,而不是从前一个位置分配“空”图标。
为了显示: 这是正常的布局, before "tossing" a penny, 这是转移的布局, after "tossing" a penny。
我找不到任何解释如何将组件添加到先前由已删除组件占用的点中的面板的源。如果有人知道如何,那将是很大的帮助!
----------------------------------- EDIT ----------- ------------------------------
我现在正在使用GridBagLayout,因为我仍然不确定新添加的组件的原因是什么不占用已删除的空间,我减少了整个程序以说明它的方面:
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));
}
}
答案 0 :(得分:0)
Container有一个方法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等,只需删除/添加即可。更好的是使用一些/普通/布局,例如GridLayout甚至FlowLayout用于测试目的。
建议:使用带有GridLayout(5,5)的JPanel(输入),只添加颜色面板(数字)。有另一个JPanel(jp2),你添加以前的JPanel(输入)和按钮(确认) - 这个jp2被添加到jframe。您应该在输入上添加/删除。
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);
还要确保在每次删除/添加后调用validate:
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) {}
}
}
}