卡片布局 - 从以前的卡片获取输入

时间:2017-02-27 15:16:08

标签: java swing layout-manager cardlayout

我需要第1-5页的运行顺序。我在每页输入数据后使用卡片布局在每个页面之间导航。导航到下一页通过每个文本字段上的动作侦听器工作。

我的问题是如何将每张卡/页面的输入传递给下一张?我可以System.out.println每个TextFeilds数据。但我无法在下一张卡/动作监听器中获取此信息。我需要这样做的原因是我想比较每个页面的字符串,并在页面/卡片2上显示第1页输入的标签。

我提前为大量的代码道歉......大多数人都会认识到大部分代码,因为它是从CardLayout示例java代码中复制的。我刚刚添加了两张卡片,直到我得到了传回变量和第四张的基础知识。

即使只是向正确的方向推进,所有的帮助也会受到赞赏。

import java.awt.*;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Scanner;
import javax.swing.*;

public class CardLayoutDemo implements ItemListener  {
    JPanel cards; //a panel that uses CardLayout
    final static String TEXTPANEL =  "Card1 with text";
    final static String TEXTPANEL2 = "Card with JTextField";

public void addComponentToPane(Container pane) {
        //Put the JComboBox in a JPanel to get a nicer look.
        JPanel comboBoxPane = new JPanel(); //use FlowLayout
        String comboBoxItems[] = { TEXTPANEL, TEXTPANEL2};
        JComboBox cb = new JComboBox(comboBoxItems);
        cb.setEditable(false);
        cb.addItemListener(this);
        comboBoxPane.add(cb);

    //Create the "cards".

    JPanel card1 = new JPanel(); 
        JTextField jtf=new JTextField("", 40);
        jtf.setSize(40, 10);
        card1.add(jtf);

        JLabel lab1 = new JLabel("Page1 Text", JLabel.LEFT);
            card1.add(lab1 = new JLabel("Page1"));

    JPanel card2 = new JPanel();
        JTextField jtf2=new JTextField("", 40);
        jtf2.setSize(40, 10);
    card2.add(jtf2);
        JLabel lab2 = new JLabel("Page2 Text", JLabel.LEFT);
        card2.add(lab2 = new JLabel("Page2 "));

     //Create the panel that contains the "cards".
    cards = new JPanel(new CardLayout());
    cards.add(card1, TEXTPANEL);
    cards.add(card2, TEXTPANEL2);
    pane.add(cards, BorderLayout.CENTER);

jtf.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e)
{

  String getText1 = jtf.getText();
                System.out.println("PAGE1 ");
                System.out.println(getText1);

    CardLayout cl = (CardLayout)(cards.getLayout());
    cl.show(cards, TEXTPANEL2);  
         jtf2.requestFocus();
         jtf2.requestFocusInWindow();


     } 


    //JOptionPane.showMessageDialog(null,"Action Listener is working");
    });


  //PAGE2

     jtf2.addActionListener(new ActionListener(){

    public void actionPerformed(ActionEvent e)
    {

    String getText2 = jtf2.getText();
                System.out.println("PAGE2 ");
                System.out.println(getText2);

    CardLayout cl = (CardLayout)(cards.getLayout());
    cl.show(cards, TEXTPANEL);  
         jtf.requestFocus();
         jtf.requestFocusInWindow();
         jtf.setText("");

    }

    });

    }//ADD COMPONENT TO PANE

    public void itemStateChanged(ItemEvent evt) {
    CardLayout cl = (CardLayout)(cards.getLayout());
    cl.show(cards, (String)evt.getItem());

  //      String getLoginUser1 = jtf.getText();
    //System.out.println(getLoginUser1); 


    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event dispatch thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("CardLayoutDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(600, 300));
        JFrame.setDefaultLookAndFeelDecorated(true);

    //Create and set up the content pane.
    CardLayoutDemo demo = new CardLayoutDemo();
    demo.addComponentToPane(frame.getContentPane());

    //Display the window.
    frame.pack();
    frame.setVisible(true);
    }

    public static void main(String[] args) {
    /* Use an appropriate Look and Feel */
    try {
        //UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
        UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
    } catch (UnsupportedLookAndFeelException ex) {
        ex.printStackTrace();
    } catch (IllegalAccessException ex) {
        ex.printStackTrace();
    } catch (InstantiationException ex) {
        ex.printStackTrace();
    } catch (ClassNotFoundException ex) {
        ex.printStackTrace();
    }


    /* Turn off metal's use of bold fonts */
    UIManager.put("swing.boldMetal", Boolean.FALSE);

    //Schedule a job for the event dispatch thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();

        }
    });
    }
    }

