通过按下按钮打开另一个 class 作为显示面板

Open another class via button push as a display panel

基本上我试图通过在我的主程序中按下按钮来打开我的 porttest.java class。

我认为他们可能是通过 frame.add(porttest) 完成此操作的一种方法,但这没有用。

这是我的 porttest.java 代码。

package Random;
import gnu.io.*;
import java.awt.Color;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.TooManyListenersException;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JLabel;

import java.awt.BorderLayout;
import java.util.Enumeration;
import java.util.HashMap;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JPanel;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JComboBox;


public class porttest {
    private Enumeration ports = null;
    private HashMap portMap = new HashMap();
    private JFrame frame;
    private JPanel panel;
    private JLabel label;
    private JComboBox comboBox;
    public porttest() {
        initialize();
        searchForPorts();
    }
      public void searchForPorts()
        {
            ports = CommPortIdentifier.getPortIdentifiers();

            while (ports.hasMoreElements())
            {
                CommPortIdentifier curPort = (CommPortIdentifier)ports.nextElement();

                //get only serial ports
                if (curPort.getPortType() == CommPortIdentifier.PORT_SERIAL)
                {
                    comboBox.addItem(curPort.getName());
                    portMap.put(curPort.getName(), curPort);
                }
            }
        }
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        panel = new JPanel();
        panel.setBounds(0, 0, 442, 266);
        panel.setLayout(null);

        label = new JLabel("COM Ports:");
        label.setBounds(10, 130, 82, 14);
        panel.add(label);
        frame.getContentPane().add(panel);

        comboBox = new JComboBox();
        comboBox.setBounds(76, 124, 93, 26);
        panel.add(comboBox);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    porttest window = new porttest();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

我需要在此处添加一些代码才能使其正常工作吗?

我想让它做的只是在我的主程序中间打开,这样用户就可以设置一些设置,然后关闭程序。我这样做的唯一原因是因为我似乎无法让 JComboBox 在 Jmenu 中工作。

也许他们有另一种使用 JComboBox 打开对话框的方法?

任何帮助都会很棒。

你说:

I thought their might be a way to do it via frame.add(porttest) but that didn't work.

或者更确切地说:

frame.add(new PortTest());

你知道为什么吗?因为 porttest 不扩展任何组件或具有可以以这种方式使用的组件字段。我将建议您将 GUI classes 用于创建 JPanel,然后可以将其放入 JFrames 或 JDialogs,或 JTabbedPanes,或通过 CardLayouts 在需要的地方进行交换。这将大大增加您的 GUI 编码的灵活性。

其他建议:

  • 避免 null 布局和 setBounds(...)。虽然空布局和 setBounds() 对于 Swing 新手来说似乎是创建复杂 GUI 的最简单和最好的方法,但您创建的 Swing GUI 越多,您在使用它们时就会 运行 遇到更严重的困难。它们不会在 GUI 调整大小时调整您的组件的大小,它们是皇家 来增强或维护的,当放置在滚动窗格中时它们完全失败,当在所有平台或不同的屏幕分辨率上查看时它们看起来很糟糕来自原来的
  • 相反,您最好了解和使用布局管理器。您可以在此处找到布局管理器教程:Layout Manager Tutorial, and you can find links to the Swing tutorials and to other Swing resources here: Swing Info.
  • 为了现在帮助我们,也为了将来帮助您自己,请编辑您的代码并更改您的变量名称以符合 Java 命名约定:class 名称全部以大写字母开头字母和 method/variable 小写字母的名称。

这是一个 classic 示例,将所有鸡蛋放入一个篮子,然后想知道为什么最后得到一个 omlet。

Java 是 OO 语言,你应该将你的 classes 分解成职责范围,通过层构建功能,这为你提供了灵活性,并且能够在你需要时更改层需要。

例如。你的 ports class 应该做一份工作,只做一份工作,得到一份 CommPortIdentifiers

的列表
  public class Ports {

    public static List<CommPortIdentifier> listCommPorts() {
      List<CommPortIdentifier> listOfPorts = new ArrayList<>(25);
      Enumeration ports = CommPortIdentifier.getPortIdentifiers();

      while (ports.hasMoreElements()) {
        CommPortIdentifier curPort = (CommPortIdentifier) ports.nextElement();

        //get only serial ports
        if (curPort.getPortType() == CommPortIdentifier.PORT_SERIAL) {
          listOfPorts.add(curPort);
        }
      }
      return listOfPorts;
    }

  }

然后,您需要一些方法来加载这些端口并显示。没有你正在使用的库,我做了最坏的假设,并假设这种方法需要时间 运行 (或者可能会阻塞),所以我使用 SwingWorker 来进行实际加载。 .

  public class LoadPortsWorker extends SwingWorker<List<CommPortIdentifier>, Object> {

    @Override
    protected List<CommPortIdentifier> doInBackground() throws Exception {
      return Ports.listCommPorts();
    }

  }

接下来,我们需要一些方法来显示它们。是的,您可以使用 JComboBox,但您还提到要使用菜单项...

    JMenu menu = new JMenu("Ports");
    LoadPortsWorker worker = new LoadPortsWorker();
    worker.addPropertyChangeListener(new PropertyChangeListener() {
      @Override
      public void propertyChange(PropertyChangeEvent evt) {
        LoadPortsWorker worker = (LoadPortsWorker)evt.getSource();
        switch (evt.getPropertyName()) {
          case "state":
            switch (worker.getState()) {
              case DONE:
                try {
                  List<CommPortIdentifier> ports = worker.get();
                  ButtonGroup bg = new ButtonGroup();
                  for (CommPortIdentifier port : ports) {
                    JRadioButtonMenuItem mi = new JRadioButtonMenuItem(new PortAction(port));
                    bg.add(mi);
                    menu.add(mi);
                  }
                } catch (InterruptedException | ExecutionException exp) {
                  exp.printStackTrace();
                }
                break;
            }
        }
      }
    });
    worker.execute();

    JMenuBar mb = new JMenuBar();
    mb.add(menu);

    JFrame frame = new JFrame("Testing");
    frame.setJMenuBar(mb);

这会创建一个名为 "ports" 的 JMenu,它会创建一系列 JRadioButtonMenuItem,每个端口一个,并将它们添加到 "ports" 菜单中。每个端口菜单项被添加到相同的按钮组,意味着只能选择一个。

为了让生活更轻松,我使用 ActionCommPortIdentifier 包装成一个漂亮的简单包...

  public class PortAction extends AbstractAction {

    private CommPortIdentifier port;

    public PortAction(CommPortIdentifier port) {
      this.port = port;
      putValue(SELECTED_KEY, false);
      putValue(NAME, port.getName());
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      // Do what ever you want to do with the port...
    }

  }

在此示例中,我将 "ports" 菜单直接添加到 JMenuBar,但您可以轻松地将其添加到另一个 JMenu 并创建子菜单。

此外,使用这个基本概念,您还可以填充 ComboBoxModelListModel 甚至 TableModel...

查看 How to use menus, How to use actions and Worker threads and SwingWorker 了解更多详情