【问题标题】:How to transfer data between panels of cardLayout如何在cardLayout的面板之间传输数据
【发布时间】:2015-03-12 22:15:59
【问题描述】:

在我的软件中,我使用卡片布局来创建“基于向导”的界面。在面板中,用户选择一个文件,在另一个面板中获取有关上一个面板中所选文件的信息。

问题是 CardLayout 将所有面板一起加载。所以面板处理预定义的数据。但我想用当前面板中给出的信息更新下一个面板。 每个面板都有“下一个”和“后退”按钮,所以我认为这就是下一个面板可以以某种方式更新的地方。我想使用 setter 和 getter 方法,但无法正确实现。

这是一个包含两个子面板的示例代码: 基类:

   public Base(){
            frame.setLayout(bl);
            frame.setSize(800, 600);
            frame.add(new MainPanel(), BorderLayout.CENTER);

            frame.setLocationRelativeTo(null);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
        public static void main(String[] args) {
            // TODO code application logic here
            new Base();
        }
    }

MainPanel(子面板支架)

class MainPanel extends JPanel{
    private CardLayout cl = new CardLayout();
    private JPanel panelHolder = new JPanel(cl);

    public MainPanel() {
        ChooseFile chooseFile = new ChooseFile(this);
        ShowResult showResult = new ShowResult(this);

        panelHolder.add(showResult, "showResult");
        panelHolder.add(chooseFile, "chooseFile");

        cl.show(panelHolder, "chooseFile");
        add(panelHolder);
    }
    public void showPanel(String panelIdentifier){
        cl.show(panelHolder, panelIdentifier);
    }
}

子面板 1:

class ChooseFile extends JPanel{
    MainPanel ob2;
    JPanel directoryChooserPanel, bottomPanel;
    JButton btn, localSourceBack, localSourceNext;
    JTextField field;
    public ChooseFile(MainPanel mainPanel){
        this.ob2 = mainPanel;
        ShowResult showResult = new ShowResult();
        setLayout(new BorderLayout());

        directoryChooserPanel = new JPanel(new GridLayout(0,2));
        btn = new JButton("Browse");
        btn.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e){
                JFileChooser chooser = new JFileChooser("D:\\Desktop");
                chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int returnVal = chooser.showOpenDialog(null);
                if(returnVal == JFileChooser.APPROVE_OPTION){
                    File myFile = chooser.getSelectedFile();
                    String text = myFile + "";

                    field.setText(text); 
                }
            }
        });


        directoryChooserPanel.add(btn);

        field = new JTextField(20);
        directoryChooserPanel.add(field);



        localSourceNext = new JButton("Next");
        localSourceNext.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e){
                ob2.showPanel("showResult");
                showResult.setRoot(getPath());
            }
        });

        add(directoryChooserPanel, BorderLayout.NORTH);
        add(localSourceNext, BorderLayout.EAST);
    }
    public String getPath(){
        return field.getText();
    }
}

子面板 2:

class ShowResult extends JPanel{
    MainPanel ob2;
    JPanel bottomPanel, labelsPanel;
    JButton srcLocalBTN, srcFtpBTN, sourceLocationBack;
    JLabel result;
    File directory;
    String root;
    ArrayList<String> myFiles = new ArrayList<String>();
    public ShowResult(MainPanel mainPanel){
        this.ob2 = mainPanel;
        setLayout(new BorderLayout());
        result = new JLabel();
        root = "No ADDRESS";
        directory = new File(root);

        listFiles(directory, myFiles);
        String filesNumber = "It contains " + myFiles.size() + " files.";
        result.setText(filesNumber);

        add(result, BorderLayout.NORTH);
    }

    public void listFiles(File directory, ArrayList<String> list){
            for(File file : directory.listFiles()){
                list.add(file.getName());
                if(file.isDirectory()){
                    listFiles(file.getAbsoluteFile(), list);
                }
            }
    }
    public ShowResult(){

    }
    public void setRoot(String chosenPath){
        root = chosenPath;
    }
}

所以它首先加载“子面板 1”,因此用户通过 jFileChooser 选择一个目录,然后我需要将此数据传输到“子面板 2”。所以它可以计算它包含多少个文件。 我试图通过获取所选目录并分配给第二个变量中的变量来传输数据。但不起作用。

有什么想法吗?

【问题讨论】:

    标签: java swing cardlayout


    【解决方案1】:

    您正在创建多个 ShowResult 对象,显示一个,然后将信息传递给另一个,即未显示的对象,但这不是 Java 的工作方式(只需在此页面搜索数量new ShowResult() 匹配)。您需要确保显示的 ShowResult 对象与您传递信息的对象完全相同,这意味着您必须通过构造函数或方法参数将显示对象的引用传递给您的 ChooseFile 类。

    更好的选择:使用 MVC 设计模式,制作,让您的控件更改模型的状态,并让您的视图显示模型的状态。这可能会降低代码的圈复杂度。

    【讨论】:

    • 谢谢。你是对的。我没有想到一个类有2个对象。但是,您能否提供示例代码或有关 MVC 教程的链接。我已经阅读过它,但知道如何在我的软件中实现它。
    • 我问自己的是,CardLayout 是否适合您想要实现的目标。我不知道。如果我阅读了有关 CardLayout 应该做什么的 JavaDoc... 看看这个答案,我怀疑它可以,或者这个答案中没有考虑到。
    • @Dan:那需要我写一本书的章节。许多链接的 Google MVC 教程。你也可以看看我之前写的,包括一些代码示例here
    • 我的代码有一点 MVC 版本会更容易理解。但是理论上,我必须有一个进行计算的模型和两个视图,一个从一个面板获取数据,另一个将结果设置到另一个面板。还有一个控制器,当按下 next 按钮并将视图链接到模型时触发。这是正确的想法吗?
    • 你说得对,我很欣赏你提到的关键点。对我来说,了解 MVC 并解决我的问题就足够了。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-06
    • 1970-01-01
    相关资源
    最近更新 更多