【问题标题】:getting Jcomponent from other class changes frame size从其他类获取 Jcomponent 会更改帧大小
【发布时间】:2014-03-16 12:08:35
【问题描述】:

您好,我正在尝试从其他类获取 jcomponent。组件正在显示,但我的帧大小发生了变化。

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);
  }
}

当我以定义的大小运行框架打开时,但当我从组合框中选择 a 时,框架大小会减小任何建议,以使屏幕大小保持不变。

【问题讨论】:

    标签: java swing actionlistener jcombobox


    【解决方案1】:

    解决此问题的快速而肮脏的方法是摆脱pack()并替换revalidate()repaint

    add(panel);
    revalidate();
    repaint();
    // pack();
    
    • revalidate 告诉布局管理器重新布局他们的组件。
    • repaint 请求重新绘制组件,尤其是“脏”区域
    • pack 告诉窗口重新布局所有组件并调整到最佳大小。

    使用 CardLayout 会更好,并且窗口和组件大小将保持不变,大到足以容纳最大的组件。 ...并避免使用所有空布局。


    例如:

    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();
             }
          });
       }
    }
    

    这让事情变得简单,也让你更难射中自己的脚。所以而不是这样:

            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();
            }
    

    你的 ActionListener 的 actionPerformed 方法是这样的:

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

    有关 CardLayout、其用途和功能的更多信息,请查看CardLayout Tutorial。但简而言之,它会自动执行在 GUI 中交换“视图”的过程,从而让自己更难自爆。

    【讨论】:

    • 成功了!!谢谢..但是卡片布局是做什么用的?很抱歉问这个“脏”区域是什么。
    • @Mohit:有关 CardLayout、其用途和功能的更多信息,请查看CardLayout Tutorial。但简而言之,它使在 GUI 中交换“视图”的过程自动化,让自己更难自爆。
    【解决方案2】:

    尝试使用revalidate() 而不是pack()pack() 自动调整框架大小以适应子组件:

    pack() 的 javadoc:

    调整此窗口的大小以适合首选大小和布局 的子组件。结果窗口的宽度和高度是 如果任一尺寸小于 上一次调用 setMinimumSize 指定的最小尺寸 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-23
      • 1970-01-01
      • 2018-09-07
      • 2015-02-23
      相关资源
      最近更新 更多