簡體   English   中英

為什么ActionListener在控制器中不起作用?

[英]Why doesn't ActionListener work in the controller?

這篇文章是這篇文章的繼續 我的軟件基本上是基於CardLayout面板的。 現在,我想從cardLayout外部更改面板。 在提供的鏈接中,我得到了幫助,並且可以正常工作。 現在,我在軟件中添加了一個控制器,該控制器位於內部面板( CardLayout )和外部面板之間。 在外部面板( leftBar )中,有一個按鈕,如果它的actionListener位於該類的內部,則它可以正常工作,並打開CardLayout的選定內部面板。 但是,如果我將ActionListener放入控制器,它將無法正常工作。 沒有錯誤出現。

這是我的示例代碼:BASE:

public class Base {
        JFrame frame = new JFrame("Panel");
        BorderLayout bl = new BorderLayout();

    public Base(){
        MainPanel mainPanel = new MainPanel();
        LeftBar leftBar = new LeftBar(mainPanel);
        frame.setLayout(bl);
        frame.setSize(800, 600);
        frame.add(leftBar, BorderLayout.WEST);
        frame.add(mainPanel, BorderLayout.CENTER);

        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
    public static void main(String[] args) throws IOException {
        new Base();
    }
}

MainPanel(CardLAyout基座)

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

    public MainPanel(){
        FirstPage firstPage = new FirstPage(this);
        SecondPage secondPage = new SecondPage(this);
        LeftBar leftBar = new LeftBar(this);

        Controller controller = new Controller(secondPage, leftBar, this);
        setLayout(new GridLayout(0,1));

        panelHolder.add(firstPage, "firstPage");
        panelHolder.add(secondPage, "secondPage");

        cl.show(panelHolder, "firstPage");
        add(panelHolder);

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

左欄

public class LeftBar extends JPanel{
    private JButton button;
    private MainPanel mainPanel;

    public LeftBar(MainPanel mainPanel){
        this.mainPanel = mainPanel;

        setPreferredSize(new Dimension(200, 40));
        setLayout(new BorderLayout());
        setBackground(Color.black);

        button = new JButton("Show Second Page");


       add(button, BorderLayout.NORTH);
    }
    public void addPageListener(ActionListener listenForButton){
        button.addActionListener(listenForButton);
    }
}

第二頁:

public class SecondPage extends JPanel{
    MainPanel mainPanel;
    JButton button;
    public SecondPage(MainPanel mainPanel){
       this.mainPanel = mainPanel;
        setBackground(Color.white);
       add(new JLabel("This is second page"));
    }
}

第一頁:

public class FirstPage extends JPanel {
    MainPanel mainPanel;
    JButton button;

    public FirstPage(MainPanel mainPanel) {
       this.mainPanel = mainPanel;
       setBackground(Color.GRAY);

       button = new JButton("Show page");
       button.addActionListener(new ActionListener(){
           @Override
           public void actionPerformed(ActionEvent ae) {
               mainPanel.showPanel("secondPage");
           }

       });

       add(button);
    }
}

和控制器:

public class Controller {
    private SecondPage secondPage;
    private LeftBar leftBar;
    private MainPanel mainPanel;
    public Controller(SecondPage secondPage, LeftBar leftBar, MainPanel mainPanel){
        this.secondPage=secondPage;
        this.leftBar=leftBar;
        this.mainPanel=mainPanel;

        this.leftBar.addPageListener(new ButtonListener());
    }

    class ButtonListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent ae) {
            System.out.println("Works");
            mainPanel.showPanel("secondPage");
        }
    }
}

如您在LeftBar中看到的,我有一個用作actionListener的按鈕方法。 然后在控制器中調用該方法並為其提供一個類。 但它不起作用。 但是,如果ACtionListener位於LeftBar類(內聯)中,則它可以工作。

知道如何解決嗎?

您將在Base構造函數中創建兩個LeftBar實例,將其添加到屏幕中。

