Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 跨类使用方法?_Java_Swing_Timer_Jbutton - Fatal编程技术网

Java 跨类使用方法?

Java 跨类使用方法?,java,swing,timer,jbutton,Java,Swing,Timer,Jbutton,我有两个类,一个是计时器,它在特定时间打印命令,另一个是GUI,它包含一个用于计时器的启动按钮。 我试图让GUI中的开始/停止按钮能够使用timer.start();和计时器。停止();计时器类中使用的方法 我已经在这个网站上搜索了很多次,并且阅读了很多Oracle文档,但是我仍然不清楚这在我的案例中是如何工作的 这是完整计时器类: package tests; import java.awt.event.ActionEvent; import java.awt.event.ActionLis

我有两个类,一个是计时器,它在特定时间打印命令,另一个是GUI,它包含一个用于计时器的启动按钮。 我试图让GUI中的开始/停止按钮能够使用timer.start();和计时器。停止();计时器类中使用的方法

我已经在这个网站上搜索了很多次,并且阅读了很多Oracle文档,但是我仍然不清楚这在我的案例中是如何工作的

这是完整计时器类:

package tests;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class TimeKeeper extends JFrame
{
private Timer timer;
private int delay = 1000; // every 1 second
private static final long serialVersionUID = 1L;
private int counter = 0;
private int[] times = {};
private String[] commands = {};


public TimeKeeper()
{
    ActionListener action = new ActionListener()
    {   
        @Override
        public void actionPerformed(ActionEvent event)
        {
            System.out.println(counter);
            counter = counter+1;

            if (counter == times[0]) {
                new SayText();
                SayText.say(commands[0]);
            }
            if (counter == times[1]){
                SayText.say(commands[1]);
            }
            else
            {
                timer.stop();
            }
        }
    };

    timer = new Timer(delay, action);
    timer.setInitialDelay(0);
    timer.start(); //MOVE THIS TO START BUTTON IN OTHER CLASS
}

public static void main(String[] args)
{
    SwingUtilities.invokeLater(new Runnable()
    {
        @Override
        public void run()
        {
            new TimeKeeper();
        }
    });
}
}
下面是GUI类的一个简短版本

//package name
//imports

public class TwoPlayer {
//variable initializations

public TwoPlayer(){
//mainFrame specs

//Jlabel

//Some JFields   

JButton button1 = new JButton("Start/Stop");   
button1.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {

    }
  }); 

//Another button 
//Another button
//Another button

//JPanel creation

//add components to mainframe

}
}

为了保持禁用状态,我至少有一个带有停止和启动方法的接口,在Timekeeper类上实现该接口,实现独立的方法来执行timer.start()/timer.start(),然后将Timekeeper实例作为接口传递到GUI中。实际上,这相当简单,但是GUI类可以接受任何您想要实现启动/停止功能的东西。

为了保持禁用状态,我至少有一个带有停止和启动方法的接口,在Timekeeper类上实现该接口,实现独立的方法来执行timer.start()/timer.start()然后将计时器实例作为接口传递到GUI中。实际上,非常简单,但是GUI类可以接受任何您想要实现启动/停止功能的内容。

使用方法的基本方法是创建类的实例,并使用如下语句

Timekeeper timekeeper = new Timekeeper();
在某些类中(如
TwoPlayer
)。然后,在该变量的范围内,您可以在您创建的实例上“调用”方法,如

// ...
timekeeper.start();
// ... other code in here
timekeeper.stop();
另外,因为我看到您已经在timekeeper类中实现了ActionListener,所以可以将timekeeper实例传递给按钮的
setActionListener()
方法

JButton button = new JButton("start timer");
button.setActionListener(timekeeper);
然后单击该按钮将在该计时器实例上调用
actionPerformed()
方法


请注意,由于计时器类实现了ActionListener,因此它在某种程度上是一个GUI类。这只是意味着您只能在一个地方使用该类,在这个地方使用Swing操作是有意义的。

使用方法的基本方法是创建一个类的实例,并使用如下语句

Timekeeper timekeeper = new Timekeeper();
在某些类中(如
TwoPlayer
)。然后,在该变量的范围内,您可以在您创建的实例上“调用”方法,如

// ...
timekeeper.start();
// ... other code in here
timekeeper.stop();
另外,因为我看到您已经在timekeeper类中实现了ActionListener,所以可以将timekeeper实例传递给按钮的
setActionListener()
方法

