Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
仅在窗口在java中不再可见后读取值_Java_Multithreading_Swing - Fatal编程技术网

仅在窗口在java中不再可见后读取值

仅在窗口在java中不再可见后读取值,java,multithreading,swing,Java,Multithreading,Swing,也许我只是不知道去哪里看,或者不知道线程是如何工作的,但是我有两个不同的JFrame(J1,J2)。J1是具有可选择J2的下拉菜单的主JFrame。当这个J2变为可见时,我需要J1等到J2的foobar值变为-1以外的值。我试过几种不同的方法剥这只猫的皮,但都没有成功 我现在正在尝试的是 // located in J1 J2 otherFrame = new J2(); .... private synchronized void getNum() { try { w

也许我只是不知道去哪里看,或者不知道线程是如何工作的,但是我有两个不同的JFrame(J1,J2)。J1是具有可选择J2的下拉菜单的主JFrame。当这个J2变为可见时,我需要J1等到J2的foobar值变为-1以外的值。我试过几种不同的方法剥这只猫的皮,但都没有成功

我现在正在尝试的是

// located in J1
J2 otherFrame = new J2();
....

private synchronized void getNum() {
    try {
        while (otherFrame.returnNum() == -1) wait();
    }
    catch (Exception e) {}
    Long myResult = otherFrame.returnNum();
    ...
}



// located in J2
public synchronized Long returnNum() {
    try {
        while (someNum == -1) wait();
    }
    catch (Exception e) {}
    notify();
    return someNum;
}

我确信这看起来很愚蠢,但我需要J1等待J2将值分配给someNum。当用户单击提交时,将分配该值。它不起作用。我在这里做错了什么(更重要的是),如果这是一个线程问题,那么我的线程概念在哪里失败了?

解决方案不是在第二个窗口中使用JFrame,而是使用一个模态对话框,如模态JDialog。这正是这种类型的顶级窗口构建的目的

这个问题是人们应该避免编写扩展JFrame的Swing类的另一个原因,因为这样做会使编码人员陷入困境并限制他们的选择。更好的方法是创建扩展类或构建类来创建JPanel,因为如果需要,JPanel可以放在JFrame或模态JDialog中,或者放在另一个JPanel中,或者在CardLayout中交换,或者

请注意,JDialog的使用与JFrame非常相似,只是有一些不同。您应该将对调用窗口(这里是您的第一个JFrame)的引用传递到对话框中,并且应该使用使对话框成为模态的构造函数,但是API可以帮助您完成所有这些

当您使模态窗口可见时,调用代码中的代码流停止,并且直到JDialog不再可见时才恢复。此时,您可以查询JDialog组件的状态,并在调用代码中使用它


例如:

import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;

import javax.swing.*;

public class DialogEg {
    private static void createAndShowGui() {

        // create JFrame for application
        JFrame frame = new JFrame("Dialog Eg");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new MainPanel());
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

@SuppressWarnings("serial")
class MainPanel extends JPanel {
    private JTextField valueField = new JTextField(5);

    public MainPanel() {
        valueField.setFocusable(false); // so user can't interact with it

        add(new JLabel("Value:"));
        add(valueField);
        add(new JButton(new GetValueAction("Get Value")));
    }

    private class GetValueAction extends AbstractAction {
        private SecondPanel secondPanel = new SecondPanel();

        public GetValueAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            // get JPanel's top level window
            Window win = SwingUtilities.getWindowAncestor(MainPanel.this);

            // create jdialog that is modal
            JDialog dialog = new JDialog(win, "Get Value", ModalityType.APPLICATION_MODAL);
            dialog.add(secondPanel);

            // so the submit button will be activated when enter pressed:
            dialog.getRootPane().setDefaultButton(secondPanel.getSubmitButton());
            dialog.pack();
            dialog.setLocationRelativeTo(win);
            dialog.setVisible(true); // **** code flow stops here

            // and resumes here once dialog is no longer visible
            int value = secondPanel.getSpinnerValue();
            valueField.setText("" + value);
        }
    }
}

@SuppressWarnings("serial")
class SecondPanel extends JPanel {
    private SpinnerModel spinModel = new SpinnerNumberModel(-1, -1, 100, 1);
    private JSpinner spinner = new JSpinner(spinModel);
    private JButton submitButton = new JButton(new SubmitAction("Submit"));

