通过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);
}
}
答案 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();