可执行的.jar - 缺少功能

时间:2012-01-01 22:14:18

标签: java jar runtime-error

我正在为我的教育第一学期的编程考试创建一个程序。它应该向用户显示在哥本哈根和其他6个城市(在其他时区)的时间。用户还应该能够将城市添加到列表中。我正在用JAVA编写程序(下面提供了源代码)。当我从eclipse运行它时,应用程序运行正常,但是当我将它导出到.jar文件时,某些功能不起作用。以下是程序如何从eclipse运行(以及它应该如何运行):Screenshots

当我从.jar文件中运行它时,程序将不会提交输入的城市名称(程序停留在屏幕3)。这不是应用程序停止或卡住。我仍然可以编辑文本fild并按“显示时间” - 按钮 - 按“添加城市”按钮没有任何反应(或当焦点位于文本字段时按Enter键也应该将输入的城市添加到列表)。

我使用了JodaTime库中的类(添加到构建路径中)。

我将项目从eclipse导出为“Runnable JAR文件”(我也尝试导出为“JAR文件”但是当我运行它时会出现错误,所以我猜这绝对不是这样做的方法:P)。在选择“Runnable JAR文件”时,我尝试了“库处理”的所有3个选项:

  1. “将所需的库提取到生成的JAR”

  2. “将所需的库打包到生成的JAR中”

  3. “将所需的库复制到生成的JAR旁边的子文件夹中”

  4. 结果与前两个相同,在第三种情况下,当我打开.jar时没有任何反应。

    我不知道问题的根源是什么。请帮帮我: - )

    更新!

    我认为这可能与我为另一个项目所做的类Capitalize有关。当我注释掉使用该类的代码时,程序运行正常。我只是不知道它是什么:S

    好的,所以我从其他项目中删除了我的班级部分,而是在这个项目中实现了一个新方法来完成这项工作。 DONE!

    谢谢大家。

    关心Joakim

    源代码:

    /**
     * This class sets up a window with which a user can interact with a GUI to get the current time in
     * Copenhagen, London, New York, Helsinki, Beijing, San Francisco, New Delhi and Tokyo. The user can
     * also add a new city and its GMT offset to the list where the current time in the new city also
     * will be shown.
     * 
     * @author Joakim
     * @version 1
     * 
     */
    public class MyTimeZone
    {
    
    public static void main(String[] args)
    {
        @SuppressWarnings("unused")
        MyTimeZone timezone = new MyTimeZone();
    }
    
    // Timezone stuff
    private DateTime time;
    private DateTimeZone selectedTimeZone;
    
    // Graphical stuff
    private JFrame window;
    private JPanel windowpanel;
    private JComboBox<GMTHours> gmtHBox;
    private JComboBox<GMTMinutes> gmtMBox;
    private JTextField input;
    private JTextArea output;
    private TreeMap<String, DateTime> outputValues;
    
    /**
     * Sets up the default window in a JFrame.
     */
    private MyTimeZone()
    {
        window = new JFrame();
        windowpanel = new JPanel(new BorderLayout());
        setUpPanel();
        window.setContentPane(windowpanel);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setMinimumSize(new Dimension(420, 300));
        window.setVisible(true);
    }
    
    /**
     * Sets up the JPanel that will be displayed in a JFrame
     */
    private void setUpPanel()
    {
        JPanel north = new JPanel(new FlowLayout());
        JPanel south = new JPanel(new FlowLayout());
        windowpanel.add(north, BorderLayout.PAGE_START);
        windowpanel.add(south, BorderLayout.PAGE_END);
    
        // "Show Time"-button
        JButton showTime = new JButton("Show Time");
        showTime.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent event)
            {
                updateTextArea();
                input.setEditable(true);
            }
    
        });
        north.add(showTime);
    
        // Output text-area
        output = new JTextArea();
        output.setEditable(false);
        outputValues = new TreeMap<String, DateTime>();
        setDefaultTexts();
        JScrollPane outputTextArea = new JScrollPane(output);
        outputTextArea.setBorder(BorderFactory.createLoweredBevelBorder());
        windowpanel.add(outputTextArea, BorderLayout.CENTER);
    
        // Input text-field
        input = new JTextField();
        input.setEditable(false);
        input.setPreferredSize(new Dimension(150, 20));
        input.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent event)
            {
                try 
                {
                    String inputString = input.getText();
                    addCity(inputString);
                    updateTextArea();
                    input.setText("");
                    gmtHBox.setSelectedItem(GMTHours.ZERO);
                    gmtMBox.setSelectedItem(GMTMinutes.ZERO);
                }
                catch (Exception e)
                {
                    output.setText(e.toString());
                }
            }
        });
        south.add(input);
    
        // Drop-down menus
        gmtHBox = new JComboBox<GMTHours>();
        gmtHBox.setPreferredSize(new Dimension(80, 20));
        for (GMTHours gmtH : GMTHours.values())
        {
            gmtHBox.addItem(gmtH);
        }
        gmtHBox.setSelectedItem(GMTHours.ZERO);
        south.add(gmtHBox);
        south.add(new JLabel(":"));
        gmtMBox = new JComboBox<GMTMinutes>();
        gmtMBox.setPreferredSize(new Dimension(40, 20));
        for (GMTMinutes gmtM : GMTMinutes.values())
        {
            gmtMBox.addItem(gmtM);
        }
        south.add(gmtMBox);
    
        // "Add City"-button
        JButton addCity = new JButton("Add City");
        addCity.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent event)
            {
                try 
                {
                    String inputString = input.getText();
                    addCity(inputString);
                    updateTextArea();
                    input.setText("");
                    gmtHBox.setSelectedItem(GMTHours.ZERO);
                    gmtMBox.setSelectedItem(GMTMinutes.ZERO);
                }
                catch (Exception e)
                {
                    output.setText(e.toString());
                }
            }
        });
        south.add(addCity);
    
    }
    
    /**
     * Updates the output text area. Is called everytime the user adds a city.
     */
    private void updateTextArea()
    {
        output.setText("");
        Set<Entry<String, DateTime>> set = outputValues.entrySet();
        Iterator<Entry<String, DateTime>> i = set.iterator();
        while (i.hasNext())
        {
            Map.Entry<String, DateTime> me = i.next();
            DateTime newTime = new DateTime(me.getValue().getZone());
            outputValues.put(me.getKey(), newTime);
            output.append(me.getKey() + ": " + getTimeString(newTime));
        }
    }
    
    /**
     * Adds a city (string) and its time to the TreeMap of cities
     * that has to be written in the output area.
     * 
     * @param inputString The city (string) to be added
     */
    private void addCity(String inputString)
    {
        Capitalize cap = new Capitalize();
        inputString = cap.capitalizeString(inputString);  // See documentation for more
                                                                // info about class Capitalize
        selectedTimeZone = DateTimeZone.forOffsetHoursMinutes(
                gmtHBox.getItemAt(gmtHBox.getSelectedIndex()).offset,
                gmtMBox.getItemAt(gmtMBox.getSelectedIndex()).offset);
        time = new DateTime(selectedTimeZone);
        outputValues.put(inputString, time);
    }
    
    /**
     * This method sets the default values of the output text area (introduction) and 
     * fills the TreeMap with the default cities and their time
     */
    private void setDefaultTexts()
    {
        output.setText("When you click the button above the current time in Copenhagen is\n"
                + "shown here as well as the time in 6 other cities along with their GMT\n"
                + "time differences shown in parantheses.\n\n" 
                + "After you have clicked 'Show Time' you can also submit cities to the\n" 
                + "list yourself by typing the name of the city in the text-field beneath and\n" 
                + "choosing the GMT offset in [hours]:[minutes] in the dropdown menus.");
    
        time = new DateTime(DateTimeZone.forID("Europe/Copenhagen"));
        outputValues.put("Copenhagen", time);
    
        time = new DateTime(DateTimeZone.forID("Europe/London"));
        outputValues.put("London", time);
    
        time = new DateTime(DateTimeZone.forID("America/New_York"));
        outputValues.put("New York", time);
    
        time = new DateTime(DateTimeZone.forID("Europe/Helsinki"));
        outputValues.put("Helsinki", time);
    
        time = new DateTime(DateTimeZone.forID("Asia/Hong_Kong"));
        outputValues.put("Beijing", time);
    
        time = new DateTime(DateTimeZone.forID("America/Vancouver"));
        outputValues.put("San Francisco", time);
    
        time = new DateTime(DateTimeZone.forID("Asia/Kolkata"));
        outputValues.put("New Delhi", time);
    
        time = new DateTime(DateTimeZone.forID("Asia/Tokyo"));
        outputValues.put("Tokyo", time);
    
    }
    
    /**
     * Converts a DateTime object to a string with the given time and the offset from the given 
     * timezone to the Greenwich Main Time.
     * 
     * @param time A DateTime object from which you want a string representing the time.
     * @return A string of the format: "02:30 (GMT-3:15)" if the time specified in the DateTime
     *         object is 2:30 and the offset is 3 hours and 15 minutes behind GMT.
     */
    private String getTimeString(DateTime time)
    {
        String completeTimeString = "";
        if (time.hourOfDay().get() < 10)
            completeTimeString = "0" + time.hourOfDay().get();
        else
            completeTimeString = "" + time.hourOfDay().get();
        completeTimeString += ":";
        if (time.minuteOfHour().get() == 0)
            completeTimeString += "0" + time.minuteOfHour().get();
        else
            completeTimeString += "" + time.minuteOfHour().get();
    
        completeTimeString += " (GMT";
        DateTime gmt = new DateTime(DateTimeZone.forID("Etc/GMT0"));
        int offsetInMinutes = time.getZone().getOffset(gmt.getMillis()) / 60000;
        if (offsetInMinutes > 0)
            completeTimeString += "+";
        completeTimeString += offsetInMinutes / 60;
        if (offsetInMinutes % 60 != 0)
        {
            if (offsetInMinutes < 0)
                offsetInMinutes = offsetInMinutes * (-1);
            completeTimeString += ":" + offsetInMinutes % 60 + ")\n";
        }
        else
            completeTimeString += ")\n";
        return completeTimeString;
    }
    
    
    
    /**
     * An enum for all the GMT hourly offset values
     * 
     * @author Joakim
     * 
     */
    private enum GMTHours
    {
        MINUS12(-12), MINUS11(-11), MINUS10(-10), MINUS9(-9), MINUS8(-8), MINUS7(-7), MINUS6(-6), 
                MINUS5(-5), MINUS4(-4), MINUS3(-3), MINUS2(-2), MINUS1(-1), ZERO(0), PLUS1(1), 
                PLUS2(2), PLUS3(3), PLUS4(4), PLUS5(5), PLUS6(6), PLUS7(7), PLUS8(8), PLUS9(9), 
                PLUS10(10), PLUS11(11), PLUS12(12);
    
        private int offset;
    
        GMTHours(int offset)
        {
            this.offset = offset;
        }
    
        @Override
        public String toString()
        {
            String s = "GMT";
            switch (offset)
            {
            case -1: s += "-1"; break;
            case -2: s += "-2"; break;
            case -3: s += "-3"; break;
            case -4: s += "-4"; break;
            case -5: s += "-5"; break;
            case -6: s += "-6"; break;
            case -7: s += "-7"; break;
            case -8: s += "-8"; break;
            case -9: s += "-9"; break;
            case -10: s += "-10"; break;
            case -11: s += "-11"; break;
            case -12: s += "-12"; break;
            case 0: s += "0"; break;
            case 1: s += "+1"; break;
            case 2: s += "+2"; break;
            case 3: s += "+3"; break;
            case 4: s += "+4"; break;
            case 5: s += "+5"; break;
            case 6: s += "+6"; break;
            case 7: s += "+7"; break;
            case 8: s += "+8"; break;
            case 9: s += "+9"; break;
            case 10: s += "+10"; break;
            case 11: s += "+11"; break;
            case 12: s += "+12"; break;
            }
            return s;
        }
    }
    
    /**
     * An enum for all the GMT minutely offset values
     * 
     * @author Joakim
     *
     */
    private enum GMTMinutes
    {
        ZERO(0), FIFTEEN(15), THIRTY(30), FORTYFIVE(45);
    
        private int offset;
    
        GMTMinutes(int offset)
        {
            this.offset = offset;
        }
    
        @Override
        public String toString()
        {
            String s = "";
            switch (offset)
            {
            case 0: s = "00"; break;
            case 15: s = "15"; break;
            case 30: s = "30"; break;
            case 45: s = "45"; break;
            }
            return s;
        }
    }
    }
    

