getting Jcomponent from other class changes frame size

那年仲夏 提交于 2019-12-02 12:25:07

The quick and dirty way to solve this is to get rid of pack() and subsitute revalidate() and repaint:

add(panel);
revalidate();
repaint();
// pack();
  • revalidate tells the layout managers to re-lay out their components.
  • repaint requests that the component be repainted, especially "dirty" regions
  • pack tells the window to re-lay out all components and resize to the optimal size.

Much better would be to use a CardLayout, and the window and component size will remain constant, big enough to fit the largest component. ... and avoid all use of null layouts.


For example:

import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class Example2 extends JPanel {
   public static final String[] COMBO_TEXTS = {"", "a", "b"};
   private static final int PREF_W = 400;
   private static final int PREF_H = PREF_W;
   private DefaultComboBoxModel<String > comboModel = new DefaultComboBoxModel<>(COMBO_TEXTS);
   private CardLayout cardLayout = new CardLayout();

   public Example2() {
      setLayout(cardLayout);
      ComboListener comboListener = new ComboListener();

      JComboBox<String> combo = new JComboBox<>(comboModel);
      combo.addActionListener(comboListener);;
      JPanel panelBlank = new JPanel();
      panelBlank.add(combo);

      JPanel panelWithText = new JPanel();
      combo = new JComboBox<>(comboModel);
      combo.addActionListener(comboListener);;
      panelWithText = new JPanel();
      panelWithText.add(combo);
      panelWithText.add(new JLabel("Text"));

      JPanel panelWithButton = new JPanel();
      combo = new JComboBox<>(comboModel);
      combo.addActionListener(comboListener);;
      panelWithButton = new JPanel();
      panelWithButton.add(combo);
      panelWithButton.add(new JButton("Hello"));

      add(panelBlank, COMBO_TEXTS[0]);
      add(panelWithText, COMBO_TEXTS[1]);
      add(panelWithButton, COMBO_TEXTS[2]);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private class ComboListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         JComboBox<String> combo = (JComboBox<String>)e.getSource();
         String item = combo.getSelectedItem().toString();
         cardLayout.show(Example2.this, item);
      }
   }

   private static void createAndShowGui() {
      Example2 mainPanel = new Example2();

      JFrame frame = new JFrame("Example2");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

This simplifies things and makes it harder to shoot yourself in the foot. So rather than this:

        public void actionPerformed(ActionEvent e) {
            value = (String) combo.getSelectedItem().toString();
            if(value.equals("a")){
                panel.add(a.getLabel());
                panel.remove(b.getLabel());
                // add(panel);
                // pack();
            }else if(value.equals("b")){
                panel.add(b.getLabel());
                panel.remove(a.getLabel());
                // add(panel);
                // pack();
            }
            add(panel);
            revalidate();
            repaint();
        }

Your ActionListener's actionPerformed method is just this:

  public void actionPerformed(ActionEvent e) {
     JComboBox<String> combo = (JComboBox<String>)e.getSource();
     String item = combo.getSelectedItem().toString();
     cardLayout.show(Example2.this, item);
  }

For more on the CardLayout, its uses and functionality, please check out the CardLayout Tutorial. But in a nutshell, it automates the process of swapping "views" in a GUI, making it much harder to shoot yourself in the foot.

Try to use revalidate() instead of pack(); pack() automatically resizes your frame in order to fit the subcomponents:

javadoc for pack():

Causes this Window to be sized to fit the preferred size and layouts of its subcomponents. The resulting width and height of the window are automatically enlarged if either of dimensions is less than the minimum size as specified by the previous call to the setMinimumSize method.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!