如何使用其中包含actionPerformed的IF语句从另一个类检查类中的JToggleButton状态?

时间:2016-01-19 08:55:49

标签: java swing if-statement jtogglebutton

  

编辑:我发现了我的问题,但仍然不知道为什么会发生这种情况,我还没有完成Mehran教授的在线讲座   萨哈米(斯坦福大学),也许如果我坚持下去,我会找到答案   讲座视频。

     

问题是我在按钮之前删除了其他组件方法   有效发布空间的方法,所以我应该把我的JToggleButton   我的主要JFrame方法之后的方法可以使用,但如果我的方法怎么办?   其他组件也继承了其他类吗?我应该首先使用哪种方法来使所有组件都有效?我会发现的   更多地练习java。

     

感谢@Dan和@SebVb提供的答案和建议,对不起,如果这样的话   只是一个初学者的错误:)

我现在正在学习java一个月,并且已经有了一个简单的学习项目,但现在我在If语句中包含JToggleButtonItemEventactionPerformed时遇到了问题。

我在一周内搜索了在if语句中使用actionPerformed的示例,其中ItemEvent来自另一个类,但我找不到相同的问题来生成工作结果。

我正在尝试制作一个窗口扫描器,只扫描选择了切换按钮然后使用缓冲图像绘制JPanel(每100毫秒重新绘制一次)并在取消选择切换按钮时将其处理掉,但我认为我的这样做的方法是错误的。我有一个主类和两个这样的子类:

主要课程:

public class WindowScanner {
    public static void main(String[] args) {
        new Window().setVisible(true);
    }
}

窗口类:

class Window extends JFrame {
    static JToggleButton captureButton = new JToggleButton("CAPTURE");

    @SuppressWarnings("Convert2Lambda")
    public Window() {
        // JFrame looks codes

        /** EDIT: these components method should be written after button method
        * JPanel looks codes
        * JLabel looks codes
        * END EDIT
        */

        add(captureButton);
        // capture button default looks code
        ItemListener captureListener = new ItemListener(){
            @Override
            public void itemStateChanged(ItemEvent captureButtonEvent) {
                int captureState = captureButtonEvent.getStateChange();
                if(captureState == ItemEvent.SELECTED){
                    // capture button SELECTED looks code
                    System.out.println("capture button is selected");
                } else if(captureState == ItemEvent.DESELECTED){
                    // capture button DESELECTED looks code
                    System.out.println("capture button is deselected");
                }
            }
        }; captureButton.addItemListener(captureListener);
    }
}

扫描仪课程:

public class Scanner extends Window {

    private static BufferedImage boardCaptured;
    static int delay = 100;

    protected BufferedImage boardScanned(){
        return boardCaptured;
    }

    @SuppressWarnings("Convert2Lambda")
    public static void Scan() {
        if (captureButton.isSelected()) {
            ActionListener taskPerformer = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent captureEvent) {
                    try {
                        // capturing method
                    } catch (AWTException error) {
                        // AWTException error method
                    }
                    // is this the right place to put JPanel code?
                    JPanel panel = new JPanel();
                    boardCaptured = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
                    Graphics2D graphic = boardCaptured.createGraphics();
                    panel.setSize(500,500);
                    panel.paint(graphic);
                    panel.revalidate();
                    panel.repaint();
                }
            }; new Timer(delay, taskPerformer).start();
        } else {
            // this suppose to end capturing if capture button isSelected() == false
        }
    }
}

所以这是我的问题:

  1. 我真的必须将Main类与Window类分开吗? 是什么原因?
  2. 如何在Scan方法中使用if语句识别我的状态 来自Window类的JToggleButton?这是不可能的,我有一个错误 这样做的方法?
  3. 在Scanner课程中,我无法为actionPerformed设置获取/设置 (Netbeans总是把它检查为错误),但为什么我可以为它做一个 BufferdImage
  4. 如果我不能发出第3号问题,我该怎么做If语句 使用Timer.stop()停止捕获?或者我再次采取错误的做法?
  5. 是否会生成Scanner类中的JPanel并制作一个查看器 我的缓冲图片?
  6. P.S。对不起它有问题,我试着不发多个帖子,所以我发了多个问题的单一帖子。请注意我之前是否有答案,我老实说找不到它或者用错误的标签搜索它。

2 个答案:

答案 0 :(得分:1)

我认为有一种更简单的方法可以做你想做的事。按订单提问

  1. 将主类与Window类分开后,您可以在任何位置重复使用Windows类。仅在主类

  2. 上初始化GUI对象是一个很好的实践
  3. 为什么你没有把你的JToggleButton私有,以及一个会访问他的状态的方法?另外,对于静态字段,Windows的所有实例都将共享相同的JToggleButton。

  4. 这是一个包含actionPerformed方法的匿名类。如果你想看到它,你必须创建一个内部类。

  5. 我觉得你的approch错了。使用一个线程,它会以特定的延迟启动重绘更好。如果您创建了一个扩展Runnable的类,您可以检查按钮的状态,然后执行相应的操作

  6. 你的JPanel在ActionListener里面,我从来没有见过,我认为它不会起作用。

  7. 在较短的版本中

    1. 将您的JPanel,BufferedImage和JToggleButton
    2. 放入您的Window类
    3. 创建特定线程以在选择JToggleButton时进行重新绘制