2 个答案:

答案 0 :(得分:2)

您可能会遇到异常,因为带有Jode时间库的Jar文件在运行时不在您的类路径中。而且,您可能没有代码(我没有详细查看您的代码)来捕获您不期望的异常并提供错误报告。因此异常被吞噬了。我建议你在转交作业之前解决这个问题。

另一个建议是使用Eclipse远程调试程序,以便在从命令行运行它时可以准确地看到它的运行情况。 Here对于如何做是一个非常好的描述。

答案 1 :(得分:1)

你必须添加所有需要的Java导入,我想念那里

import java.util.TreeMap;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
etc...

并且您可能会使用DateSpinnerModel查看JSpinner,而不是针对每个JComboBoxes部分实施Date

我无法抗拒你的实现,确定JodaTime是优秀的API,但是JSpinner给了我

import java.awt.GridLayout;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;

public class TimeZoneSpinners {

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

            @Override
            public void run() {
                new TimeZoneSpinners().makeUI();
            }
        });
    }

    public void makeUI() {
        final String[] zones = {"Asia/Tokyo", "Asia/Hong_Kong",
            "Asia/Calcutta", "Europe/Paris", "Europe/London",
            "America/New_York", "America/Los_Angeles"
        };
        final JLabel[] labels = new JLabel[zones.length];
        final SimpleDateFormat[] formats = new SimpleDateFormat[zones.length];

        SpinnerDateModel model = new SpinnerDateModel();
        Calendar cal = Calendar.getInstance();
        Date date = cal.getTime();
        model.setValue(date);

        JSpinner spinner = new JSpinner(model);
        spinner.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                Date date = (Date) ((JSpinner) e.getSource()).getValue();
                for (int i = 0; i < labels.length; i++) {
                    labels[i].setText(formats[i].format(date));
                }
            }
        });

        SimpleDateFormat format = ((JSpinner.DateEditor) spinner.getEditor()).getFormat();
        format.setTimeZone(TimeZone.getTimeZone(zones[0]));
        format.applyPattern("yyyy-MM-dd HH:mm:ss");

        JPanel panel = new JPanel(new GridLayout(zones.length, 2, 4, 4));
        for (int i = 0; i < zones.length; i++) {
            formats[i] = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
            formats[i].setTimeZone(TimeZone.getTimeZone(zones[i]));

            JLabel label = new JLabel(zones[i]);
            labels[i] = new JLabel("yyyy-MMM-dd HH:mm:ss");
            panel.add(label);
            panel.add(labels[i]);
        }

        JFrame frame = new JFrame();
        frame.getContentPane().add(spinner, "North");
        frame.getContentPane().add(panel, "Center");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}
