java - 如何暂停 main()

标签 java multithreading

我正在尝试编写我的程序,以便当用户单击“Drive To...”JButton(在我的主类 Dispatch 中)时,它会从用户所在的另一个类 (Cab) 打开一个 JFrame (GoToDistination)可以输入所需的信息,单击“继续”后,它会立即更新 Dispatch JFrame 中的 mainTextArea。

我的问题是,当程序通过主JFrame(Dispatch)时,它只是打开新的JFrame并继续,而不等待输入的信息。它仅在点击开关 JButton 两次后更新(这是因为它切换到 Cab#2,然后返回 Cab#1)。

我对线程进行了一些研究,但我对 Java 仍然是新手,到目前为止我所做的一切都是我自己学到的(这是针对初学者的 Java 大学类(class),我已经远远超出了这点)。任何有关此问题的可能解决方案的帮助将不胜感激。相关代码如下:

调度类:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

public class Dispatch extends JFrame 
{
protected JTextPane mainTextArea;
private JPanel panel;
private JButton GoTo;
private JButton Switch;
private JButton quit;
private Font font;
private int cabNumber=1;
private Cab cab1=new Cab(); //Taxi #1
private Cab cab2=new Cab(); //Taxi #2

public Dispatch()
{
    super("Chess City Cab Service");                            //Sets the JFrame
    Dimension dim= Toolkit.getDefaultToolkit().getScreenSize();
    int width=400;      
    int height=200;     
    int xWindow=(dim.width-width)/2;
    int yWindow=(dim.height-height)/2;
    setLocation(xWindow, yWindow);
    SimpleAttributeSet bSet = new SimpleAttributeSet();             //For setting JTextPane to Center
    StyleConstants.setAlignment(bSet, StyleConstants.ALIGN_CENTER); //Alignment text.

    panel=new JPanel();
    panel.setBackground(Color.YELLOW);
    mainTextArea=new JTextPane();           //create and set JTextPane
    mainTextArea.setEditable(false);
    font=new Font("Serif",Font.PLAIN, 14);
    mainTextArea.setFont(font);
    mainTextArea.setBackground(Color.YELLOW);

    String cabButtonString="";
    menuOutput();
    mainTextArea.revalidate();
    panel.add(mainTextArea);
    StyledDocument doc = mainTextArea.getStyledDocument();
    doc.setParagraphAttributes(0, 104, bSet, false);

    GoTo=new JButton("Drive To...");            //Tells taxi to go to a certain destination
    GoTo.setToolTipText("Click this button to go to a destination");
    panel.add(GoTo);

    if(cabNumber==1)
        cabButtonString="Click this button to switch to cab #2";
    else
        cabButtonString="Click this button to switch to cab #1";

    Switch=new JButton("Switch");           //for switching be/w the two cabs
    Switch.setToolTipText(cabButtonString);
    panel.add(Switch);

    quit=new JButton("Quit");               //quit the program
    quit.setToolTipText("Click this button to quit program");
    panel.add(quit);

    add(panel);                                 //set JFrame size and to visible
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(400,200);
    setVisible(true);

    HandlerClass handler=new HandlerClass();
    GoTo.addActionListener(handler);
    Switch.addActionListener(handler);
    quit.addActionListener(handler);
}
private class HandlerClass implements ActionListener
{
    public void actionPerformed(ActionEvent event)
    {
        Object source = event.getSource();

        if(source==GoTo)            //Goes to the GoToDistinationScreen() in the 
        {                           //CabThreadTester Class where user tells the taxi
            if (cabNumber==1)       //where to go. This is where I need this JFram to pause
            {                       //and allow for other class to complete before moving on.
                cab1.GoToDistinationScreen();
            }
            else
            {
                cab2.GoToDistinationScreen();
            }
            mainTextArea.setText("");       //Clears mainTextArea and then reenters with updated
            mainTextArea.revalidate();      //information.
            menuOutput();
            mainTextArea.revalidate();
        }
        else if(source==Switch)     //Switch between two taxis, currently only way to update taxi location
        {                           //by pressing twice.
            if(cabNumber==1)
            {
                cabNumber=2;
                Switch.setToolTipText("Click this button to switch to cab #1");
                Switch.revalidate();
            }
            else
            {
                cabNumber=1;
                Switch.setToolTipText("Click this button to switch to cab #2");
                Switch.revalidate();
            }
            mainTextArea.setText("");
            mainTextArea.revalidate();
            menuOutput();
            mainTextArea.revalidate();
        }
        else if(source==quit)   //quits the program
        {
            System.exit(0);
        }
    }
}
public void menuOutput()    //Decides what the mainTextArea will show
{
    if(cabNumber==1)
    {
        mainTextArea.setText("     Cab #"+cabNumber+"\nCurrent Location: Intersection of "+cab1.getAlphaStreetName()+" & "+cab1.getNumericStreetName()+"\nPassenger on board");
    }
    else
    {
        mainTextArea.setText("     Cab #"+cabNumber+"\nCurrent Location: Intersection of "+cab2.getAlphaStreetName()+" & "+cab2.getNumericStreetName()+"\nPassenger on board");
    }
}
public static void main(String[] args) 
{   
    new Dispatch();
}
}

驾驶室类:

import java.awt.*;
import java.awt.event.*;
import javax.swing.text.*;
import javax.swing.*;

public class Cab
{
public boolean hasPassenger;
private int xLoc, yLoc,xGoTo, yGoTo;
public String alphaStreet;
public String numericStreet;

public Cab()
{
    hasPassenger=false;
    xLoc=0;
    yLoc=0;
    xGoTo=0;
    yGoTo=0;
    alphaStreet="A Street";
    numericStreet="Zero Street";
    //Sets the initial values
}
public String getAlphaStreetName() //returns alphabetical Street names
{
    return alphaStreet;
}
public String getNumericStreetName() //returns numerical street names
{
    return numericStreet;
}
public void GoToDistinationScreen()     //displays GoToDistination subclass
{
    GoToDistination go=new GoToDistination();
    go.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    go.setSize(250,175);
    go.setVisible(true);
}   
public class GoToDistination extends JFrame
{
    private JComboBox alphaBox;
    private JComboBox numericBox;
    private JTextArea goTextArea;   //1st textArea
    private JTextArea asTextArea;   //2nd textArea
    private JTextArea nsTextArea;   //3rd textArea
    private Font font;
    private String[] alpha={"A", "B", "C", "D", "E",        //both arrays for JComboBox options
            "F", "G", "H", "I", "J","K"};
    private String[] numeric={"Zero","1st","2nd","3rd","4th","5th","6th","7th",
            "8th","9th","10th"};
    private JButton Continue, Cancel;
    private String letter, number;      //Data Stored from ItemEvents
    private JPanel panel;

    public GoToDistination()
    {
        super("Chess City Cab Service");
        Dimension dim= Toolkit.getDefaultToolkit().getScreenSize();
        int width=250;                                              //sets the JFrame
        int height=175;
        int xWindow=(dim.width-width)/2;
        int yWindow=(dim.height-height)/2;
        setLocation(xWindow, yWindow);
        panel=new JPanel();
        panel.setBackground(Color.YELLOW);
        goTextArea=new JTextArea(1,20);     
        goTextArea.setEditable(false);          
        font=new Font("Serif",Font.PLAIN, 14);  
        goTextArea.setFont(font);                   //sets goTextArea
        goTextArea.setBackground(Color.YELLOW);
        goTextArea.append("  Drive to the intersection of: ");
        panel.add(goTextArea);
        alphaBox=new JComboBox(alpha);
        letter=alphaBox.getSelectedItem().toString();   //for if there is no ItemEvent 
        alphaBox.addItemListener(
                new ItemListener()
                {
                    public void itemStateChanged(ItemEvent event)
                    {
                        if(event.getStateChange()==ItemEvent.SELECTED)
                            letter=alphaBox.getSelectedItem().toString();
                    }
                }
        );          
        panel.add(alphaBox);                //sets the asTextArea
        asTextArea=new JTextArea(1,5);
        asTextArea.append(" Street & ");
        asTextArea.setEditable(false);
        asTextArea.setFont(font);
        asTextArea.setBackground(Color.YELLOW);
        panel.add(asTextArea);
        numericBox=new JComboBox(numeric);
        number=numericBox.getSelectedItem().toString();
        numericBox.addItemListener(
                new ItemListener()
                {
                    public void itemStateChanged(ItemEvent event)   //for if there is no ItemEvent
                    {
                        if(event.getStateChange()==ItemEvent.SELECTED)
                            number=numericBox.getSelectedItem().toString();
                    }
                }
        );          
        panel.add(numericBox);
        nsTextArea=new JTextArea(1,4);      //sets the nsTextArea
        nsTextArea.append(" Street");
        nsTextArea.setEditable(false);
        nsTextArea.setFont(font);
        nsTextArea.setBackground(Color.YELLOW);
        panel.add(nsTextArea);

        Continue=new JButton("Continue");
        Continue.setToolTipText("Click this button to enter selected distination");
        panel.add(Continue);

        Cancel=new JButton("Cancel");
        Continue.setToolTipText("Click this button to cancel actions and return to menu");
        panel.add(Cancel);
        add(panel);

        HandlerClass handler=new HandlerClass();
        Continue.addActionListener(handler);
        Cancel.addActionListener(handler);
    }
    private class HandlerClass implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            Object source = event.getSource();
            if(source==Continue)
            {
                int hashletter=letter.hashCode();
                int hashnumber=number.hashCode();
                xGoTo=aSwitch(hashletter);
                yGoTo=nSwitch(hashnumber);
                alphaStreet=aStreetName(xGoTo);                 //sets Street names for the location of taxi
                numericStreet=nStreetName(yGoTo);
                dispose();
            }
            else if(source==Cancel)
            {
                dispose();
            }
        }
    }
    private String aStreetName(int xGoTo)
    {
        switch(xGoTo)
        {
        case 0:return "A Street";
        case 1:return "B Street";
        case 2:return "C Street";
        case 3:return "D Street";
        case 4:return "E Street";
        case 5:return "F Street";
        case 6:return "G Street";
        case 7:return "H Street";
        case 8:return "I Street";
        case 9:return "J Street";
        }
        return "K Street";
    }
    private String nStreetName(int yGoTo)
    {
        switch(yGoTo)
        {
        case 0:return "Zero Street";
        case 1:return "1st Street";
        case 2:return "2nd Street";
        case 3:return "3rd Street";
        case 4:return "4th Street";
        case 5:return "5th Street";
        case 6:return "6th Street";
        case 7:return "7th Street";
        case 8:return "8th Street";
        case 9:return "9th Street";
        }
        return "10th Street";
    }
    private int aSwitch(int hashletter)
    {
        switch(hashletter)
        {
        case 65:return 0;
        case 66:return 1;
        case 67:return 2;
        case 68:return 3;
        case 69:return 4;
        case 70:return 5;
        case 71:return 6;
        case 72:return 7;
        case 73:return 8;
        case 74:return 9;
        }
        return 10;
        /* hash table for alpha string array
        A: 65
        B: 66
        C: 67
        D: 68
        E: 69
        F: 70
        G: 71
        H: 72
        I: 73
        J: 74
        K: 75
         */
    }
    private int nSwitch(int hashnumber)
    {
        switch(hashnumber)
        {
        case 2781896:return 0;
        case 50770:return 1;
        case 51560:return 2;
        case 52645:return 3;
        case 53672:return 4;
        case 54633:return 5;
        case 55594:return 6;
        case 56555:return 7;
        case 57516:return 8;
        case 58477:return 9;
        }
        return 10;
        /*  hash table for numeric string array
            Zero: 2781896
            1st: 50770
            2nd: 51560
            3rd: 52645
            4th: 53672
            5th: 54633
            6th: 55594
            7th: 56555
            8th: 57516
            9th: 58477
            10th: 1509587
         */
    }

}
}

