是否可以使您添加到java的组件代码更小?

时间:2014-02-01 14:04:16

标签: java swing components

我想知道我们是否一遍又一遍地向java(在主类中)添加相同的组件并为每个组件编写单独的代码,是否可以使代码更小?例如如果我们多次添加按钮和标签,每个按钮和标签都做不同的工作,是否可以将它们放在更少的代码中,或者它是否必须像那样。

JLabel label = new JLabel("Text1");
label.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(label);
JTextField field = new JTextField();
panel.add(field);

JLabel label1 = new JLabel("Text2");
label1.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(label1);
JTextField field1 = new JTextField();
panel.add(field1);

JLabel label2 = new JLabel("Text3");
label2.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(label2);
JTextField field2 = new JTextField();
panel.add(field2);

在我的代码中,我必须反复添加相同的组件,例如10次,但是每个组件都在做不同的工作,是否可以用更少的代码将它们放在一起?

编辑:

 String[] labelNames = {"label1", "label2", "label3",};
 String[] fieldNames = {"Name1", "Name2", "Name3",};
 String[] labelTexts = {"Text1", "Text2", "Text3"};
 Map<String, JTextField> fieldMap = new HashMap<>();
 // for loop here to add JLabels
 for (String text : labelTexts) {
    for (int i = 0; i < fieldNames.length; i++) {
        for (int j = 0; j < labelNames.length; j++) {
   JLabel labelNames = new JLabel(text);
   panel.add(labelNames);
   JTextField fieldName = new JTextField(10);
   panel.add(fieldName);
   fieldMap.put(text, fieldName);
 }
 }
 }

1 个答案:

答案 0 :(得分:1)

使用集合或数组和循环来简化事情:

String[] labelTexts = {"Text1", "Text2", "Text3"};
Map<String, JTextField> fieldMap = new HashMap<>();
// for loop here to add JLabels
for (String text : labelTexts) {
  JLabel label = new JLabel(text);
  panel.add(label);
  JTextField field = new JTextField(10);
  panel.add(field);
  fieldMap.put(text, field);
}

例如,我在此示例中使用了上述类型的代码:

class PlayerEditorPanel extends JPanel {
   enum FieldTitle {
      NAME("Name"), SPEED("Speed"), STRENGTH("Strength");
      private String title;

      private FieldTitle(String title) {
         this.title = title;
      }

      public String getTitle() {
         return title;
      }
   };

   private static final Insets WEST_INSETS = new Insets(5, 0, 5, 5);
   private static final Insets EAST_INSETS = new Insets(5, 5, 5, 0);
   private static final double SCALE = 0.4;
   private Map<FieldTitle, JTextField> fieldMap = new HashMap<FieldTitle, JTextField>();
   private BufferedImage backgroundImg = null;
   private int imgWidth;
   private int imgHeight;

   public PlayerEditorPanel(BufferedImage img) {
      this.backgroundImg = img;
      imgWidth = (int) (backgroundImg.getWidth() * SCALE);
      imgHeight = (int) (backgroundImg.getHeight() * SCALE);

      setLayout(new GridBagLayout());
      setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("Player Editor"),
            BorderFactory.createEmptyBorder(5, 5, 5, 5)));
      GridBagConstraints gbc;
      for (int i = 0; i < FieldTitle.values().length; i++) {
         FieldTitle fieldTitle = FieldTitle.values()[i];
         gbc = createGbc(0, i);
         JLabel fieldLabel = new JLabel(fieldTitle.getTitle() + ":",
               JLabel.LEFT);
         fieldLabel.setForeground(new Color(200, 10, 10));
         fieldLabel.setFont(fieldLabel.getFont().deriveFont(Font.BOLD, 24f));
         add(fieldLabel, gbc);
         gbc = createGbc(1, i);
         JTextField textField = new JTextField(10);
         add(textField, gbc);

         fieldMap.put(fieldTitle, textField);
      }
   }

   @Override
   @Transient
   public Dimension getPreferredSize() {
      if (backgroundImg != null) {
         return new Dimension(imgWidth, imgHeight);
      }

      return super.getPreferredSize();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (backgroundImg != null) {
         g.drawImage(backgroundImg, 0, 0, imgWidth, imgHeight, this);
      }
   }

   private GridBagConstraints createGbc(int x, int y) {
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridx = x;
      gbc.gridy = y;
      gbc.gridwidth = 1;
      gbc.gridheight = 1;

      gbc.anchor = (x == 0) ? GridBagConstraints.WEST : GridBagConstraints.EAST;
      gbc.fill = (x == 0) ? GridBagConstraints.BOTH
            : GridBagConstraints.HORIZONTAL;

      gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS;
      gbc.weightx = (x == 0) ? 0.1 : 1.0;
      gbc.weighty = 1.0;
      return gbc;
   }

   public String getFieldText(FieldTitle fieldTitle) {
      return fieldMap.get(fieldTitle).getText();
   }

}

在这里的答案中:How to align multiple textfields on a background image within a JOptionPane?


修改

您在评论中说明:

  

我使用过JFrame。

  • 首先,您应该避免让您的Swing GUI类扩展JFrame,因为这会不必要地将您的GUI代码绘制到需要稍微努力离开的角落。
  • 相反,将你的Swing GUI代码设置为制作JPanels,现在可以轻松放入其他JPanels的面板,或者放入JFrame,JDialogs,JOptionPanes,交换CardLayouts,......无论何时需要它们。
  • 而是在需要时创建,填充和打包JFrame。

编辑2
你问:

  

因此,我们通过for循环添加的每个标签和字段的名称将被命名为label1,label2等和field1,field2等。是否可以将每个字段/标签的名称更改为不同的名称。而不是字段1,2,3有数字,字符串和双等,对于标签,而不是标签1,2和3有numanswer,stringanswer,doubanswer等。

当然,你可以使用你想要的任何名字。没有与数字标签相关的魔力。

  

如何获取单个文本字段的文本并将其设置为不同的变量?例如第一个文本字段为变量firstnumber,第二个textfield为userinput,等等。

我从来没有得到我的代码的关键 - 我使用Map将JTextField与另一个对象(如String或enum)相关联,并通过这样做,允许轻松提取由JTextField使用String或enum作为键。

例如在我的后一个例子中,我使用一个名为FieldTitle的三个项目(项目数量可以是任何项目)的枚举,并使用该枚举创建我的JLabel文本和到每个关联的JTextField的映射。我使用for循环遍历枚举项的数组(由枚举values()方法保存),并在该循环中,我创建我的JLabel和JTextField,使用GridBagLayout将它们添加到我的JPanel中,以便数据显示为一个表,每个标签文本字段对包含一行表。然后,我使用枚举作为键将新创建的JTextField添加到Map:fieldMap.put(fieldTitle, textField);。然后当任何外部类想要提取JTextField持有的文本时,他们只需要调用getFieldText方法,传入适当的枚举,并获取它们的字符串。