【问题标题】:How do I make a JButton run an executable in the same directory?如何让 JButton 在同一目录中运行可执行文件?
【发布时间】:2014-10-07 01:42:57
【问题描述】:

好的,我正在尝试让我的 JButton 在不同的目录中运行可执行文件。这是我之前编写的控制台应用程序,我希望此按钮运行可执行文件。我对 Java 编程语言相当陌生,但这是我的代码。

import java.util.*;

import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;



public class main
{
    public static void main(final String[] args) throws IOException {
        JFrame f = new JFrame("Test");
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(500, 500);
        JPanel p = new JPanel();
        JButton b1 = new JButton("Calculate");
        f.add(p);
        p.add(b1);
        Process proce = Runtime.getRuntime().exec("C:/Ctest.exe");
    }
    private static void test1() {
        // TODO Auto-generated method stub

    }
    {
        JFrame f = new JFrame("Test");
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(500, 500);
        JPanel p = new JPanel();
        JButton b1 = new JButton("Calculate");
        f.add(p);
        p.add(b1);
        b1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {

            }
        });
     }
}

另外,如果您对我有任何建议,请随时告诉我。我使用eclipse IDE。

【问题讨论】:

  • 很抱歉,您的代码毫无意义,看起来像是编程的“思想飞行”——随机的编程思想挤在一起。至于您的问题,“运行控制台程序”到底是什么意思?这是一个 Java 控制台程序吗?它是一种用户将通过控制台与程序交互的程序吗?如果是这样,从 GUI 运行它的目的是什么?这些详细信息将帮助其他人更好地了解您的问题。
  • 请编辑您的代码。您似乎粘贴了两次块。
  • @PM77-1 是的,这只是一个实验程序,当我单击按钮时会打开一个新窗口,但感谢您指出这一点。
  • @HovercraftFullOfEels 好的,我所说的运行控制台程序的意思是,它将运行一个控制台包装程序。用户将使用 System.in 直接通过扫描仪与它进行交互,但我现在正在问这个问题,所以我可以在未来以更高级的方式使用它。请原谅我非常不清楚。

标签: java swing jbutton processbuilder


【解决方案1】:

首先查看ProcessBuilder

Swing 是一个单线程框架,因此您不希望在 Event Dispatching Thread(其中调用了 actionPerformed)的当前上下文中启动 Process,并且需要在它自己的内部执行它线程上下文。

这引发了将结果从Process 同步回 UI 的问题,这只能在 EDT 的上下文中完成。为此,您应该考虑使用SwingWorker

查看Concurrency in SwingWorker Threads and SwingWorker 了解更多详情

看看

更多示例...

【讨论】:

  • 谢谢 我一定会考虑到这一点,我必须学习 ProcessBuilder 但我确信它不是世界上最糟糕的事情,也不是最难学的事情。再次感谢您的回答
【解决方案2】:

我的意思是你应该考虑从你的控制台程序中提取核心逻辑和数据来创建一个或多个模型类,然后在你的控制台程序或 GUI 中使用它们。

例如,假设您有一个简单的控制台程序,可以从某人那里获取姓名和出生日期信息:

class SimpleConsole {
   public static void main(String[] args) throws ParseException {
      Scanner scanner = new Scanner(System.in);
      System.out.print("Please enter your name: ");
      String name = scanner.nextLine();

      System.out.print("Please enter your date of birth as mm/dd/yyyy: ");
      String dateString = scanner.nextLine();
      Date dateOfBirth = new SimpleDateFormat("MM/dd/yyyy").parse(dateString);

      Calendar birthday = Calendar.getInstance();
      birthday.setTime(dateOfBirth);
      Calendar today = Calendar.getInstance();
      int age = today.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
      birthday.set(Calendar.YEAR, today.get(Calendar.YEAR));
      if (birthday.compareTo(today) > 0) {
         age--;
      }

      System.out.println("Hello, " + name + ". Your age is: " + age);

   }
}

我要做的第一件事是从该程序中提取关键信息和逻辑,并创建一个名为 Person 的类,它包含一个名称字符串、一个 dateOfBirth Date 字段和一个 calculateAge() 方法:

class Person {
   String name;
   Date dateOfBirth;

