【问题标题】:Nicer way to layout TextFields aligned to the top of JPanel布局与 JPanel 顶部对齐的 TextField 的更好方法
【发布时间】:2015-12-13 01:58:04
【问题描述】:

如果我将GridLayoutBoxLayout 用于JTextFieldJLabel 对,它将在文本字段中平均分配JPanel

看起来像这样:

我想要的看起来像这样(文本字段被挤压到顶部):

我能够在this answer 之后实现这一目标。代码是:

public void forceSize( int szx, int szy, JComponent comp ){
    comp.setPreferredSize( new Dimension( szx, szy ) );
    comp.setMaximumSize  ( new Dimension( szx, szy ) );
    comp.setMinimumSize  ( new Dimension( szx, szy ) );
};

public void addLabeledBox( String label_str, JTextField valField, JPanel labelPane, JPanel valuePane ){
    JLabel label  = new JLabel( label_str );
    label.setLabelFor( valField );
    labelPane.add( label    );
    forceSize( 100, 20, label );
    forceSize( 100, 20, valField );
    valuePane.add( valField );
}

public JComponent makeCityPanel( ){

    //JPanel labelPane = new JPanel( new GridLayout(0,1) );
    //JPanel valuePane = new JPanel( new GridLayout(0,1) );

    JPanel labelPane = new JPanel( ); labelPane.setLayout( new BoxLayout( labelPane, BoxLayout.Y_AXIS )  );
    JPanel valuePane = new JPanel( ); valuePane.setLayout( new BoxLayout( valuePane, BoxLayout.Y_AXIS )  );

    //panel.setLayout(new GridBagLayout());
    //panel.setLayout(new GridBagLayout());

    name_field = new JTextField( );
    addLabeledBox( "name",       name_field,         labelPane, valuePane );

    ix_field = new JFormattedTextField( NumberFormat.getNumberInstance() );
    addLabeledBox( "ix",         ix_field,         labelPane, valuePane);

    iy_field = new JFormattedTextField( NumberFormat.getNumberInstance() );
    addLabeledBox( "iy",         iy_field,         labelPane, valuePane);

    factorySpace_field = new JFormattedTextField( NumberFormat.getNumberInstance() );
    addLabeledBox( "FactorySpace",  factorySpace_field,         labelPane, valuePane);

    storeSpace_field = new JFormattedTextField( NumberFormat.getNumberInstance() );
    addLabeledBox( "StoreSapce",    storeSpace_field,         labelPane, valuePane );

    //JScrollPane cityPanel = new  JScrollPane( ); 
    JPanel cityPanel = new JPanel(new GridLayout(1,0));
    cityPanel.add( labelPane );
    cityPanel.add( valuePane );
    cityPanel.setSize( 100 , 100 );

    return cityPanel;
}

但是,我觉得这不是正确的方法。 (还有here他们说这很糟糕)。

那么有没有更好的办法呢?