2 个答案:

答案 0 :(得分:1)

以下是关于该问题的另一种观点。您可以创建某种卡片管理器并在其中保存所有必需的信息。这是一个例子:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

public class CardLayoutDemo implements ItemListener  {

    private static class QuizManager {
        final  java.util.List<String> quizData = new ArrayList<>();
        final  java.util.List<JPanel> cards = new ArrayList<>();
        final  JPanel rootView;

        public QuizManager(JPanel root){
            rootView = root;
        }

        private JPanel createQuizPanel(String pageText, final int index) {
            JPanel card = new JPanel();
            JTextField jtf=new JTextField("", 40);
            jtf.setSize(40, 10);
            JLabel prev = new JLabel("", JLabel.LEFT);
            card.add(prev);
            card.add(jtf);
            card.add(new JLabel(pageText, JLabel.LEFT));


            jtf.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    QuizManager.this.onCardSubmited(card, index, jtf.getText());
                }
            });

            card.addComponentListener(new ComponentAdapter() {
                @Override
                public void componentShown(ComponentEvent e) {
                    super.componentShown(e);
                    jtf.requestFocus();
                    jtf.requestFocusInWindow();
                    String text = QuizManager.this.getPrevStringFor(index);
                    if (text != null) {
                        prev.setText(text);
                    }
                }
            });

            return card;
        }

        private String getPrevStringFor(int index) {
            if (index == 0) return null;

            return quizData.get(index-1);
        }
        private String buildPanelName(int index) {
            return String.format("card-%d", index);
        }
        public QuizManager addCard(String title) {
            int index = cards.size();
            quizData.add(null);//not set yet, just allocating
            JPanel card = createQuizPanel(title, index);
            cards.add(card);//this array looks like redundant
            rootView.add(card, buildPanelName(index));
            return this;
        }

        private void showCard(int index) {
            CardLayout cl = (CardLayout) (rootView.getLayout());
            cl.show(rootView, buildPanelName(index));
        }

        public void show() {
            showCard(0);
        }

        public void onCardSubmited(JPanel card, int cardIndex, String text) {
            System.out.println("page " + cardIndex);
            System.out.println("text : " + text);
            quizData.set(cardIndex, text);
            if (cardIndex < cards.size() - 1) {
                showCard(cardIndex + 1);
            } else {
                System.out.println("WE FINISHED");
                //add finalazing code here
            }
        }
    }

    JPanel cardsRoot;
    public void addComponentToPane(Container pane) {
        cardsRoot = new JPanel(new CardLayout());
        QuizManager manager = new QuizManager(cardsRoot)
                .addCard("First page")
                .addCard("Second page")
                .addCard("Third card")
                .addCard("Forth card");

        pane.add(cardsRoot, BorderLayout.CENTER);
        manager.show();
    }

    public void itemStateChanged(ItemEvent evt) {
        CardLayout cl = (CardLayout)(cardsRoot.getLayout());
        cl.show(cardsRoot, (String)evt.getItem());
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event dispatch thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("CardLayoutDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(600, 300));
        JFrame.setDefaultLookAndFeelDecorated(true);

        //Create and set up the content pane.
        CardLayoutDemo demo = new CardLayoutDemo();
        demo.addComponentToPane(frame.getContentPane());

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
    /* Use an appropriate Look and Feel */
        try {
            //UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
            UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
        } catch (UnsupportedLookAndFeelException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }


    /* Turn off metal's use of bold fonts */
        UIManager.put("swing.boldMetal", Boolean.FALSE);

        //Schedule a job for the event dispatch thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();

            }
        });
    }
}

