编辑:我发现了我的问题,但仍然不知道为什么会发生这种情况,我还没有完成Mehran教授的在线讲座 萨哈米(斯坦福大学),也许如果我坚持下去,我会找到答案 讲座视频。
问题是我在按钮之前删除了其他组件方法 有效发布空间的方法,所以我应该把我的
JToggleButton
我的主要JFrame
方法之后的方法可以使用,但如果我的方法怎么办? 其他组件也继承了其他类吗?我应该首先使用哪种方法来使所有组件都有效?我会发现的 更多地练习java。感谢@Dan和@SebVb提供的答案和建议,对不起,如果这样的话 只是一个初学者的错误:)
我现在正在学习java一个月,并且已经有了一个简单的学习项目,但现在我在If语句中包含JToggleButton
,ItemEvent
和actionPerformed
时遇到了问题。
我在一周内搜索了在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
}
}
}
所以这是我的问题:
JToggleButton
?这是不可能的,我有一个错误
这样做的方法?actionPerformed
设置获取/设置
(Netbeans总是把它检查为错误),但为什么我可以为它做一个
BufferdImage
?Timer.stop()
停止捕获?或者我再次采取错误的做法?JPanel
并制作一个查看器
我的缓冲图片?P.S。对不起它有问题,我试着不发多个帖子,所以我发了多个问题的单一帖子。请注意我之前是否有答案,我老实说找不到它或者用错误的标签搜索它。
答案 0 :(得分:1)
我认为有一种更简单的方法可以做你想做的事。按订单提问
将主类与Window类分开后,您可以在任何位置重复使用Windows类。仅在主类
为什么你没有把你的JToggleButton私有,以及一个会访问他的状态的方法?另外,对于静态字段,Windows的所有实例都将共享相同的JToggleButton。
这是一个包含actionPerformed方法的匿名类。如果你想看到它,你必须创建一个内部类。
我觉得你的approch错了。使用一个线程,它会以特定的延迟启动重绘更好。如果您创建了一个扩展Runnable的类,您可以检查按钮的状态,然后执行相应的操作
你的JPanel在ActionListener里面,我从来没有见过,我认为它不会起作用。
在较短的版本中
答案 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
的当前实例和WindowScanner
中Scanner
的实例在同一个实例中声明。
注意:请使用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();
}
}