在 Java 中使用 wait()
Use wait() in Java
我需要在新线程中创建一个新的 JFrame。当我关闭 JFrame 时,我需要 return 一个字符串。
问题是 wait() 方法 "doesn't wait" new Thread 的 "notify()"。
谢谢你的回答。
import java.awt.Button;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class FinestraTesto extends Thread {
JLabel jdescr;
JTextArea testo;
JPanel pannelloTasti;
JButton bottoneInvio;
JButton bottoneAnnulla;
JFrame finestraTestuale;
JPanel panAll;
static Boolean pause = true;
String titolo;
String descrizione;
private static String testoScritto = "";
public String mostra() {
// Create a new thread
Thread th = new Thread(new FinestraTesto(titolo, descrizione));
th.start();
synchronized (th) {
try {
// Waiting the end of th.
th.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return testoScritto;
}
public void run() {
synchronized (this) {
System.out.println("Fatto 1 thread");
finestraTestuale = new JFrame(titolo);
finestraTestuale.setPreferredSize(new Dimension(600, 200));
finestraTestuale.setSize(600, 200);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
finestraTestuale.setLocation(
dim.width / 2 - finestraTestuale.getSize().width / 2,
dim.height / 2 - finestraTestuale.getSize().height / 2);
panAll = new JPanel();
panAll.setLayout(new BoxLayout(panAll, BoxLayout.Y_AXIS));
bottoneInvio = new JButton("Conferma");
bottoneAnnulla = new JButton("Annulla");
pannelloTasti = new JPanel();
testo = new JTextArea();
testo.setPreferredSize(new Dimension(550, 100));
testo.setSize(550, 100);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(testo);
jdescr = new JLabel(descrizione);
jdescr.setPreferredSize(new Dimension(550, 50));
jdescr.setSize(550, 50);
pannelloTasti.setLayout(new BoxLayout(pannelloTasti,
BoxLayout.X_AXIS));
pannelloTasti.add(bottoneInvio);
pannelloTasti.add(bottoneAnnulla);
panAll.add(jdescr);
panAll.add(scrollPane);
panAll.add(pannelloTasti);
finestraTestuale.add(panAll);
bottoneInvio.addActionListener(new ActionListener() {
@Override
/**
* metodo attivato quando c'è un'azione sul bottone
*/
public void actionPerformed(ActionEvent arg0) {
testoScritto = testo.getText();
pause = false;
finestraTestuale.show(false);
// send notify
notify();
}
});
bottoneAnnulla.addActionListener(new ActionListener() {
@Override
/**
* metodo attivato quando c'è un'azione sul bottone
*/
public void actionPerformed(ActionEvent arg0) {
pause = false;
testoScritto = "";
finestraTestuale.show(false);
// send notify
notify();
}
});
finestraTestuale.show();
}
}
public FinestraTesto(String titolo, String descrizione) {
this.titolo = titolo;
this.descrizione = descrizione;
}
}
您最好使用 Synchronizers 而不是 wait
和 notify
。它们更受欢迎,因为简单和安全。
Given the difficulty of using wait and notify correctly, you should
use the higher-level concurrency utilities instead.
Effective Java (2nd Edition), Item 69
我用这个 class 解决了:
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class CustomDialog
{
private List<JComponent> components;
private String title;
private int messageType;
private JRootPane rootPane;
private String[] options;
private int optionIndex;
private JTextArea testo;
public CustomDialog(String title,String descrizione)
{
components = new ArrayList<>();
setTitle(title);
setMessageType(JOptionPane.PLAIN_MESSAGE);
addMessageText(descrizione);
testo = new JTextArea();
testo.setPreferredSize(new Dimension(550, 100));
testo.setSize(550, 100);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(testo);
addComponent(scrollPane);
setRootPane(null);
setOptions(new String[] { "Send", "Cancel" });
setOptionSelection(0);
}
public void setTitle(String title)
{
this.title = title;
}
public void setMessageType(int messageType)
{
this.messageType = messageType;
}
public void addComponent(JComponent component)
{
components.add(component);
}
public void addMessageText(String messageText)
{
components.add(new JLabel(messageText));
}
public void setRootPane(JRootPane rootPane)
{
this.rootPane = rootPane;
}
public void setOptions(String[] options)
{
this.options = options;
}
public void setOptionSelection(int optionIndex)
{
this.optionIndex = optionIndex;
}
public String show()
{
int optionType = JOptionPane.OK_CANCEL_OPTION;
Object optionSelection = null;
if(options.length != 0)
{
optionSelection = options[optionIndex];
}
int selection = JOptionPane.showOptionDialog(rootPane,
components.toArray(), title, optionType, messageType, null,
options, optionSelection);
if(selection == 0)
return testo.getText();
else
return null;
}
}
我需要在新线程中创建一个新的 JFrame。当我关闭 JFrame 时,我需要 return 一个字符串。 问题是 wait() 方法 "doesn't wait" new Thread 的 "notify()"。 谢谢你的回答。
import java.awt.Button;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class FinestraTesto extends Thread {
JLabel jdescr;
JTextArea testo;
JPanel pannelloTasti;
JButton bottoneInvio;
JButton bottoneAnnulla;
JFrame finestraTestuale;
JPanel panAll;
static Boolean pause = true;
String titolo;
String descrizione;
private static String testoScritto = "";
public String mostra() {
// Create a new thread
Thread th = new Thread(new FinestraTesto(titolo, descrizione));
th.start();
synchronized (th) {
try {
// Waiting the end of th.
th.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return testoScritto;
}
public void run() {
synchronized (this) {
System.out.println("Fatto 1 thread");
finestraTestuale = new JFrame(titolo);
finestraTestuale.setPreferredSize(new Dimension(600, 200));
finestraTestuale.setSize(600, 200);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
finestraTestuale.setLocation(
dim.width / 2 - finestraTestuale.getSize().width / 2,
dim.height / 2 - finestraTestuale.getSize().height / 2);
panAll = new JPanel();
panAll.setLayout(new BoxLayout(panAll, BoxLayout.Y_AXIS));
bottoneInvio = new JButton("Conferma");
bottoneAnnulla = new JButton("Annulla");
pannelloTasti = new JPanel();
testo = new JTextArea();
testo.setPreferredSize(new Dimension(550, 100));
testo.setSize(550, 100);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(testo);
jdescr = new JLabel(descrizione);
jdescr.setPreferredSize(new Dimension(550, 50));
jdescr.setSize(550, 50);
pannelloTasti.setLayout(new BoxLayout(pannelloTasti,
BoxLayout.X_AXIS));
pannelloTasti.add(bottoneInvio);
pannelloTasti.add(bottoneAnnulla);
panAll.add(jdescr);
panAll.add(scrollPane);
panAll.add(pannelloTasti);
finestraTestuale.add(panAll);
bottoneInvio.addActionListener(new ActionListener() {
@Override
/**
* metodo attivato quando c'è un'azione sul bottone
*/
public void actionPerformed(ActionEvent arg0) {
testoScritto = testo.getText();
pause = false;
finestraTestuale.show(false);
// send notify
notify();
}
});
bottoneAnnulla.addActionListener(new ActionListener() {
@Override
/**
* metodo attivato quando c'è un'azione sul bottone
*/
public void actionPerformed(ActionEvent arg0) {
pause = false;
testoScritto = "";
finestraTestuale.show(false);
// send notify
notify();
}
});
finestraTestuale.show();
}
}
public FinestraTesto(String titolo, String descrizione) {
this.titolo = titolo;
this.descrizione = descrizione;
}
}
您最好使用 Synchronizers 而不是 wait
和 notify
。它们更受欢迎,因为简单和安全。
Given the difficulty of using wait and notify correctly, you should use the higher-level concurrency utilities instead.
Effective Java (2nd Edition), Item 69
我用这个 class 解决了:
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class CustomDialog
{
private List<JComponent> components;
private String title;
private int messageType;
private JRootPane rootPane;
private String[] options;
private int optionIndex;
private JTextArea testo;
public CustomDialog(String title,String descrizione)
{
components = new ArrayList<>();
setTitle(title);
setMessageType(JOptionPane.PLAIN_MESSAGE);
addMessageText(descrizione);
testo = new JTextArea();
testo.setPreferredSize(new Dimension(550, 100));
testo.setSize(550, 100);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(testo);
addComponent(scrollPane);
setRootPane(null);
setOptions(new String[] { "Send", "Cancel" });
setOptionSelection(0);
}
public void setTitle(String title)
{
this.title = title;
}
public void setMessageType(int messageType)
{
this.messageType = messageType;
}
public void addComponent(JComponent component)
{
components.add(component);
}
public void addMessageText(String messageText)
{
components.add(new JLabel(messageText));
}
public void setRootPane(JRootPane rootPane)
{
this.rootPane = rootPane;
}
public void setOptions(String[] options)
{
this.options = options;
}
public void setOptionSelection(int optionIndex)
{
this.optionIndex = optionIndex;
}
public String show()
{
int optionType = JOptionPane.OK_CANCEL_OPTION;
Object optionSelection = null;
if(options.length != 0)
{
optionSelection = options[optionIndex];
}
int selection = JOptionPane.showOptionDialog(rootPane,
components.toArray(), title, optionType, messageType, null,
options, optionSelection);
if(selection == 0)
return testo.getText();
else
return null;
}
}