最佳答案

除了不便之外,我不确定 Dispatch 会给聚会带来什么。相反,我会关注单个 Cab 的状态,并根据需要多次复制它。在下面的示例中,Cab 具有可调节的颜色和里程表。 Timer 会定期递增里程表值。每个独立的 CabJTabbedPane 中占据一个单独的选项卡。

附录:回到问题“如何暂停 main()”,答案是“不要”。相反,使用单独的线程,例如由Timer管理的一个,用于推进模型的状态并更新显示。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.util.Random;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.Timer;

/** @see http://stackoverflow.com/questions/5617027 */
public class Cab extends JPanel {

    private static final Random random = new Random();
    private static final String format = "00000000";
    private static final DecimalFormat df = new DecimalFormat(format);
    private Hue hue = Hue.Yellow;
    private Timer timer;
    private JLabel odometer = new JLabel(df.format(0));
    private int km;

    public Cab() {
        this.setPreferredSize(new Dimension(320, 240));
        this.setBackground(hue.getColor());
        this.add(odometer);
        final JComboBox colorBox = new JComboBox();
        for (Hue h : Hue.values()) {
            colorBox.addItem(h);
        }
        colorBox.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Hue h = (Hue) colorBox.getSelectedItem();
                Cab.this.setBackground(h.getColor());
            }
        });
        this.add(colorBox);
        timer = new Timer(250, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                km += random.nextInt(100);
                odometer.setText(df.format(km));
            }
        });
        timer.start();
    }

    private enum Hue {

        Yellow(Color.yellow), Cyan(Color.cyan), Magenta(Color.magenta);
        private final Color color;

        private Hue(Color color) {
            this.color = color;
        }

        public Color getColor() {
            return color;
        }
    }

    private static void display() {
        JFrame f = new JFrame("Dispatch");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.add("Cab #1", new Cab());
        tabbedPane.add("Cab #2", new Cab());
        tabbedPane.add("Cab #3", new Cab());
        f.add(tabbedPane);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

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

            @Override
            public void run() {
                display();
            }
        });
    }
}

关于java - 如何暂停 main(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5617027/

相关文章:

java - Swing 并发和事件分发线程

android - 通过 Runnable 启动新 Activity

java - Spring Controller 中的正则表达式

java - 输入昵称后,用户不会显示在 recyclerView 中

java - Android 媒体编解码器 : How long does it take to decode and display one video frame

c - 线程同步

ios - Swift Core蓝牙 : Should CentralManager run in a separate thread?

java - 使用鼠标和图形缩放

java - 通过线程在 TextView 中闪烁光标

java - 为什么线程运行不一致?