java - 是否可以让你添加到java中的组件的代码变得更小?

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

最佳答案

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

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?

<小时/>

编辑

您在评论中指出:

I have used a JFrame.

  • 首先,您应该避免让您的 Swing GUI 类扩展 JFrame,因为这会不必要地将您的 GUI 代码陷入需要付出一些努力才能摆脱的困境。
  • 相反,将您的 Swing GUI 代码调整为制作 JPanel,这些面板现在可以轻松放入其他 JPanel 中,或者放入 JFrame、JDialogs、JOptionPanes 中,在 CardLayout 中交换,...​​无论需要什么地方。
  • 相反,在需要时创建、填充和打包 JFrame。
<小时/>

编辑2
你问:

So the name of each label and field we are adding through for loop will be named as label1, label2 etc. and field1, field2 etc. Is it possible to change the name of each field/label to something different e.g. instead of field 1, 2, 3 have number, string and double etc and for label, instead of label 1, 2 and 3 have numanswer, stringanswer, doubanswer etc.

当然,您可以使用任何您想要的名称。数字标签并没有什么魔力。

how can I get the text of individual textfield and set it to different variables? e.g. first textfield to a variable firstnumber, second textfield to userinput and so on.

我从来没有明白代码的真正关键是什么——我使用 Map 将 JTextField 与另一个对象(例如 String 或枚举)关联起来,通过这样做,可以轻松提取 JTextField 所保存的文本JTextField 使用字符串或枚举作为键。

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

关于java - 是否可以让你添加到java中的组件的代码变得更小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21498988/

相关文章:

java - 如何在 Windows 10 中运行来自 GitHub 的 Java 代码?

java - JPA : Auto Increment ID with Oracle Database

java - JTable 的 getSelectedColumn 不适用于更改模型

.net - 是否有插入具有多个级联值的 .NET Blazor 组件的简写?

java - 如何检查 double 值是否包含特殊字符

java - 用 SQL 替换 JPA/Hibernate DiscriminatorColumn

java - MigLayout,禁用 JButton 宽度调整大小

java - 如何在 JFrame 上对 ImageIcon 进行动画处理,图像将加载但不会更改

java - 绘制另一个组件

android - 何时在 Android 中为 ComponentName 使用哪个构造函数?