简体   繁体   English

从其他类获取Jcomponent会更改帧大小

[英]getting Jcomponent from other class changes frame size

Hello I am try to get jcomponent from other class.the components are displaying but my frame size changes. 您好,我尝试从其他类获取jcomponent。这些组件正在显示,但是我的帧大小发生了变化。

Example.java 范例.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 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 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 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 : 解决此问题的快速而肮脏的方法是摆脱pack()并替换revalidate()repaint

add(panel);
revalidate();
repaint();
// pack();
  • revalidate tells the layout managers to re-lay out their components. revalidate告诉布局管理器重新布局其组件。
  • repaint requests that the component be repainted, especially "dirty" regions repaint请求repaint组件,尤其是“脏”区域
  • pack tells the window to re-lay out all components and resize to the optimal size. pack告诉窗口重新布置所有组件并调整大小到最佳大小。

Much better would be to use a CardLayout, and the window and component size will remain constant, big enough to fit the largest component. 更好的方法是使用CardLayout,并且窗口和组件的大小将保持恒定,足以容纳最大的组件。 ... 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: 您的ActionListener的actionPerformed方法就是这样:

  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 . 有关CardLayout的更多信息,用途和功能,请查看CardLayout教程 But in a nutshell, it automates the process of swapping "views" in a GUI, making it much harder to shoot yourself in the foot. 简而言之,它可以自动在GUI中交换“视图”的过程,从而使拍摄自己的脚变得更加困难。

Try to use revalidate() instead of pack() ; 尝试使用revalidate()代替pack() pack() automatically resizes your frame in order to fit the subcomponents: pack()自动调整框架大小以适合子组件:

javadoc for pack(): 用于pack()的javadoc:

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. 如果任意一个尺寸小于上一次调用setMinimumSize方法指定的最小尺寸,则窗口的宽度和高度将自动放大。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM