我对java.awt.Button
有以下代码:
Button btn = new Button("abcde");
btn.addActionListener((ActionEvent e) ->
{
String s = btn.getLabel().toUpperCase();
btn.setLabel(s);
});
我需要将btn.addActionListener
中的代码移至public static void main(String[] args)
,如下所示(使用伪代码):
Button btn = new Button("abcde");
btn.addActionListener((ActionEvent e) ->
{
notify_main()_that_button_had_been_clicked();
});
public static void main(String[] args)
{
block_until_button_clicked();
String s = UI.getButton().getLabel();
s = s.toUpperCase();
UI.getButton().setLabel(s);
}
我知道有更好的GUI开发解决方案,但仅限于将AWT用于UI。
由于法律限制,我无权更改上述内容,也无法提供有关真实代码的详细信息。
为了补救上述问题,我将提交以下MVCE。请基于此回答:
import java.awt.Frame;
import java.awt.Button;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class ResponsiveUI extends Frame
{
public final Button btn = new Button("abcde");
public ResponsiveUI()
{
add(btn);
btn.addActionListener((ActionEvent e) ->
{
String s = btn.getLabel().toUpperCase();
btn.setLabel(s);
});
}
public static void main(String[] args)
{
ResponsiveUI rui = new ResponsiveUI();
rui.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent we)
{
System.exit(0);
}
});
rui.setSize(250, 150);
rui.setResizable(false);
rui.setVisible(true);
}
}
我已经广泛使用Google,并且能够找到一些有用的链接。
join()
)。wait()
和notify()
似乎是正确的选择。EventQueue.InvokeAndWait
。下面是修改后的MVCE:
import java.awt.Frame;
import java.awt.Button;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.InvocationTargetException;
public class ResponsiveUI extends Frame
{
public final Object lock = new Object(); // POINT #2 : signaling mechanism
public final Button btn = new Button("abcde");
public ResponsiveUI()
{
add(btn);
btn.addActionListener((ActionEvent e) ->
{
// POINT #2 : signal the main() thread that button is clicked
synchronized (lock)
{
lock.notify();
}
});
}
public static void main(String[] args)
{
ResponsiveUI rui = new ResponsiveUI();
// POINT #1: put UI into separate thread, so we can keep it responsive
// POINT #1: I still do not know how to properly join() (it works OK though)
Runnable r = () ->
{
rui.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent we)
{
System.exit(0);
}
});
rui.setSize(250, 150);
rui.setResizable(false);
rui.setVisible(true);
};
EventQueue.invokeLater(r);
try
{
synchronized (rui.lock) // POINT #2
{ // POINT #2
rui.lock.wait(); // POINT #2 : wait for button press
final Button b = new Button(); // POINT #4 : EventQueue uses final local variables
// store text into temp button (ugly but works)
EventQueue.invokeAndWait(() -> // POINT #4
{
b.setLabel(rui.btn.getLabel());
});
// we could do all kind of things, but for illustrative purpose just transform text into upper case
EventQueue.invokeAndWait(() -> // POINT #3 :
{
rui.btn.setLabel(b.getLabel().toUpperCase());
});
}
}
catch (InterruptedException | InvocationTargetException ex)
{
System.out.println("Error : " + ex);
}
}
}
一般方法是,您需要与main
方法和ActionListener
实现同时共享一些锁或信号灯。拥有共享信号量后,main
方法可以阻止(等待)该信号量,并且ActionListener
可以通知该信号量。
使用伪代码:
Lock lock = new Lock();
Button btn = new Button("abcde");
btn.addActionListener((ActionEvent e) -> {
lock.notify();
});
public static void main(String[] args) {
lock.waitUntilNotified();
String s = UI.getButton().getLabel();
s = s.toUpperCase();
UI.getButton().setLabel(s);
}
我已将确切的信号量实现留给您,因为您的应用程序的性质将决定哪种机制最有效。例如,也许您想使用一个简单的对象并在其上调用wait
和notify
方法,或者,如果您需要对加载到该队列中的元素(即项)进行处理,则可以使用阻塞队列。排队,按下按钮表示排队的物品现在应处理)。
您可以在此处找到有关如何实现wait
和notify
方法的信息:
共享锁可能很困难,因为在main
方法中,不能将锁作为方法参数传递。一种简单的方法(在此上下文之外不是首选)是将锁创建为static
变量:
public class Application {
public static final Lock LOCK = new Lock();
public static void main(String[] args) {
LOCK.waitUntilNotified();
String s = UI.getButton().getLabel();
s = s.toUpperCase();
UI.getButton().setLabel(s);
}
}
在其他班级:
public class SomeOtherClass {
Button btn = new Button("abcde");
btn.addActionListener((ActionEvent e) -> {
Application.LOCK.notify();
});
}
请记住,Lock
只是伪代码,应该用您决定使用的锁的任何实现方式替换。