Java,swing,wait(),notify()的问题
我是Java的新手,我尝试制作一个简单的基于转弯的游戏只是为了获得一些经验。尽管我做了很多Google的研究,但我遇到了一个无法独自解决的问题……也许我无法解决它,因为我的理解不够好。
问题是我不知道如何为玩家进行程序。我的意思是,我想使一些jbuttons活跃起来,直到按下其中一个,然后为另一个球员做同样的事情。由于程序很安静,因此我删除了与问题无关的80%的代码,并在下面发布了其余的代码。
该代码分为课程,由于问题的同谋,我想以这种方式保持这种方式(剩余的80%代码)。为了更好地查看程序的操作,我每次激活时都会制作按钮以更改颜色。不幸的计划一旦达到notify()方法就停止工作。
谁能帮忙?先感谢您。
测试器:
package grafika;
import javax.swing.SwingUtilities;
public class OknoTester {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Okno main = new Okno();
}
// ctr + spacja - podpowiedzi w Eclipsie
});
}
}
主类
package grafika;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JSplitPane;
public class Okno {
private JFrame frame;
public Okno()
{
initialize();
}
private void initialize()
{
// NEW WINDOW
frame = new JFrame();
frame.setTitle("Gra w statki");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(new Dimension(600,100));
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
// DIVIDE WINDOW
JSplitPane splitPaneH = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT );
frame.getContentPane().add(splitPaneH);
splitPaneH.setDividerSize(0);
// INITIALIZATION OF SITES
Komputer left = new Komputer();
Komputer right = new Komputer();
// SHOWPANELS
splitPaneH.setLeftComponent(left.Pokaz());
splitPaneH.setRightComponent(right.Pokaz());
splitPaneH.setResizeWeight(0.5);
splitPaneH.setEnabled(false);
// ALLOW TO USE ONE OF LEFT OR RIGHT SET OF BUTTONS
while(true)
{
left.CzytajRuch();
right.CzytajRuch();
}
}
}
带按钮的类
package grafika;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Komputer implements ActionListener{
private JButton b1 = new JButton("1");
private JButton b2 = new JButton("2");
private JPanel panel = new JPanel();
private Boolean aktywny = false;
public void CzytajRuch()
{
aktywny = true;
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public JPanel Pokaz()
{
return panel;
}
public Komputer() {
GridLayout gl = new GridLayout(1,2);
panel.setLayout(gl);
panel.add(b1);
b1.addActionListener(this);
b2.addActionListener(this);
panel.add(b2);
}
public void actionPerformed(ActionEvent ae) {
if(aktywny == true)
{
JButton pb = (JButton) ae.getSource();
if (pb == b1)
b1.setBackground(new Color((int)(Math.random() * 0x1000000)));
if (pb == b2)
b2.setBackground(new Color((int)(Math.random() * 0x1000000)));
aktywny = false;
notify();
}
}
}
感谢您的时间阅读此书。我会批准任何帮助。
I am quiet new to Java and I try to make a simple turn-based game just to gain some experience. I have encounter a problem which I cannot solve on my own, despite I did quiet a lot of google research... Probably I cannot solve it because I don't understand it well enough.
The problem is I don't know how to make a program making turns for player. I mean I would like to make a few Jbuttons active till one of them is pressed and then do the same for another player. Since program is quiet complicated, I deleted 80% of code which is unrelated to problem and I post the rest of it below.
The code is divided into classes and I would like to keep it this way due to complicity of a problem (remaining 80% of code). In order to see better what programs do, I made buttons to change colours each time when activated. Unfortunatelly program stops working as soon as it hits notify() method.
Can anyone help? Thank you in advance.
Tester:
package grafika;
import javax.swing.SwingUtilities;
public class OknoTester {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Okno main = new Okno();
}
// ctr + spacja - podpowiedzi w Eclipsie
});
}
}
Main class
package grafika;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JSplitPane;
public class Okno {
private JFrame frame;
public Okno()
{
initialize();
}
private void initialize()
{
// NEW WINDOW
frame = new JFrame();
frame.setTitle("Gra w statki");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(new Dimension(600,100));
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
// DIVIDE WINDOW
JSplitPane splitPaneH = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT );
frame.getContentPane().add(splitPaneH);
splitPaneH.setDividerSize(0);
// INITIALIZATION OF SITES
Komputer left = new Komputer();
Komputer right = new Komputer();
// SHOWPANELS
splitPaneH.setLeftComponent(left.Pokaz());
splitPaneH.setRightComponent(right.Pokaz());
splitPaneH.setResizeWeight(0.5);
splitPaneH.setEnabled(false);
// ALLOW TO USE ONE OF LEFT OR RIGHT SET OF BUTTONS
while(true)
{
left.CzytajRuch();
right.CzytajRuch();
}
}
}
Class with buttons
package grafika;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Komputer implements ActionListener{
private JButton b1 = new JButton("1");
private JButton b2 = new JButton("2");
private JPanel panel = new JPanel();
private Boolean aktywny = false;
public void CzytajRuch()
{
aktywny = true;
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public JPanel Pokaz()
{
return panel;
}
public Komputer() {
GridLayout gl = new GridLayout(1,2);
panel.setLayout(gl);
panel.add(b1);
b1.addActionListener(this);
b2.addActionListener(this);
panel.add(b2);
}
public void actionPerformed(ActionEvent ae) {
if(aktywny == true)
{
JButton pb = (JButton) ae.getSource();
if (pb == b1)
b1.setBackground(new Color((int)(Math.random() * 0x1000000)));
if (pb == b2)
b2.setBackground(new Color((int)(Math.random() * 0x1000000)));
aktywny = false;
notify();
}
}
}
Thank you for your time reading this. I would apprieciate any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
秋千是单线螺纹。这意味着您不能在派遣线程的事件上执行长时间的运行或阻止操作。
如果您尝试在EDT的上下文中使用
等待
,它不仅会阻止EDT并防止处理过任何进一步的更新或事件,而且您将永远无法使用Notify
notify < /code>(从EDT内部)唤醒它。
等待
和notify
是从不同的线程上下文(不是在同一线程上下文中)使用的,请参见 Swing中的并发有关更多详细信息。
您需要做的是监视某种“代币”。只有拥有“代币”的球员才能做任何事情。
您可以通过某种“控制器”来将其提炼为简单的标志。每次玩家做某事时,控制器都会检查播放器当前是否处于活动状态时,处理动作,然后将活动播放器切换到其他玩家,例如...
Swing is single threaded. This means you can't perform long running or blocking operations on the Event Dispatching Thread.
If you try and use
wait
within the context of the EDT, not only will it block the EDT and prevent any further updates or events from been processed, you will never be able to usenotify
(from within the EDT) to wake it.wait
andnotify
are meant to be used from different thread contexts (not from within the same thread context)See Concurrency in Swing for some more details.
What you need to do, is monitor some kind of "token". Only the player with who holds the "token" can do anything.
You can distill this down to a simple flag is maintained by some kind "controller". Each time a player does something, the controller checks to see if the player is currently active or not, processes the action and the switches the active player to a different player, for example...