Swing - nie rozwija się jComboBox na nowym panelu

0

Cześć.
Nie potrafię sobie poradzić z następującym problemem. Piszę aplikację SWING, która posiada główny JFrame i który ma mieć możliwość wywoływania różnych JPanel w zależności od wybranej akcji. Każdy nowy JPanel będzie umieszczany w tym JFrame. Niestety mam problem, który objawia się w momencie kiedy wywoływany jest JPanel, na którym znajduje się JComboBox. Ten JComboBox mimo iż ma kilka wpisów nie rozwija się. Może wam coś przyjdzie do głowy czemu ta lista się nie rozwija. A może problem leży w wywoływaniu nowego JPanel. Oto kody. Aplikacja pisana w NetBeans więc jest sporo nadmiarowego kodu:


import java.awt.Component;
import javax.swing.JRootPane;

/**
 *
 *
 */
public class MainFrame extends javax.swing.JFrame {

	/**
	 * Creates new form NewJFrame
	 */
	public MainFrame() {
		initComponents();
	}

	/**
	 * This method is called from within the constructor to initialize the
	 * form. WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
        private void initComponents() {

                jPanel1 = new javax.swing.JPanel();
                jButton1 = new javax.swing.JButton();
                jPanel2 = new javax.swing.JPanel();

                setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

                jPanel1.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));

                jButton1.setText("jButton1");
                jButton1.addActionListener(new java.awt.event.ActionListener() {
                        public void actionPerformed(java.awt.event.ActionEvent evt) {
                                jButton1ActionPerformed(evt);
                        }
                });

                javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
                jPanel1.setLayout(jPanel1Layout);
                jPanel1Layout.setHorizontalGroup(
                        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel1Layout.createSequentialGroup()
                                .addGap(21, 21, 21)
                                .addComponent(jButton1)
                                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                );
                jPanel1Layout.setVerticalGroup(
                        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel1Layout.createSequentialGroup()
                                .addGap(22, 22, 22)
                                .addComponent(jButton1)
                                .addContainerGap(83, Short.MAX_VALUE))
                );

                jPanel2.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));

                javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
                jPanel2.setLayout(jPanel2Layout);
                jPanel2Layout.setHorizontalGroup(
                        jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGap(0, 386, Short.MAX_VALUE)
                );
                jPanel2Layout.setVerticalGroup(
                        jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGap(0, 142, Short.MAX_VALUE)
                );

                javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
                getContentPane().setLayout(layout);
                layout.setHorizontalGroup(
                        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(layout.createSequentialGroup()
                                .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addContainerGap())
                );
                layout.setVerticalGroup(
                        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addContainerGap())
                );

                pack();
        }// </editor-fold>                        

        private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
		// TODO add your handling code here:
		JRootPane rootPane = this.getRootPane();
		Panel2 panel = new Panel2();

		//czyszczenie ekranu z komponentow
		Component[] components = rootPane.getComponents();
		for (Component c : components) {
			c.setVisible(false);
		}
		rootPane.add(panel);
		panel.setVisible(true);
		panel.setBounds(0, 0, 200, 200);
        }                                        

	/**
	 * @param args the command line arguments
	 */
	public static void main(String args[]) {
		/* Set the Nimbus look and feel */
		//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
		/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
		 */
		try {
			for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
				if ("Nimbus".equals(info.getName())) {
					javax.swing.UIManager.setLookAndFeel(info.getClassName());
					break;
				}
			}
		} catch (ClassNotFoundException ex) {
			java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		} catch (InstantiationException ex) {
			java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		} catch (IllegalAccessException ex) {
			java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		} catch (javax.swing.UnsupportedLookAndFeelException ex) {
			java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		}
		//</editor-fold>
		//</editor-fold>

		/* Create and display the form */
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				new MainFrame().setVisible(true);
			}
		});
	}

        // Variables declaration - do not modify                     
        private javax.swing.JButton jButton1;
        private javax.swing.JPanel jPanel1;
        private javax.swing.JPanel jPanel2;
        // End of variables declaration                   
}
public class Panel2 extends javax.swing.JPanel {

	/**
	 * Creates new form NewJPanel
	 */
	public Panel2() {
		initComponents();
		jComboBox2.setVisible(true);
	}