    public SecondPanel() {
        add(spinner);
        add(submitButton);
    }

    public int getSpinnerValue() {
        return (Integer) spinner.getValue();
    }

    public JButton getSubmitButton() {
        return submitButton;
    }

    private class SubmitAction extends AbstractAction {
        public SubmitAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            int value = getSpinnerValue();

            // get JPanel's top level window
            Window win = SwingUtilities.getWindowAncestor(SecondPanel.this);
            if (value < 0) {
                String msg = "Submitted value must cannot be negative. Please try again";
                JOptionPane.showMessageDialog(win, msg, "Invalid Entry", JOptionPane.ERROR_MESSAGE);
                spinner.requestFocusInWindow(); // bring focus back to spinner
            } else {
                spinner.requestFocusInWindow();
                win.dispose();  // get rid of dialog
            }
        }
    }
}
导入java.awt.Window;
导入java.awt.Dialog.ModalityType;
导入java.awt.event.ActionEvent;
导入javax.swing.*;
公开课对话{
私有静态void createAndShowGui(){
//为应用程序创建JFrame
JFrame=新JFrame(“对话框Eg”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(新的主面板());
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
createAndShowGui();
}
});
}
}
@抑制警告(“串行”)
类主面板扩展了JPanel{
私有JTextField valueField=新JTextField(5);
公共主面板(){
valueField.setFocusable(false);//因此用户无法与其交互
添加(新JLabel(“值:”);
添加(valueField);
添加(newjbutton(newgetvalueaction(“getvalue”));
}
私有类GetValueAction扩展了AbstractAction{
私有SecondPanel SecondPanel=新的SecondPanel();
public GetValueAction(字符串名称){
超级(姓名);
int助记符=(int)name.charAt(0);
putValue(助记符键,助记符);
}
@凌驾
已执行的公共无效操作(操作事件e){
//获取JPanel的顶级窗口
Window win=SwingUtilities.getWindow祖先(MainPanel.this);
//创建模态的jdialog
JDialog dialog=newjdialog(win,“获取值”,ModalityType.APPLICATION\u MODAL);
对话框。添加(第二个面板);
//因此,按下enter键时,提交按钮将被激活:
dialog.getRootPane().setDefaultButton(secondPanel.getSubmitButton());
dialog.pack();
对话框。setLocationRelativeTo(win);
setVisible(true);//****代码流在此停止
//一旦对话框不再可见,将在此处继续
int value=secondPanel.getSpinnerValue();
valueField.setText(“+value”);
}
}
}
@抑制警告(“串行”)
类SecondPanel扩展了JPanel{
专用喷丝头型号spinModel=新喷丝头型号(-1,-1100,1);
私有JSpinner微调器=新JSpinner(微调模型);
私有JButton submitButton=新JButton(新提交(“提交”));
公共事务委员会(){
添加(微调器);
添加(提交按钮);
}
public int getSpinnerValue(){
return(Integer)spinner.getValue();
}
公共JButton getSubmitButton(){
返回提交按钮;
}
私有类SubmitAction扩展了AbstractAction{
公共提交(字符串名称){
超级(姓名);
int助记符=(int)name.charAt(0);
putValue(助记符键,助记符);
}
@凌驾
已执行的公共无效操作(操作事件e){
int value=getSpinnerValue();
//获取JPanel的顶级窗口
Window win=SwingUtilities.getWindow祖先(SecondPanel.this);
如果(值<0){
String msg=“提交的值不能为负数,请重试”;
JOptionPane.showMessageDialog(win,msg,“无效条目”,JOptionPane.ERROR\u消息);
spinner.requestFocusInWindow();//将焦点带回spinner
}否则{
spinner.requestFocusInWindow();
win.dispose();//摆脱对话框
}
}
}
}

解决方案不是在第二个窗口中使用JFrame,而是使用一个模态对话框,如模态JDialog。这正是这种类型的顶级窗口构建的目的

这个问题是人们应该避免编写扩展JFrame的Swing类的另一个原因,因为这样做会使编码人员陷入困境并限制他们的选择。更好的方法是创建扩展类或构建类来创建JPanel,因为