public Base() {
    MainPanel mainPanel = new MainPanel();
    LeftBar leftBar = new LeftBar(mainPanel);
    frame.setLayout(bl);
    frame.setSize(800, 600);
    frame.add(leftBar, BorderLayout.WEST);
    frame.add(mainPanel, BorderLayout.CENTER);

還有MainPanel構造函數中的一個傳遞給控制器​​...

public class MainPanel extends JPanel {

    private CardLayout cl = new CardLayout();
    private JPanel panelHolder = new JPanel(cl);

    public MainPanel() {
        FirstPage firstPage = new FirstPage(this);
        SecondPage secondPage = new SecondPage(this);
        LeftBar leftBar = new LeftBar(this);

這意味着控制器將ActionListener附加到在屏幕上永遠不可見的按鈕

我要做的第一件事是開始分離代碼,而不是傳遞類的實例,您需要建立一系列控制器和視圖可以同意的MainPanel ,例如, MainPanel應該提供一種切換視圖的方法,您的LeftBar應該在用戶想要切換視圖時提供通知

例如...

public interface Pageable {

    public void showView(String name);

}

public interface Navigatable {

    public void addActionListener(ActionListener listener);

}

然后您的主視圖將實現Pageable接口

public class MainPanel extends JPanel implements Pageable {
    //...
    @Override
    public void showView(String name) {
        cl.show(panelHolder, name);
    }

您的LeftBar將實現Navigatable接口

public class LeftBar extends JPanel implements Navigatable {
    //...
    @Override
    public void addActionListener(ActionListener listener) {
        button.addActionListener(listener);
    }

這只是定義了任何實現的合同功能,您的控制器不應該關心其他任何事情(也不應該允許它執行原本不希望做的事情,例如從您的視圖中刪除頑皮的控制器中的所有組件)

然后,您的控制器僅負責管理接口之間的合同...

public class Controller {

    private final Navigatable navigatable;
    private final Pageable pageable;

    public Controller(Navigatable navigatable, Pageable pageable) {
        this.navigatable = navigatable;
        this.pageable = pageable;

        navigatable.addActionListener(new ButtonListener());
    }

    class ButtonListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent ae) {
            pageable.showView("secondPage");
        }
    }
}

例如...

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Base {

    JFrame frame = new JFrame("Panel");
    BorderLayout bl = new BorderLayout();

    public Base() {
        MainPanel mainPanel = new MainPanel();
        LeftBar leftBar = new LeftBar(mainPanel);
        frame.setLayout(bl);
        frame.setSize(800, 600);
        frame.add(leftBar, BorderLayout.WEST);
        frame.add(mainPanel, BorderLayout.CENTER);

        Controller controller = new Controller(leftBar, mainPanel);

        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void main(String[] args) throws IOException {
        new Base();
    }

    public interface Pageable {

        public void showView(String name);

    }

    public interface Navigatable {

        public void addActionListener(ActionListener listener);

    }

    public class MainPanel extends JPanel implements Pageable {

        private CardLayout cl = new CardLayout();
        private JPanel panelHolder = new JPanel(cl);

        public MainPanel() {
            FirstPage firstPage = new FirstPage(this);
            SecondPage secondPage = new SecondPage(this);
            setLayout(new GridLayout(0, 1));

            panelHolder.add(firstPage, "firstPage");
            panelHolder.add(secondPage, "secondPage");

            cl.show(panelHolder, "firstPage");
            add(panelHolder);

        }

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

        @Override
        public void showView(String name) {
            cl.show(panelHolder, name);
        }
    }

    public class LeftBar extends JPanel implements Navigatable {

        private JButton button;
        private MainPanel mainPanel;

        public LeftBar(MainPanel mainPanel) {
            this.mainPanel = mainPanel;

            setPreferredSize(new Dimension(200, 40));
            setLayout(new BorderLayout());
            setBackground(Color.black);

            button = new JButton("Show Second Page");

            add(button, BorderLayout.NORTH);
        }

        @Override
        public void addActionListener(ActionListener listener) {
            button.addActionListener(listener);
        }
    }

    public class SecondPage extends JPanel {

        MainPanel mainPanel;
        JButton button;

        public SecondPage(MainPanel mainPanel) {
            this.mainPanel = mainPanel;
            setBackground(Color.white);
            add(new JLabel("This is second page"));
        }
    }

    public class FirstPage extends JPanel {

        MainPanel mainPanel;
        JButton button;

        public FirstPage(MainPanel mainPanel) {
            this.mainPanel = mainPanel;
            setBackground(Color.GRAY);

            button = new JButton("Show page");
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                    mainPanel.showPanel("secondPage");
                }

            });

            add(button);
        }
    }

    public class Controller {

        private final Navigatable navigatable;
        private final Pageable pageable;

        public Controller(Navigatable navigatable, Pageable pageable) {
            this.navigatable = navigatable;
            this.pageable = pageable;

            navigatable.addActionListener(new ButtonListener());
        }

        class ButtonListener implements ActionListener {

            @Override
            public void actionPerformed(ActionEvent ae) {
                pageable.showView("secondPage");
            }
        }
    }
}

現在,就個人而言,這只是圍繞您的代碼的一些小技巧,就個人而言,我更希望有一個與單個視圖/合同進行交互的控制器,這使它非常簡單...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM