从JPanel动态删除对象

时间:2014-11-19 14:49:51

标签: java swing jpanel

通过JSpinner我想从JPanel添加和删除对象“porta”,它可以正常添加,当我只删除一个对象时,如果我尝试删除两个或多个对象它不能正常工作。这是我认为该问题与vector的最后一个元素相关的代码,我在其中添加了对象“porta”:

 import javax.swing.JFrame;

public class PreparaGara extends JFrame {

public JSpinner spinner;
private JPanel panel_1,panel_2;
private int spin;
private int NPorta = 1;
private PortaP scorriPorta,porta;
final Vector<PortaP> vp = new Vector<PortaP>();

/**
 * Launch the application.
 */

/**
 * Create the application.
 */
public PreparaGara() {

    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {

    final JFrame frame = new JFrame();
    frame.setVisible(true);
    frame.setBounds(100, 100, 1000, 400);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(new GridLayout(4, 1, 3, 3));


    JMenuBar menuBar = new JMenuBar();
    frame.getContentPane().add(menuBar);

    JMenu mnGara = new JMenu("Gara");
    mnGara.setFont(new Font("Courier New", Font.BOLD, 30));
    menuBar.add(mnGara);

    panel_1 = new JPanel();
    frame.getContentPane().add(panel_1);
    panel_1.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));

    final JPanel panel_2 = new JPanel();
    frame.getContentPane().add(panel_2);
    panel_2.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));


    JMenuItem mntmPorte = new JMenuItem("Porte");
    mntmPorte.setFont(new Font("Segoe UI", Font.PLAIN, 20));
    mntmPorte.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {


            JLabel lbl = new JLabel();
            lbl.setText("Numero Porte : ");
            panel_1.add(lbl);


            SpinnerNumberModel sm =new SpinnerNumberModel(0,0,30,1);
            final JSpinner spinner = new JSpinner(sm);
            panel_1.add(spinner);       
            spinner.getFocusListeners();
            spin=0;
            panel_1.revalidate();

            spinner.addChangeListener(new ChangeListener() {

                @Override
                public void stateChanged(ChangeEvent arg0) {
                    int ora=(int) spinner.getValue();

                    if(spin<ora && spin<30){

                        porta = new PortaP(NPorta);
                        panel_2.add(porta);
                        NPorta++;
                        vp.add(porta);
                        panel_2.revalidate();


                    }else{
                        //int i = vp.size();
                        panel_2.remove(vp.lastElement());
                        //panel_2.remove(porta);
                        vp.lastElement().remove(porta);                         
                        NPorta=NPorta-1;
                        //System.out.println(i);
                        panel_2.revalidate();
                        panel_2.repaint();
                    }

                spin=ora;
                }});
        }
    });
    mnGara.add(mntmPorte);

    JMenuItem mntmGiudici = new JMenuItem("Giudici");
    mntmGiudici.setFont(new Font("Segoe UI", Font.PLAIN, 20));
    mnGara.add(mntmGiudici);

    JMenu mnDbase = new JMenu("Dbase");
    mnDbase.setFont(new Font("Courier New", Font.BOLD, 30));
    menuBar.add(mnDbase);

    JMenuItem mntmResetPenalit = new JMenuItem("Reset Penalit\u00E0");
    mnDbase.add(mntmResetPenalit);

    JMenuItem mntmResetPorte = new JMenuItem("Reset Porte");
    mnDbase.add(mntmResetPorte);

    JMenuItem mntmRestGiudici = new JMenuItem("Reset Giudici");
    mntmRestGiudici.setActionCommand("Reset Giudici");
    mnDbase.add(mntmRestGiudici);

    JMenu mnReturn = new JMenu("Return");
    mnReturn.setFont(new Font("Courier New", Font.BOLD, 30));
    menuBar.add(mnReturn);

    JMenuItem mntmChiudiMenu = new JMenuItem("Chiudi Menu");
    mnReturn.add(mntmChiudiMenu);






    JPanel panel = new JPanel();
    frame.getContentPane().add(panel);
  }

 }

3 个答案:

答案 0 :(得分:0)

我已经完成了这件事。首先,我建议您要更改的面板部分应该是一个单独的子面板。当发生更新时,在该子面板上调用initialize(),并指出它应包含的内容。因此,您每次更改时都会重建面板。只要确保你没有任何东西抓住旧组件(听众等),否则你会有内存泄漏。

其他人可能有更好的解决方案,但这是我发现的最简洁的解决方案。

答案 1 :(得分:0)

最后我发现了问题是什么,它出现在Vector

                    }else{

                        panel_2.remove(vp.lastElement());
                        // this is the correct instruction:
                        vp.remove(vp.lastElement());

                        NPorta=NPorta-1;

而不是错误的:

                      vp.lastElement().remove(porta);  

答案 2 :(得分:0)

您需要在每次更改时调用重绘。这将确保应用更改。您可以尝试使用LOW_PRIORITY创建一个额外的Thread,它同时与GUI的一个一起工作,并将repaint()和validate()方法调用到您的主框架。

Thread repainter = new Thread(new Runnable() {
@Override
public void run() {
    while (true) { // I recommend setting a condition for your panel being open/visible
        frame.repaint();
        frame.validate();
        try {
            Thread.sleep(30);
        } catch (InterruptedException ignored) {
        }
    }
}
});

repainter.setName("Panel repaint");
repainter.setPriority(Thread.MIN_PRIORITY);
repainter.start();