看看制作很多卡片会有多容易。

答案 1 :(得分:0)

您已获得隐藏在addComponentToPane(...)方法中的关键组件的变量声明,仅将其范围限制为此方法,从而阻止您获取所需的信息。虽然针对此类问题的规范解决方案是使用模型 - 视图 - 控制器或MVC类型模式,以便从视图(GUI)中提取模型(底层程序逻辑和数据),但您可以快速完成和脏解决方案只是给你的变量私有类范围。

例如,如果JTextField被称为textField并且被保存在充当&#34; card&#34;的JPanel中,比如名为cardPanel,那么你可以创建一个看起来像这样的类:

public class CardPanel extends JPanel {
    // constants to give the GUI a bigger size
    private static final int PREF_W = 300;
    private static final int PREF_H = 100;

    // our key JTextField declared at class level
    private JTextField textField = new JTextField(20);

    // a JLabel to display the previous cardpanel's text
    private JLabel label = new JLabel(" ");

    // create the JPanel
    public CardPanel(String name) {
        setName(name);
        setBorder(BorderFactory.createTitledBorder("Panel " + name));
        JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
        labelPanel.add(new JLabel("Prior Card's Word: "));
        labelPanel.add(label);

        setLayout(new BorderLayout());
        add(textField, BorderLayout.PAGE_START);
        add(labelPanel, BorderLayout.CENTER);
    }

    // have to jump through this hoop if we want to JTextField to
    // have focus when a card is swapped
    public void setFocusOnTextField() {
        textField.requestFocusInWindow();
        textField.selectAll();
    }

    // to make our GUI larger
    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    // allow outside classes to add a listener to the JTextField
    public void addActionListener(ActionListener listener) {
        textField.addActionListener(listener);
    }

    // allow outside classes to get text from the text field 
    public String getTextFieldText() {
        return textField.getText();
    }

    // allow outside classes to put text into the JLabel 
    public void setLabelText(String text) {
        label.setText(text);
    }
}

然后我们可以像这样使用它:

public class MyCardLayoutDemo extends JPanel {
    private static final String[] NAMES = {"One", "Two", "Three", "Four"};
    private Map<String, CardPanel> namePanelMap = new HashMap<>();
    private CardLayout cardLayout = new CardLayout();
    private int nameIndex = 0;

    public MyCardLayoutDemo() {
        setLayout(cardLayout);
        MyListener listener = new MyListener();

        for (String name : NAMES) {
            CardPanel cardPanel = new CardPanel(name);
            cardPanel.addActionListener(listener);
            add(cardPanel, name);
            namePanelMap.put(name, cardPanel);
        }
    }

    private class MyListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            // get the current CardPanel
            String name = NAMES[nameIndex];
            CardPanel currentCard = namePanelMap.get(name);

            // advance the name index to get the next CardPanel
            nameIndex++;
            nameIndex %= NAMES.length;
            name = NAMES[nameIndex];
            CardPanel nextCard = namePanelMap.get(name);

            // get text from current CardPanel
            String text = currentCard.getTextFieldText();
            nextCard.setLabelText(text);  // and put it into next one

            // swap cards
            cardLayout.show(MyCardLayoutDemo.this, name);
            nextCard.setFocusOnTextField();
        }
    }

    private static void createAndShowGui() {
        MyCardLayoutDemo mainPanel = new MyCardLayoutDemo();

        JFrame frame = new JFrame("My CardLayout Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}