简体   繁体   English

向面板/框架添加许多不同的挥杆对象的有效方法。 (Java)

[英]Efficient way to add lots of different swing objects to a panel/frame. (Java)

I'm trying to do as the title says. 我正在尝试按照标题所述进行操作。

I've got an efficient way for posting several of the same swing objects to a frame by storing them in an array and adding them using a for loop like so: 通过将它们存储在数组中并使用for循环添加它们,我有一种有效的方法将多个相同的swing对象发布到框架中:

JLabel[] contrllabels= new JLabel[8];
contrllabels[0] = new JLabel("SCF Type: ");
contrllabels[1] = new JLabel("Units: ");
contrllabels[2] = new JLabel("Spherical Harmonics: ");
contrllabels[3] = new JLabel("Molecular Charge: ");
contrllabels[4] = new JLabel("PP: ");
contrllabels[5] = new JLabel("DFT Type: ");
contrllabels[6] = new JLabel("Max Iterations: ");
contrllabels[7] = new JLabel("Mult: ");


for(int i = 0;i<contrllabels.length;i++){
    c.gridy = i;
    frame.add(contrllabels[i],c);
}

But what if there are several swing objects of different types? 但是,如果有几个不同类型的秋千对象该怎么办? I've got several combo boxes and textfields which I'd like to be added to the frame in a similar manner. 我有几个组合框和文本框,希望以类似的方式添加到框架中。 I use gridbaglayout so if I don't use a for loop, I end up with lots of unnecessary code due to giving the constraints new values every time I want a different object added. 我使用gridbaglayout,所以如果我不使用for循环,由于每次我想要添加一个不同的对象时都给约束赋予新的值,我最终会得到很多不必要的代码。

Is there such thing as an array of references which point to these different objects which I can then iterate through to add to the frame? 是否存在诸如引用数组的引用,这些引用指向这些不同的对象,然后可以对其进行迭代以添加到框架中? Something like 就像是

JTextField tf = new JTextField(5);
JComboBox cb = new JComboBox("example");

Swing[] array = {tf,cb}

for(int i = 0;i<array.length;i++){
    c.gridy = i;
    frame.add(array[i],c);
}

I know such an array doesn't exist, but is there some way of implementing such a thing? 我知道这样的数组不存在,但是有实现这种事情的某种方法吗? It would greatly reduce the number of lines in my code and make it less confusing. 这将大大减少代码中的行数,并减少混乱。

Thank you 谢谢

You could use an array or collection of a common super type such as an array or ArrayList of JComponent. 您可以使用数组或常见超级类型的集合,例如JComponent的数组或ArrayList。 I'm curious if you're using a parallel array of GridBagConstraints to go with each component that is being added -- ugh. 我很好奇您是否正在使用GridBagConstraints的并行数组来与要添加的每个组件配合使用-嗯。 I often use arrays of components but usually if they are like components such as JLabel/JTextField pairs or a cluster of JRadioButtons. 我经常使用组件数组,但通常使用类似JLabel / JTextField对或JRadioButtons群集之类的组件的数组。

As an aside, for my money, I try to avoid GridBagLayout as much as possible and instead nest containers that use the more coder-friendly layouts. 顺便说一句,为了我的钱,我尽量避免使用GridBagLayout,而是嵌套使用更易于编码的布局的容器。

For instance this small GUI was made with a combination of FlowLayout, BoxLayout, BorderLayout and GridLayout: 例如,这个小GUI是由FlowLayout,BoxLayout,BorderLayout和GridLayout组合而成的:

在此处输入图片说明

