【问题标题】:JTextField and button is not updated while switching between panel using cardlayout使用卡片布局在面板之间切换时,JTextField 和按钮不会更新
【发布时间】:2016-05-16 18:58:07
【问题描述】:

几天以来,我一直在努力更新卡片布局中的 Jtextfield 和 Jbutton 数据。我创建了一个小演示来解释我的问题。当我点击“开始”按钮时,它应该显示另一个面板,这正在工作,但是当我返回主页时,我希望我的 Jtextfield 和 jbutton 从“世界”更新到“你好”,但这不起作用。任何帮助和建议将不胜感激。(对不起代码的缩进,我不知道为什么复制粘贴不能正常工作)。

  public class CardlayoutDemo {

     public static String data = "world";
     private static final String INTRO = "intro";
     private static final String GAME = "game";
     private CardLayout cardlayout = new CardLayout();
     private JPanel mainPanel = new JPanel(cardlayout);
     private IntroPanel introPanel = new IntroPanel();
     private GamePanel gamePanel = new GamePanel();
  public CardlayoutDemo() {
        mainPanel.add(introPanel.getMainComponent(), INTRO);
  mainPanel.add(gamePanel.getMainComponent(), GAME);

  introPanel.addBazBtnActionListener(new ActionListener() {
     @Override
     public void actionPerformed(ActionEvent e) {
         CardlayoutDemo.data = "hello";
         mainPanel.repaint();
         mainPanel.revalidate();
         CardLayout cl = (CardLayout)mainPanel.getLayout();
        cl.show(mainPanel, GAME);
     }
  });

  gamePanel.addBackBtnActionListener(new ActionListener() {
     @Override
     public void actionPerformed(ActionEvent e) {
         CardLayout cl = (CardLayout)mainPanel.getLayout();
        cl.show(mainPanel, INTRO);
     }
  });
     }

     private JComponent getMainComponent() {
  return mainPanel;
     }

     private static void createAndShowUI() {
  JFrame frame = new JFrame("Demo");
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  frame.getContentPane().add(new CardlayoutDemo().getMainComponent());
  frame.pack();
  frame.setLocationRelativeTo(null);
  frame.setVisible(true);
     }

     public static void main(String[] args) {
  java.awt.EventQueue.invokeLater(new Runnable() {
     public void run() {
        createAndShowUI();
     }
  });
     }
  }

  class IntroPanel {
     private JPanel mainPanel = new JPanel();
     public JButton start;
     private JButton exit;
     private JTextField lblData;

     public IntroPanel() {
  mainPanel.setLayout(new BorderLayout());
  JPanel content = new JPanel();
  start = new JButton("Start");
  exit = new JButton(CardlayoutDemo.data);
  lblData = new JTextField(CardlayoutDemo.data);
  content.add(lblData);
  content.add(start);
  content.add(exit);
  mainPanel.add(content, BorderLayout.CENTER);

  exit.addActionListener(new ActionListener() {
     @Override
     public void actionPerformed(ActionEvent e) {
        Window win = SwingUtilities.getWindowAncestor(mainPanel);
        win.dispose();
     }
  });
     }
     public void addBazBtnActionListener(ActionListener listener) {
        start.addActionListener(listener);
     }
     public JComponent getMainComponent() {
        return mainPanel;
     }
  }

  class GamePanel {
     private static final Dimension MAIN_SIZE = new Dimension(400, 200);
     private JPanel mainPanel = new JPanel();
     private JButton back;

     public GamePanel() {
        back = new JButton("return to main menu");
        mainPanel.add(back);
  mainPanel.setPreferredSize(MAIN_SIZE);
     }

     public JComponent getMainComponent() {
        return mainPanel;
     }

     public void addBackBtnActionListener(ActionListener listener) {
        back.addActionListener(listener);
     }
  }

【问题讨论】:

    标签: java swing jbutton jtextfield cardlayout


    【解决方案1】:

    当此行在您的侦听器中执行时:

    CardlayoutDemo.data = "hello";
    

    您正在创建一个新的 java.lang.String 对象并设置字段数据以引用您刚刚创建的新字符串。这对变量先前引用的 JTextField 或 String 对象的内部状态没有影响。

    要更改 JTextField 的文本,您应该调用 JTextField 的 setText(String) 方法。

    【讨论】:

    • 哦,我明白了。看起来我需要在切换到新面板之前覆盖“显示”方法来更新字段。谢谢。欣赏它。
    【解决方案2】:

    不,不要覆盖show 方法。而是为您的类提供允许其他类能够更改其状态的方法。例如,您可以将此方法添加到 IntroPanel 类:

    class IntroPanel {
        // .....
    
        // !! added!
        public void lblDataSetText(String text) {
            lblData.setText(text);
        }
    }
    

    然后当你想改变它的 lblData 字段的状态时调用它:

    introPanel.addBazBtnActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            // !! CardlayoutDemo.data = "hello";
            mainPanel.repaint();
            mainPanel.revalidate();
            CardLayout cl = (CardLayout) mainPanel.getLayout();
            cl.show(mainPanel, GAME);
            introPanel.lblDataSetText("Hello!"); // !!
        }
    });
    

    请注意,这是一个快速而肮脏的解决方案。如果您想要一个更强大的解决方案,可以在更大的程序中更好地扩展,那么按照 M-V-C 设计模式重新构建您的程序,并让您的视图更改显示的文本以响应模型中字符串状态的变化。这将需要更多的工作,而且在小型“玩具”程序中不值得付出努力,但在大型复杂程序中值得付出努力,因为它有助于减少耦合,从而降低复杂性和错误风险。

    【讨论】:

    • 这是个好主意。我不知道 MVC 设计,但现在我对此一无所知,所以我会尝试实现它。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2016-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多