JButton button = new JButton("start timer");
button.setActionListener(timekeeper);
然后单击该按钮将在该计时器实例上调用
actionPerformed()
方法


请注意,由于计时器类实现了ActionListener,因此它在某种程度上是一个GUI类。这只意味着你只能在一个地方使用这个类,让它通过一个摆动动作来操作是有意义的。

我想说你的设计缺乏一点,哦,好吧,设计

让我们退一步,TwoPlayer类有什么权利修改计时员类?事实上,没有,这不是它的责任。目前,它只想让计时器启动和停止。它不在乎怎么做

同样地,
TimeKeeper
类关心的是管理
计时器

这是一个很好的例子,说明了为什么不应该从
JFrame
进行扩展,因为它将您锁定在一个用例中,这几乎不可能扩展或扩展功能

那么,答案是什么?好吧,让我们后退一步,看看你如何重新设计这个……/P>
计时器
负责管理
计时器
,为此,我们需要为其他类提供启动和停止该
计时器
(可能还需要其他功能,但我坚持基本要求)。此外,它应该从更灵活的东西扩展,可能是
JPanel
,这将使它更易于重用,并在需要时进行扩展

public class TimeKeeper extends JPanel {

    private Timer timer;
    private int delay = 1000; // every 1 second
    private int counter = 0;
    private int[] times = {};
    private String[] commands = {};

    public TimeKeeper() {
        ActionListener action = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                System.out.println(counter);
                counter = counter + 1;

                if (counter == times[0]) {
                    //new SayText();
                    //SayText.say(commands[0]);
                }
                if (counter == times[1]) {
                    //SayText.say(commands[1]);
                } else {
                    timer.stop();
                }
            }
        };

        timer = new Timer(delay, action);
        timer.setInitialDelay(0);
    }

    public void start() {
        timer.start();
    }

    public void stop() {
        timer.stop();
    }

}
现在,我们需要某种方式让玩家与计时员互动,为此,我们需要一个开始/停止按钮。您可以使用
JToggleButton
或以其他方式管理单个按钮的状态,但为简单起见,我使用了两个

public static class ControlsPane extends JPanel {

    public static final String START_COMMAND = "Start";
    public static final String STOP_COMMAND = "Stop";

    private JButton start;
    private JButton stop;

    public ControlsPane() {
        start = new JButton(START_COMMAND);
        stop = new JButton(STOP_COMMAND);
        setLayout(new GridBagLayout());
        add(start);
        add(stop);
    }

    public void addActionListener(ActionListener listener) {
        start.addActionListener(listener);
        stop.addActionListener(listener);
    }

    public void removeActionListener(ActionListener listener) {
        start.removeActionListener(listener);
        stop.removeActionListener(listener);
    }

}
现在,这个类所做的只是提供了两个按钮(在一个面板上)以及添加/删除
ActionListener
的功能,当单击一个或另一个按钮时,会通知该按钮

请注意,这个类没有实际的方法可以与
计时器
交互,它的唯一责任是在按下一个或另一个按钮时生成通知,实际做某事的责任是与其他人一起

让我们把它放在一起

TimeKeeper timeKeeper = new TimeKeeper();
ControlsPane controlsPane = new ControlsPane();
controlsPane.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        switch (e.getActionCommand()) {
            case ControlsPane.START_COMMAND:
                timeKeeper.start();
                break;
            case ControlsPane.STOP_COMMAND:
                timeKeeper.stop();
                break;
        }
    }
});

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(timeKeeper);
frame.add(controlsPane, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
因此,我们创建了
TimeKeeper
controlspan
的一个实例。我们将一个
ActionListener
注册到
ControlsPane
,它根据
ControlsPane
生成的事件调用
TimeKeeper
start
stop
方法,然后我们将两个面板添加到屏幕上

这是一个非常松散的示例a和


你可能想看一看,想了解更多细节,我想说你的设计缺少一点设计

让我们退一步,TwoPlayer类有什么权利修改计时员类?事实上,没有,这不是它的责任。目前,它只想让计时器启动和停止。它不在乎怎么做

同样地,
TimeKeeper
类关心的是管理
计时器

这是一个很好的例子,说明了为什么不应该从
JFrame
进行扩展,它将您锁定在一个用例中,这使得它成为下一个