来自Java TimeZones的

import java.util.TimeZone;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Arrays;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class TZShiftTest {

    public static void main(String[] args) throws Exception {
        // Assume DST shift happens on a minute boundary,
        // that is, when minutes, seconds, and millis are zero.
        // 60 min./hr. * 24 hr./day * 265 days/yr * about 250 TZs that use DST = 131,400,000 tests
        // to test every minute of every TZ that uses DST for one year
        DateFormat df = new SimpleDateFormat("EEE, yyyy-MM-dd HH:mm:ss.SSS zzzz");
        String[] ids = TimeZone.getAvailableIDs();
        Arrays.sort(ids);
        long totalElapsed = 0L;
        for (String id : ids) {
            long start;
            long end;
            long elapsed;
            int startYear;
            TimeZone tz = TimeZone.getTimeZone(id);
            if (!tz.useDaylightTime()) {
                continue;
            }
            Calendar cal = new GregorianCalendar();
            start = System.nanoTime();
            cal.setTimeZone(tz);
            cal.set(Calendar.MILLISECOND, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.DAY_OF_MONTH, 1);
            cal.set(Calendar.MONTH, Calendar.JANUARY);
            startYear = cal.get(Calendar.YEAR);
            df.setTimeZone(tz);
            while (cal.get(Calendar.YEAR) == startYear) {
                tz.inDaylightTime(cal.getTime());
                cal.add(Calendar.MINUTE, 1);
            }
            end = System.nanoTime();
            elapsed = end - start;
            totalElapsed += elapsed;
            System.out.printf("%s took %,d ms, total is %,d s%n", tz.getDisplayName(), elapsed / 1000000L, totalElapsed / 1000000000L);
        }
    }
}