【问题标题】:Getting data from different class without re-opening JFrame in java?从不同的类中获取数据而不在java中重新打开JFrame?
【发布时间】:2014-09-15 03:20:19
【问题描述】:

我的程序中有两个课程给我带来了麻烦。第一个打开一个 JFrame。第二个更新 .properties 文件上的数据。在 JFrame 中有一个带有 JTextAreas 的面板和一个“保存更改”按钮。当按下该按钮时,我从第二类调用一个方法,但要做到这一点,我必须
firstClass x = new firstClass(); 所以当按下按钮时,文件会更新,但会打开一个新的 JFrame。我很确定创建实例 x 是造成这种情况的原因,但如果不这样做,我不知道有任何其他方法可以做到这一点。

第 1 类:

public class firstClass{    
    public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable(){
                @Override
                public void run(){
                    new firstClass();
                }
            });
        }

JFrame go = new JFrame("firstClass");
JPanel panel = new JPanel();
JTextArea textArea = new JTextArea();
JButton savechanges = new JButton("Save");

public firstClass() {
    panel.add(textArea);
    panel.add(savechanges);

    savechanges.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent arg0){
            secondClass f = new secondClass();
            try {
                f.UpdateData();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });

    go.add(panel);
    go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    go.setSize(750, 750);
    go.setVisible(true);
}

第 2 类:

public class secondClass {
    public static void main(String[] args) {
        //creates properties file
    }

        public void UpdateData() throws IOException{
        firstClass x = new firstClass();  // <-------------------------------
        FileInputStream in = new FileInputStream("config.properties");
        Properties props = new Properties();
        props.load(in);
        in.close();

        FileOutputStream out = new FileOutputStream("config.properties");
        props.setProperty("prop1", x.textArea.getText().toString());
        props.store(out, null);
        out.close();

    }

【问题讨论】:

    标签: java swing properties jframe instance


    【解决方案1】:

    你正在跨越目的,谁实际上在控制这里,谁对什么负责??

    区分责任范围,例如,您的SecondClass 仅(真正)负责从用户那里收集数据,而您的FirstClass 实际上是知道应该使用哪些数据的人,@ 987654325@不应该在乎...

    这样想,SecondClass 是服务员,它接受订单并将信息提供给 FirstClass,他是厨师,知道如何完成订单和准备餐点......

    不要使用单独的框架(请参阅The Use of Multiple JFrames, Good/Bad Practice?,出于某些原因,您不应该这样做),而应考虑使用某些 kine 的模态 JDialog

    对话框应该从用户那里收集信息,当它关闭时,根据它是如何关闭的,使用调用者来处理和处理结果......

    SecondClass secondClass = new SecondClass();
    int reason = secondClass.showDialog();
    if (reason == SAVE_RESULTS) {
        //... Get the data from the secondClass and save it...
    }
    

    详情请见How to Make Dialogs

    更新

    好的,所以您似乎想要某种能够存储/检索值的“配置”管理器。

    配置管理器将知道如何读取和写入属性并且不会关心其他任何事情,它有一个明确定义的边界。然后,您需要要求配置管理器根据需要读取或写入值...

    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Properties;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JTextArea;
    import javax.swing.SwingUtilities;
    
    public class TestConfig {
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new TestConfig();
                }
            });
        }
    
        JFrame go = new JFrame("firstClass");
        JPanel panel = new JPanel();
        JTextArea textArea = new JTextArea();
        JButton savechanges = new JButton("Save");
    
        public TestConfig() {
            panel.add(textArea);
            panel.add(savechanges);
    
            savechanges.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    try {
                        ConfigurationManager.INSTANCE.put("prop1", textArea.getText());
                    } catch (IOException ex) {
                        JOptionPane.showMessageDialog(panel, "Failed to write properties", "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
    
            go.add(panel);
            go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            go.setSize(750, 750);
            go.setVisible(true);
    
        }
    
        public enum ConfigurationManager {
    
            INSTANCE;
    
            protected Properties readProperties() throws IOException {
                Properties p = new Properties();
                try (FileInputStream fis = new FileInputStream("config.properties")) {
                    p.load(fis);
                }
                return p;
            }
    
            public String get(String name) throws IOException {
                return readProperties().getProperty(name);
            }
    
            public void put(String key, String vaue) throws IOException {            
                Properties p =  readProperties();
                p.put(key, vaue);
                writeProperties(p);            
            }
    
            protected void writeProperties(Properties p) throws IOException {
                try (FileOutputStream fos = new FileOutputStream("config.properties")) {
                    p.store(fos, "Config");
                }
            }            
        }
    }
    

    这个例子非常繁琐...每次读取一个值时,它都会从磁盘加载内容,每次设置值时,它都会存储到磁盘中。

    您可以将值缓存在内存中,在第一次加载时读取它们一次,然后在将来的某个时间写入,但我希望您能明白这一点

    【讨论】:

    • 我明白你的意思,我只是不确定我是如何跨越目的的。 1 类只有一个 JFrame 和几个面板(使用 cardLayout 所以一次只显示一个面板)所以我认为我没有使用单独的框架。 1 级是厨师,正如你所说,2 级是服务员,只是收集信息。我想要文件中的信息的原因是,当用户关闭应用程序并重新打开它时,之前输入的数据仍然存在。我只是不想在保存数据时打开另一个框架实例。
    • 所以将信息返回给厨师......您甚至不需要在secondClass 中创建firstClass 的第二个实例,只需将它需要保存的详细信息传递给它。 ..
    • 厨师将从secondClass 中更新的config.properties 文件中获取信息。我传递用户在 textArea 中输入的详细信息的方式是使用这个:props.setProperty("prop1", x.textArea.getText().toString());,但如果没有第二个 firstClass 实例,这将无法工作?
    • 您“似乎”需要的是某种配置管理器来管理设置的存储和检索...
    • 看来我又想多了……我所做的只是将UpdateData 方法移到firstClass 上,它工作正常。我认为这就是你试图通过跨越目的来告诉我的......
    猜你喜欢
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多