문제

Hello I am try to get jcomponent from other class.the components are displaying but my frame size changes.

Example.java

public class Example extends JFrame{

  static JPanel panel = new JPanel();
  static A a = new A();
  static B b = new B();
  static JComboBox<String> combo = new JComboBox<>();   
  static String value;

     Example(){
        setSize(400, 400);
        combo.setBounds(450, 140, 50, 20);
        combo.addItem("");
        combo.addItem("a");
        combo.addItem("b");
        combo.addActionListener(new ActionListener() {

            @Override
            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();
                }
            }
        });
        panel.add(combo);
        this.add(panel);
        setVisible(true);
        }
}

A.java

public class A extends JFrame{

  JPanel panel = new JPanel();
  JLabel lab = new JLabel("Text");

  A(){
      lab.setBounds(280, 25, 150, 50);
      lab.setVisible(true);
      panel.add(lab);
      add(panel);
  }
  public  JLabel getLabel(){
    return lab;
  }
}

B.java

public class B extends JFrame{

    JPanel panel = new JPanel();
    JButton lab = new JButton("Hello");

    B(){
       lab.setBounds(380, 25, 250, 50);
       lab.setVisible(true);
       panel.add(lab);
       add(panel);
    }
    public JButton getLabel(){
       return lab;  
    }
}

Main.java

public class Main {
  public static void main(String [] agrs) {
    Example ex = new Example();
    ex.setVisible(true);
  }
}

when I run frame open as defined size but when I select a from combo box the frame size decreases any suggestion so as screen size remain same.

도움이 되었습니까?

해결책

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top