The large JPanel that holds the whole GUI uses BorderLayout, The JTextArea in the center is placed BorderLayout.CENTER, the Provider JLabel and JTextField at the top are in a FlowLayout JPanel that is placed overall BorderLayout.NORTH, the bottom buttons are in a JPanel that uses GridLayout(1, 0, 5, 0) which is held in another JPanel that uses FlowLayout which is placed in the GUI BorderLayout.SOUTH, and the stuff on the right are in a BoxLayout using JPanel. 容纳整个GUI的大型JPanel使用BorderLayout,中间的JTextArea放置在BorderLayout.CENTER中,提供者JLabel和JTextField顶部在FlowLayout JPanel中,放置在整个BorderLayout.NORTH中,底部的按钮在JPanel中它使用GridLayout(1、0、5、0),该网格保存在另一个使用FlowLayout的JPanel中,该FlowLayout放置在GUI BorderLayout.SOUTH中,而右侧的内容在使用JPanel的BoxLayout中。

For example: 例如:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException;

@SuppressWarnings("serial")
public class GetLetterTextGui extends JPanel {
   private static final int TA_ROWS = 20;
   private static final int TA_COLS = 35;
   private static final int PROVIDER_FIELD_COLS = 10;
   private static final String GUI_TITLE = "Get Letter Text";
   private JList letterList;
   private JTextArea textarea = new JTextArea(TA_ROWS, TA_COLS);
   private JTextField providerField = new JTextField(PROVIDER_FIELD_COLS);
   private JCheckBox addValedictionChkBox = new JCheckBox("Add Valediction", true);

   public GetLetterTextGui() {
      letterList = new JList(new String[]{"Fe", "Fi", "Fo", "Fum"});

      providerField.setText("John Smith, MD");

      textarea.setWrapStyleWord(true);
      textarea.setLineWrap(true);

      JPanel northPanel = new JPanel();
      northPanel.add(new JLabel("Provider:"));
      northPanel.add(providerField);

      JPanel southPanel = new JPanel();
      JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 0));
      btnPanel.add(new JButton("Copy to Clipboard"));
      btnPanel.add(new JButton("Clear"));
      btnPanel.add(new JButton(new ExitAction()));
      southPanel.add(btnPanel);

      JPanel eastPanel = new JPanel();
      eastPanel.setLayout(new BoxLayout(eastPanel, BoxLayout.PAGE_AXIS));
      eastPanel.add(new JScrollPane(letterList));
      eastPanel.add(new JPanel() {{add(addValedictionChkBox);}});

      int eb = 0;
      setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb));
      setLayout(new BorderLayout(eb, eb));
      add(northPanel, BorderLayout.PAGE_START);
      add(eastPanel, BorderLayout.LINE_END);
      add(new JScrollPane(textarea), BorderLayout.CENTER);
      add(southPanel, BorderLayout.PAGE_END);
   }


   private class ExitAction extends AbstractAction {
      private final Object MNEMONIC = new Integer(KeyEvent.VK_X);

      public ExitAction() {
         super("Exit");
         putValue(MNEMONIC_KEY, MNEMONIC);
      }

      @Override
      public void actionPerformed(ActionEvent evt) {
         Window win = SwingUtilities.getWindowAncestor(GetLetterTextGui.this);
         win.dispose();
      }
   }

   private static void createAndShowGui() {
      GetLetterTextGui mainPanel = new GetLetterTextGui();

      JFrame frame = new JFrame(GUI_TITLE);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      try {
         for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
               UIManager.setLookAndFeel(info.getClassName());
               break;
            }
         }

         SwingUtilities.invokeLater(new Runnable() {
            public void run() {
               createAndShowGui();
            }
         });

      } catch (ClassNotFoundException e) {
         e.printStackTrace();
      } catch (InstantiationException e) {
         e.printStackTrace();
      } catch (IllegalAccessException e) {
         e.printStackTrace();
      } catch (UnsupportedLookAndFeelException e) {
         e.printStackTrace();
      }
   }
}

All GUI components are JComponent objects. 所有GUI组件都是JComponent对象。 ArrayList<JComponent> can hold references to all of them. ArrayList<JComponent>可以保存所有引用。 Give it a try: 试试看:

JFrame frame = new JFrame("test");
ArrayList<JComponent> cps = new ArrayList<JComponent>();
cps.add(new JLabel("Hello"));
cps.add(new JPanel());
cps.add(new JButton("OK"));

for (JComponent widget : cps) {
  frame.add(widget);
}

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

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