java - 通过按钮作为显示面板打开另一个类(class)

标签 java swing class dialog

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

我认为他们可能是一种通过 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 打开对话框的方法?

任何帮助都会很棒。

最佳答案

这是一个典型的例子,将所有的鸡蛋都放在一个篮子里,然后想知道为什么最后会得到一个 omlet。

Java 是面向对象的语言,您应该将您的类分解为职责区域,通过层构建功能,这为您提供了灵 active 以及根据需要更改层的能力。

例如。您的 ports 类应该做一份工作,并且只做一份工作,获取 CommPortIdentifier 的列表

  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...
    }

  }

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

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

看看How to use menus , How to use actionsWorker threads and SwingWorker了解更多详情

关于java - 通过按钮作为显示面板打开另一个类(class),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29981606/

相关文章:

c++ - 如何在线程之间传递指向类对象的指针,并在主线程完成执行后让它保持不变?

eclipse 中的 java.lang.NoClassDefFoundError : org/aopalliance/intercept/MethodInterceptor with TransactionInterceptor error on maven pom. xml

java - 如何根据某些属性使用 RxJava2 对 ArrayList 进行分组?

java - ActionListener 阻止程序运行?

java - 为什么我的第二个 JButton 没有输出?

c++ - Qt和C++:覆盖或扩展类

java - 用于使用 Cognito 用户池服务 Oauth 客户端凭证流身份验证的 AWS Java SDK 服务?

java - 为什么使用计时器删除 View 时应用程序崩溃?

Java读卡器乱码

c++ - 如何从另一个文件加载类 - Visual Studio C++