   public Person(String name, Date dateOfBirth) {
      this.name = name;
      this.dateOfBirth = dateOfBirth;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public Date getDateOfBirth() {
      return dateOfBirth;
   }

   public void setDateOfBirth(Date dateOfBirth) {
      this.dateOfBirth = dateOfBirth;
   }

   public int getAge() {
      Calendar birthday = Calendar.getInstance();
      birthday.setTime(dateOfBirth);
      Calendar today = Calendar.getInstance();
      int age = today.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
      birthday.set(Calendar.YEAR, today.get(Calendar.YEAR));
      if (birthday.compareTo(today) > 0) {
         age--;
      }
      return age;
   }
}

现在您可以创建一个使用 Person 的控制台程序:

class BetterConsole {
   public static void main(String[] args) throws ParseException {
      Scanner scanner = new Scanner(System.in);
      System.out.print("Please enter your name: ");
      String name = scanner.nextLine();

      System.out.print("Please enter your date of birth as mm/dd/yyyy: ");
      String dateString = scanner.nextLine();
      Date dateOfBirth = new SimpleDateFormat("MM/dd/yyyy").parse(dateString);

      Person person = new Person(name, dateOfBirth);


      System.out.println("Hello, " + person.getName() + ". Your age is: " + person.getAge());
      scanner.close();
   }
}

但更重要的是,Person 类可以很容易地用于您想要的任何类型的 GUI 程序。我必须去睡觉,所以我现在不能显示 GUI,但可能明天。


哎呀,这是 GUI 示例:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;

public class BirthdayGui extends JPanel {
   private static final String PATTERN = "MM/dd/yyyy";
   private JTextField nameField = new JTextField(10);
   private SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN);
   private JFormattedTextField birthDayField = new JFormattedTextField(simpleDateFormat);
   private PersonTableModel tableModel = new PersonTableModel();
   private JTable table = new JTable(tableModel);

   public BirthdayGui() {
      setLayout(new BorderLayout());;
      add(new JScrollPane(table), BorderLayout.CENTER);
      add(createDataEntryPanel(), BorderLayout.PAGE_END);
   }

   private JPanel createDataEntryPanel() {
      birthDayField.setColumns(nameField.getColumns());
      JPanel dataInPanel = new JPanel();
      dataInPanel.add(new JLabel("Enter Name:"));
      dataInPanel.add(nameField);
      dataInPanel.add(new JLabel("Enter Birthday as " + PATTERN + ":"));
      dataInPanel.add(birthDayField);
      dataInPanel.add(new JButton(new AddPersonAction("Add Person", KeyEvent.VK_A)));
      return dataInPanel;
   }

   private class AddPersonAction extends AbstractAction {
      public AddPersonAction(String name, int mnemonic) {
         super(name);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         String name = nameField.getText();
         Date dateOfBirth = (Date) birthDayField.getValue();
         Person person = new Person(name, dateOfBirth);
         tableModel.addRow(person);
      }
   }

   private class PersonTableModel extends AbstractTableModel {
      public final String[] COL_NAMES = {"Name", "Age"};
      List<Person> personList = new ArrayList<>();

      @Override
      public String getColumnName(int column) {
         return COL_NAMES[column];
      }

      @Override
      public int getColumnCount() {
         return COL_NAMES.length;
      }

      @Override
      public int getRowCount() {
         return personList.size();
      }

      @Override
      public Object getValueAt(int rowIndex, int columnIndex) {
         if (rowIndex < 0 || rowIndex >= getRowCount()) {
            throw new ArrayIndexOutOfBoundsException(rowIndex);
         }
         if (columnIndex < 0 || columnIndex >= getColumnCount()) {
            throw new ArrayIndexOutOfBoundsException(columnIndex);
         }

         Person person = personList.get(rowIndex);
         if (columnIndex == 0) {
            return person.getName();
         } else if (columnIndex == 1) {
            return person.getAge();
         }
         return null;
      }

      @Override
      public java.lang.Class<?> getColumnClass(int column) {
         if (column == 0) {
            return String.class;
         } else if (column == 1) {
            return Integer.class;
         } else {
            return super.getColumnClass(column);
         }
      };

      public void addRow(Person person) {
         personList.add(person);
         int firstRow = personList.size() - 1;
         fireTableRowsInserted(firstRow, firstRow);
      }

   }

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

      JFrame frame = new JFrame("ConsoleGuiEg");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }   
}

【讨论】:

    【解决方案3】:

    您必须执行以下操作:

    1. 创建ActionListener 并覆盖方法actionPerformed
    2. 在覆盖的操作执行方法中调用Runtime.getRuntime().exec()
    3. 通过调用button.setActionListener()ActionListener 设置为您的按钮

    【讨论】:

    • “调用Runtime.getRuntime().exec()..” 你在编码什么,Java 1.4?!?对于 Java 1.5+,请使用 ProcessBuilder,因为它可以更容易地使代码变得健壮(与此建议相反,该建议失败的频率高于其工作的频率,即使它工作时也会阻塞 EDT)。 -1
    猜你喜欢
    • 1970-01-01
    • 2019-08-13
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多