【问题讨论】:

    标签: java swing user-interface


    【解决方案1】:

    另一种方法是使用不同的布局管理器嵌套面板:

    1. 将“主”面板的布局设为BorderLayout,并将此面板添加到选项卡式窗格中。
    2. 使用您的GridLayout 创建第二个“子”面板并将您的组件添加到面板中。
    3. 将“子”面板添加到“主”面板的 BorderLayout.PAGE_Start。这将尊重面板的首选高度。

    或者您可以随时使用GridBagLayout。它涉及更多,因为您需要为每个组件指定约束,但是您可以使用单个面板获得所需的效果。阅读 How to Use GridBagLayout 上的 Swing 教程部分,了解更多信息和工作示例。

    【讨论】:

      【解决方案2】:

      MigLayout 是一个很好的布局。

      这里有一段代码可以使用布局实现你想要的。

      import javax.swing.*;
      import java.awt.*;
      import net.miginfocom.swing.MigLayout;
      
      public class SimpleGUI
      {
          public JFrame myMainWindow = new JFrame("City View");
      
          JPanel guiPanel = new JPanel();
      
          JLabel name = new JLabel("Name");
          JLabel ix = new JLabel("ix");
          JLabel iy = new JLabel("iy");
          JLabel factorySpace = new JLabel("Factory Space");
          JLabel storeSpace = new JLabel("Store Space");
          JTextField t1 = new JTextField();
          JTextField t2 = new JTextField();
          JTextField t3 = new JTextField();
          JTextField t4 = new JTextField();
          JTextField t5 = new JTextField();
      
          int fontMetrics;
          FontMetrics fM;
      
          public void runGUI()
          {
              myMainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      
              myMainWindow.setLayout(new GridLayout(1,1));
      
              createTestPanel();
      
              myMainWindow.getContentPane().add(guiPanel);
      
              myMainWindow.setVisible(true);
              myMainWindow.pack();
              myMainWindow.setMinimumSize(new Dimension(myMainWindow.getBounds().getSize()));
          }
      
          public void createTestPanel()
          {
              MigLayout layout = new MigLayout("wrap 2", "[grow]");
              guiPanel.setLayout(layout);
      
              fM = name.getFontMetrics(name.getFont());
              fontMetrics = fM.stringWidth("Name");
              name.setSize(fontMetrics+10,25);
              guiPanel.add(name);
      
              guiPanel.add(t1,"growx, width 100:100:");
      
              fM = ix.getFontMetrics(ix.getFont());
              fontMetrics = fM.stringWidth("ix");
              ix.setSize(fontMetrics+10,25);
              guiPanel.add(ix);
      
              guiPanel.add(t2,"growx, width 100:100:");
      
              fM = iy.getFontMetrics(iy.getFont());
              fontMetrics = fM.stringWidth("iy");
              iy.setSize(fontMetrics+10,25);
              guiPanel.add(iy);
      
              guiPanel.add(t3,"growx, width 100:100:");
      
              fM = factorySpace.getFontMetrics(factorySpace.getFont());
              fontMetrics = fM.stringWidth("Factory Space");
              factorySpace.setSize(fontMetrics+10,25);
              guiPanel.add(factorySpace);
      
              guiPanel.add(t4,"growx, width 100:100:");
      
              fM = storeSpace.getFontMetrics(storeSpace.getFont());
              fontMetrics = fM.stringWidth("Store Space");
              storeSpace.setSize(fontMetrics+10,25);
              guiPanel.add(storeSpace);
      
              guiPanel.add(t5,"growx, width 100:100:");
          }
      
          public static void main(String[] args)
          {
              SimpleGUI sG = new SimpleGUI();
              sG.runGUI();
          }   
      }
      

      但是,当您调整它的大小时,如果在添加标签时使用类似这样的东西,它可能看起来会更好。

      JLabel someLabel = new JLabel("something");
      
      ...
      MigLayout layout = new MigLayout("wrap 2", "[right][grow]");
      guiPanel.setLayout(layout);
      
      guiPanel.add(someLabel,"grow");
      

      这将给出一个看起来像这样的 GUI。

      一些示例代码是

      import javax.swing.*;
      import java.awt.*;
      import net.miginfocom.swing.MigLayout;
      
      public class SimpleGUI
      {
          public JFrame myMainWindow = new JFrame("City View");
      
          JPanel guiPanel = new JPanel();
      
          JLabel name = new JLabel("Name");
          JLabel ix = new JLabel("ix");
          JLabel iy = new JLabel("iy");
          JLabel factorySpace = new JLabel("Factory Space");
          JLabel storeSpace = new JLabel("Store Space");
          JTextField t1 = new JTextField();
          JTextField t2 = new JTextField();
          JTextField t3 = new JTextField();
          JTextField t4 = new JTextField();
          JTextField t5 = new JTextField();
      
          public void runGUI()
          {
              myMainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      
              myMainWindow.setLayout(new GridLayout(1,1));
      
              createTestPanel();
      
              myMainWindow.getContentPane().add(guiPanel);
      
              myMainWindow.setVisible(true);
              myMainWindow.pack();
              myMainWindow.setMinimumSize(new Dimension(myMainWindow.getBounds().getSize()));
          }
      
          public void createTestPanel()
          {
              MigLayout layout = new MigLayout("wrap 2", "[right][grow]");
              guiPanel.setLayout(layout);
      
              guiPanel.add(name);
              guiPanel.add(t1,"growx, width 100:100:");
              guiPanel.add(ix);
              guiPanel.add(t2,"growx, width 100:100:");
              guiPanel.add(iy);
              guiPanel.add(t3,"growx, width 100:100:");
              guiPanel.add(factorySpace);
              guiPanel.add(t4,"growx, width 100:100:");
              guiPanel.add(storeSpace);
              guiPanel.add(t5,"growx, width 100:100:");
          }
      
          public static void main(String[] args)
          {
              SimpleGUI sG = new SimpleGUI();
              sG.runGUI();
          }   
      }
      

      【讨论】:

        【解决方案3】:

        这在我看来像是 GroupLayout 的经典案例。不幸的是,GroupLayout 的教程过于喜欢将方法调用“链接”在一起,但如果你通过它,你应该能够做到,这是一个相当简单的案例。

        基本思想是将每个组件一次添加到垂直布局,一次添加到水平布局;将其视为创建行列和行。与 GridLayout 相比,这一点的好处是布局和字段“列”不需要具有相同的宽度。

        【讨论】:

          猜你喜欢
          • 2013-06-21
          • 2012-02-27
          • 2023-04-04
          • 2017-03-14
          • 1970-01-01
          • 2019-02-03
          • 2013-07-14
          • 2015-10-04
          • 2014-05-19
          相关资源
          最近更新 更多