答案 1 :(得分:1)

这是我认为你想要做的简单版本。可以对其进行编辑以包含变量,例如boardCaptured。这段代码主要描述了如何从不同的类中获取组件。

Main.java (包含一个java文件中的所有类)

import javax.swing.JLabel;
import javax.swing.JToggleButton;
import javax.swing.JFrame;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.Timer;

class WindowScanner extends JFrame {
    private JLabel label;
    private JToggleButton captureButton = new JToggleButton("CAPTURE");

    WindowScanner() {
        super("Fist Window");
        setSize(150, 100);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLayout(new FlowLayout());
        add(captureButton);
        setVisible(true);

        new Scanner(this);
    }

    public JToggleButton getCaptureButton() {
        return captureButton;
    }
}

class Scanner extends JFrame {
    private WindowScanner wS;
    private int delay = 1000;
    private Timer t = new Timer(delay, new taskPerformer());

    Scanner(WindowScanner wS) {
        super("Second Window");
        this.wS = wS;
        setBounds(200,0,500,500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        wS.getCaptureButton().addActionListener(new taskPerformer());
    }

    private Color randomColor() {
        Random rand = new Random();
        float r = rand.nextFloat() / 2f ;
        float g = rand.nextFloat() / 2f;
        float b = rand.nextFloat() / 2f;
        Color randomColor = new Color(r, g, b);
        return randomColor;
    }

    private class taskPerformer implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent captureEvent) {
            if(captureEvent.getSource() == wS.getCaptureButton()) {
                if (wS.getCaptureButton().isSelected()) {
                    t.start();
                } else {
                    t.stop();
                }
            }

            if(captureEvent.getSource() == t) {
                getContentPane().setBackground(randomColor());
                revalidate();
                repaint();
            }
        }
    }
}

public class Main {
    public static void main (String[] args) {
        new WindowScanner();
    }
}

这段特殊的代码使用来自JFrame的计时器,每秒将第二个javax.swing.timer中的背景颜色更改为随机颜色。此代码描述了如何从其他类获取组件或变量(如果更改)。

主要是这些代码片段允许它。

<强> 1

public JToggleButton getCaptureButton() {
    return captureButton;
}

这允许其他类获取组件。

<强> 2

private WindowScanner wS;

Scanner(WindowScanner wS) {
    ...
    this.wS = wS;
    ...
}

这使WindowScanner的当前实例和WindowScannerScanner的实例在同一个实例中声明。

注意:请使用public getters and setters

至于您列出的5个问题。

  

1)我真的必须将Main类与Window类分开吗?是什么原因?

在大多数情况下,是的。正如SebVb所说,这是一种很好的做法。但是,如果您希望将它们放在同一个类中,则可以执行此类操作。

import javax.swing.JToggleButton;
import javax.swing.JFrame;
import java.awt.FlowLayout;

public class Test extends JFrame {
    private JToggleButton captureButton = new JToggleButton("CAPTURE");

    Test() {
        super("Fist Window");
        setSize(150, 100);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLayout(new FlowLayout());
        add(captureButton);
        setVisible(true);
    }

    public JToggleButton getCaptureButton() {
        return captureButton;
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                Test frame = new Test();
            }
        });
    }
}
  

2)如何在Scan方法中使用if语句从Window类中识别我的JToggleButton的状态?这是不可能的,我做错了吗?

您使用了错误的方法来执行此操作。请参阅上面提到的代码和代码片段,了解如何正确执行此操作。 (使用public getters。)

  

3)在Scanner类中,我无法为我的actionPerformed设置get / set(Netbeans总是将其检查为错误),但为什么我可以为BufferdImage创建一个?

我无法完全说出我确定你在问什么,但请看上面的代码,看看是否有帮助。如果它没有留下评论试图完全解释你的意思。

  

4)如果我无法解决第3个问题,如何使用Timer.stop()使If语句停止捕获?或者我再次采取错误的做法?

在我的代码中,我向您展示了这与JToggleButton的关系。请参阅下面的代码片段

private class taskPerformer implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent captureEvent) {
        if(captureEvent.getSource() == wS.getCaptureButton()) {
            if (wS.getCaptureButton().isSelected()) {
                t.start();
            } else {
                t.stop();
            }
        }

        if(captureEvent.getSource() == t) {
            getContentPane().setBackground(randomColor());
            revalidate();
            repaint();
        }
    }
}

此代码说明JToggleButton如果选中了ActionEvent,则启动计时器t.start(),或者如果未选择,则停止计时器t.stop()

  

5)我是否会生成Scanner类的JPanel并为我的缓冲图像制作一个查看器?

我再也不确定你在问什么,但这是我最好的猜测。你有两个选择。

<强> 1

boardCaptured直接放在框架上。

paint(graphic);
repaint();
revaildate();

<强> 2

JPanel

之外创建一个ActionListener
JPanel panel = new JPanel()
boardCaptured = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphic = boardCaptured.createGraphics();
panel.setSize(500,500);
panel.paint(graphic);
add(panel);

private class taskPerformer implements ActionListener {
    if(captureEvent.getSource() == t) {
        panel.paint(graphic);
        panel.revalidate();
        panel.repaint();
    }
}