	/**
	 * This method is called from within the constructor to initialize the
	 * form. WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
        private void initComponents() {

                jComboBox1 = new javax.swing.JComboBox<>();
                jLabel1 = new javax.swing.JLabel();
                jComboBox2 = new javax.swing.JComboBox<>();

                jComboBox1.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

                jLabel1.setText("Panel 2");

                jComboBox2.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

                javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
                this.setLayout(layout);
                layout.setHorizontalGroup(
                        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addGroup(layout.createSequentialGroup()
                                                .addGap(45, 45, 45)
                                                .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                                        .addGroup(layout.createSequentialGroup()
                                                .addGap(31, 31, 31)
                                                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 141, javax.swing.GroupLayout.PREFERRED_SIZE)))
                                .addContainerGap(329, Short.MAX_VALUE))
                );
                layout.setVerticalGroup(
                        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                                .addGap(42, 42, 42)
                                .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(18, 18, 18)
                                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 153, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addContainerGap(67, Short.MAX_VALUE))
                );
        }// </editor-fold>                        


        // Variables declaration - do not modify                     
        private javax.swing.JComboBox<String> jComboBox1;
        private javax.swing.JComboBox<String> jComboBox2;
        private javax.swing.JLabel jLabel1;
        // End of variables declaration                   
}
0

Populujesz model.
Potrzebujesz jeszcze chyba edytora.
Taka moja pierwsza myśl, jak wrócę z pracy do domu, to sprawdzę.
Nie mam żadnej swojej apki swingowej pod ręką

0

Hej.
Metodą eliminacji:
Problemem jest to:

        Component[] components = rootPane.getComponents();
        for (Component c : components) {
            c.setVisible(false);
        }

Po usunięciu tego fragmentu działa - co prawda wyświetla box pod buttonem, ale działa.
Coś pewnie chramoli się w wątkach AWT.

Ja bym spróbował najpierw dodać panel z butonem do contentPanelu, a potem usunał ten panel i dodał ten z drop boxem w jego miescje jako contenpanel.

0
        //czyszczenie ekranu z komponentow
        rootPane.remove(jPanel1);
        rootPane.remove(jPanel2);
0

Ps. Jak chcesz się na prawdę dobrze nauczyć Swinga - To polecam Java 2 Podstawy i Java 2 Techniki zaawansowane + nie używanie Netbeansa :) (Sorry zboczenie zawodowe, przez dwa lata byłem programistą swinga i wszystko pisałem "z łapy")

0
Black007 napisał(a):

Hej.
Metodą eliminacji:
Problemem jest to:

        Component[] components = rootPane.getComponents();
        for (Component c : components) {
            c.setVisible(false);
        }

Po usunięciu tego fragmentu działa - co prawda wyświetla box pod buttonem, ale działa.
Coś pewnie chramoli się w wątkach AWT.

Ja bym spróbował najpierw dodać panel z butonem do contentPanelu, a potem usunał ten panel i dodał ten z drop boxem w jego miescje jako contenpanel.

Dzięki za zainteresowanie problemem.
Jak tylko pojawił się ten problem rzeczywiście pomyślałem, że coś z wątkami. Hmm tylko jak to sprawdzić, zdebugować?
Usunięcie wskazanych przez ciebie linijek rzeczywiście rozwiązuje problem ale zastanawiam się co pobranie listy aktualnych komponentów i ustawienie dla każdego z nich metody setVisible(false) ma wspólnego z jComboBox, który de facto jeszcze nie został wywołany?
poniższy kod niestety nie działa (nie są usuwane panele i ich zawartość):

		rootPane.remove(jPanel1);
		rootPane.remove(jPanel2);

natomiast zamiast tych dwóch powyższych linijek zrobiłem jak niżej:

		jPanel1.setVisible(false);
		jPanel2.setVisible(false);

i co prawda panele znikają natomiast, żeby pojawił się jComboBox trzeba najechać myszką (!!!) w miejscu gdzie on się fizycznie na nowym panelu znajduje.

O co tu chodzi? ;-)

0

Tak na szybko i z głowy to na conentpanelu wywołaj invalidate(), po ich usunięciu i wtedy powinien odrysować.

0

Wracając do oryginalnego kodu, to możesz jeszcze zamiast dodawać do rootPane Panel2, ustwaić go jako ContentPane

rootPane.add(panel);

na to:

setContentPane(panel);
0

Cześć
Dziękuje Black007 za aktywność w wątku. Zgodnie z twoją sugestią przepisałem tę aplikację bez korzystania ze wsparcia NetBeans i hmm jComboBox normalnie się rozwija. Nie wiem czym to jest spowodowane, gdzieś na Stack Overflow widziałem, że dziwne zachowania w Swing-u zdarzają się przez Look and Feel. Może tu jest podobnie?
Gdyby kogoś interesowało to umieszczam kody działające:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

/**
 *
 * 
 */
public class MojFrame extends JFrame {

	JPanel panel1;
	JPanel panel2;

	JButton buttonPanel1;

	public MojFrame() {
		super("Dwa panele");
		setPreferredSize(new Dimension(500, 500));
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		setLayout(null);
		pack();
		setVisible(true);

		panel1 = new JPanel();
		panel1.setBorder(new TitledBorder("Pierwszy"));
		panel1.setVisible(true);
		panel1.setBounds(0, 0, 200, 200);
		add(panel1);

		buttonPanel1 = new JButton("1 Przycisk");
		buttonPanel1.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				Container contentPane = getContentPane();
				for (Component c : contentPane.getComponents()) {
					c.setVisible(false);


					//tworzenie nowego panelu
					MojPanel mp = new MojPanel();
					add(mp);
				}
			}
		});
		panel1.add(buttonPanel1);

		panel2 = new JPanel(new BorderLayout());
		panel2.setBorder(new TitledBorder("drugi"));
		panel2.setVisible(true);
		panel2.setBounds(0, 200, 200, 200);
		add(panel2);

	}

}
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

/**
 *
 *
 */
public class MojPanel extends JPanel {
	JComboBox combo;
	JButton button;

	public MojPanel() {
		combo = new JComboBox();
		button  = new JButton("2 przycisk");
		button.setVisible(true);
		combo.setVisible(true);
		combo.setModel(new DefaultComboBoxModel(new String[]{"jeden","dwa"}));
		add(button);
		add(combo);
		setBorder(new TitledBorder("Trzeci"));
		setVisible(true);
		setBounds(0, 0, 200, 200);
	}
}

btw czy to normalne, że ta aplikacja trzyma w RAM-ie ponad 20 MB?

0

Hej, z tym look and feel to może tak być, że jeśli jest jakieś spoza standardu, to faktycznie może tak się zachowywać.
20 mb, to chyba optymalny rozmiar, pamiętaj, że po za aplikacją masz jeszcze maszynę wirtualną

1 użytkowników online, w tym zalogowanych: 0, gości: 1