如何使用其中包含 actionPerformed 的 IF 语句从另一个 class 检查 class 中的 JToggleButton 状态?
How to check JToggleButton state in a class from another class using IF-statement that have actionPerformed within it?
EDIT : I found my problem but still don't have a clue for why this happen, I'm still not finished Online Lectures from Professor Mehran
Sahami (Stanford), maybe I'll find an answer if I push on on the
lecture videos.
The problem is I remove my other components methods before my button
method for efficient posting space, so I should put my JToggleButton
method after my main JFrame
method for it to work, but what if my
other components inherit other class too? Which method should I put first to make all of components works? That I'll found out with
practicing java more.
Thank you @Dan and @SebVb for answers and suggestions, sorry if this
just a beginners mistake :)
我正在学习 java 一个月,并且已经有了简单的学习项目,但现在我在 JToggleButton
、ItemEvent
和 actionPerformed
中遇到问题If 语句。
我已经搜索了一周的时间来寻找在 if 语句中使用 actionPerformed
的示例,该语句具有来自另一个 class 的 ItemEvent
,但我找不到相同的问题来产生工作结果。
我正在尝试制作一个 window 扫描仪,它只会在选择切换按钮时进行扫描,然后使用缓冲图像绘制 JPanel
(每 100 毫秒重新绘制一次)并在切换按钮被选中时将其丢弃取消选择,但我认为我的做法是错误的。我有一个主 class 和两个子 class,如下所示:
主要class:
public class WindowScanner {
public static void main(String[] args) {
new Window().setVisible(true);
}
}
Window class:
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);
}
}
扫描仪class:
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
}
}
}
所以这是我的问题:
- 我真的必须将 Main class 与 Window class 分开吗?
什么原因?
- 如何使 Scan 方法中的 if 语句识别我的状态
JToggleButton
来自 Window class?这不可能吗,我错了
方法来做到这一点?
- 在扫描仪 class 中,我无法为我的
actionPerformed
创建 get/set
(Netbeans 总是将其检查为错误),但为什么我可以为
BufferdImage
?
- 如果我不能得到第 3 个问题,我该如何做 If 语句
使用
Timer.stop()
停止捕获?还是我又走错了路?
- 我的
JPanel
in Scanner class 将被制作并成为一个查看器
对于我的缓冲图像?
P.S。很抱歉,问题太多了,我尽量不做多个 post,所以我做一个 post 有多个问题。如果之前有答案请通知我,老实说我找不到它或者用错误的标签搜索它。
我认为有一种更简单的方法可以做您想做的事。按顺序回答您的问题
将主要 class 与您的 Window class 分开可以让您 re-use 您的 Windows class随处可见。最好只在主 class
上初始化 GUI 对象
你为什么不让你的 JToggleButton 私有和一个可以访问他的状态的方法?此外,对于静态字段,Windows 的所有实例都将共享相同的 JToggleButton。
这是一个匿名的 class,其中包含您的 actionPerformed 方法。想看就得造个内class。
我认为你的做法是错误的。使用一个线程,它会以特定的延迟启动你的重绘会更好。如果您创建一个扩展 Runnable 的 class,您可以检查按钮的状态,然后执行适当的操作
您的 JPanel 在 ActionListener 中,我从未见过,我认为它无法工作。
在较短的版本中
- 放入您的 Window class 您的 JPanel、BufferedImage 和 JToggleButton
- 创建一个特定的线程来在选择 JToggleButton 时进行重新绘制
这是我认为您想做的事情的简单版本。可以对其进行编辑以包含您的变量,例如 boardCaptured
。这段代码主要描述了如何从不同的class.
中获取一个组件
Main.java(在一个 java 文件中包含所有 classes)
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();
}
}
这段特殊的代码使用 javax.swing.timer
中的计时器每秒将第二个 JFrame
中的背景颜色更改为随机颜色。此代码描述了如何从不同的 class.
获取组件或变量(如果您更改它)
主要是这些代码片段允许它。
1
public JToggleButton getCaptureButton() {
return captureButton;
}
这允许其他 classes 获取组件。
2
private WindowScanner wS;
Scanner(WindowScanner wS) {
...
this.wS = wS;
...
}
这使得 WindowScanner
的当前实例和 Scanner
中声明的 WindowScanner
的实例成为同一实例。
注意:考虑使用 public getters and setters
.
至于你列出的 5 个问题。
1) Do I really have to make Main class separated from Window class? What the reason?
在大多数情况下,是的。正如 SebVb 所说,这是一种很好的做法。但是,如果您希望将它们放在同一个 class.
中,您可以这样做
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) How to make my if statement in Scan method recognize state of my JToggleButton from Window class? Is it impossible and I had a wrong approach to do it?
您使用了错误的方法来执行此操作。请参阅我在上面放置的代码和代码片段,了解如何正确执行此操作。 (使用 public getters
。)
3) In Scanner class, i can't make a get/set for my actionPerformed (Netbeans always checked it as an error), but why I can make one for BufferdImage?
我不能完全确定你在问什么,但请查看我上面的代码,看看是否有帮助。如果它没有留下评论试图完全解释你的意思。
4) If I can't get question number 3 happen, how can I make If statement to stop capturing using Timer.stop()? Or am I in wrong approach again?
在我的代码中,我向您展示了这与 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) Do my JPanel in Scanner class would be produced and make a viewer for my buffered image?
同样,我不完全确定你在问什么,但这是我最好的猜测。你有两个选择。
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();
}
}
EDIT : I found my problem but still don't have a clue for why this happen, I'm still not finished Online Lectures from Professor Mehran Sahami (Stanford), maybe I'll find an answer if I push on on the lecture videos.
The problem is I remove my other components methods before my button method for efficient posting space, so I should put my
JToggleButton
method after my mainJFrame
method for it to work, but what if my other components inherit other class too? Which method should I put first to make all of components works? That I'll found out with practicing java more.Thank you @Dan and @SebVb for answers and suggestions, sorry if this just a beginners mistake :)
我正在学习 java 一个月,并且已经有了简单的学习项目,但现在我在 JToggleButton
、ItemEvent
和 actionPerformed
中遇到问题If 语句。
我已经搜索了一周的时间来寻找在 if 语句中使用 actionPerformed
的示例,该语句具有来自另一个 class 的 ItemEvent
,但我找不到相同的问题来产生工作结果。
我正在尝试制作一个 window 扫描仪,它只会在选择切换按钮时进行扫描,然后使用缓冲图像绘制 JPanel
(每 100 毫秒重新绘制一次)并在切换按钮被选中时将其丢弃取消选择,但我认为我的做法是错误的。我有一个主 class 和两个子 class,如下所示:
主要class:
public class WindowScanner {
public static void main(String[] args) {
new Window().setVisible(true);
}
}
Window class:
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);
}
}
扫描仪class:
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
}
}
}
所以这是我的问题:
- 我真的必须将 Main class 与 Window class 分开吗? 什么原因?
- 如何使 Scan 方法中的 if 语句识别我的状态
JToggleButton
来自 Window class?这不可能吗,我错了 方法来做到这一点? - 在扫描仪 class 中,我无法为我的
actionPerformed
创建 get/set (Netbeans 总是将其检查为错误),但为什么我可以为BufferdImage
? - 如果我不能得到第 3 个问题,我该如何做 If 语句
使用
Timer.stop()
停止捕获?还是我又走错了路? - 我的
JPanel
in Scanner class 将被制作并成为一个查看器 对于我的缓冲图像?
P.S。很抱歉,问题太多了,我尽量不做多个 post,所以我做一个 post 有多个问题。如果之前有答案请通知我,老实说我找不到它或者用错误的标签搜索它。
我认为有一种更简单的方法可以做您想做的事。按顺序回答您的问题
将主要 class 与您的 Window class 分开可以让您 re-use 您的 Windows class随处可见。最好只在主 class
上初始化 GUI 对象
你为什么不让你的 JToggleButton 私有和一个可以访问他的状态的方法?此外,对于静态字段,Windows 的所有实例都将共享相同的 JToggleButton。
这是一个匿名的 class,其中包含您的 actionPerformed 方法。想看就得造个内class。
我认为你的做法是错误的。使用一个线程,它会以特定的延迟启动你的重绘会更好。如果您创建一个扩展 Runnable 的 class,您可以检查按钮的状态,然后执行适当的操作
您的 JPanel 在 ActionListener 中,我从未见过,我认为它无法工作。
在较短的版本中
- 放入您的 Window class 您的 JPanel、BufferedImage 和 JToggleButton
- 创建一个特定的线程来在选择 JToggleButton 时进行重新绘制
这是我认为您想做的事情的简单版本。可以对其进行编辑以包含您的变量,例如 boardCaptured
。这段代码主要描述了如何从不同的class.
Main.java(在一个 java 文件中包含所有 classes)
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();
}
}
这段特殊的代码使用 javax.swing.timer
中的计时器每秒将第二个 JFrame
中的背景颜色更改为随机颜色。此代码描述了如何从不同的 class.
主要是这些代码片段允许它。
1
public JToggleButton getCaptureButton() {
return captureButton;
}
这允许其他 classes 获取组件。
2
private WindowScanner wS;
Scanner(WindowScanner wS) {
...
this.wS = wS;
...
}
这使得 WindowScanner
的当前实例和 Scanner
中声明的 WindowScanner
的实例成为同一实例。
注意:考虑使用 public getters and setters
.
至于你列出的 5 个问题。
1) Do I really have to make Main class separated from Window class? What the reason?
在大多数情况下,是的。正如 SebVb 所说,这是一种很好的做法。但是,如果您希望将它们放在同一个 class.
中,您可以这样做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) How to make my if statement in Scan method recognize state of my JToggleButton from Window class? Is it impossible and I had a wrong approach to do it?
您使用了错误的方法来执行此操作。请参阅我在上面放置的代码和代码片段,了解如何正确执行此操作。 (使用 public getters
。)
3) In Scanner class, i can't make a get/set for my actionPerformed (Netbeans always checked it as an error), but why I can make one for BufferdImage?
我不能完全确定你在问什么,但请查看我上面的代码,看看是否有帮助。如果它没有留下评论试图完全解释你的意思。
4) If I can't get question number 3 happen, how can I make If statement to stop capturing using Timer.stop()? Or am I in wrong approach again?
在我的代码中,我向您展示了这与 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) Do my JPanel in Scanner class would be produced and make a viewer for my buffered image?
同样,我不完全确定你在问什么,但这是我最好的猜测。你有两个选择。
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();
}
}