gpt4 book ai didi

java - 为什么 ActionListener 在 Controller 中不起作用?

转载 作者:行者123 更新时间:2023-12-02 04:46:54 26 4
gpt4 key购买 nike

这篇文章是this post.的继续基本上我的软件是基于CardLayout面板。现在我想从 cardLayout 外部更改面板。在提供的链接中,我得到了帮助来做到这一点并且它有效。现在,我在软件中添加了一个 Controller ,位于内部面板 ( CardLayout ) 和外部面板之间。在外部面板(leftBar)中,我有一个按钮,如果它是actionListener位于该类内部,它可以正常工作并打开 CardLayout 所选择的内部面板。但如果我采取 ActionListener进入 Controller ,它就是不起作用。没有出现错误。

这是我的示例代码:基础:

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);
}
}

和 Controller :

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 。我在 Controller 中调用该方法并给它一个类。但这不起作用。然而ACtionListener如果它位于 LeftBar 类(内联)中,则有效。

知道如何修复它吗?

最佳答案

您正在创建 LeftBar 的两个实例,其中一个位于 Base 构造函数中,该实例将添加到屏幕上...

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 构造函数中传递给 Controller ​​...

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 将一个 ActionListener 附加到屏幕上永远不可见的按钮

我要做的第一件事是开始解耦你的代码,而不是传递类的实例,你需要建立一系列 Controller 和 View 可以同意的契约,例如,你的 MainPanel 应该提供一种切换 View 的方法,您的 LeftBar 应该在用户想要切换 View 时提供通知

例如...

public interface Pageable {

public void showView(String name);

}

public interface Navigatable {

public void addActionListener(ActionListener listener);

}

然后你的主视图将实现Pageable接口(interface)

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

并且您的LeftBar将实现Navigatable接口(interface)

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

这只是定义了任何实现的契约(Contract)功能,您的 Controller 不应该关心任何其他事情(也不应该允许它做不该做的事情,比如从 View 中删除所有组件,顽皮的 Controller )

然后你的 Controller 就负责管理接口(interface)之间的契约......

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");
}
}
}
}

现在就我个人而言,这只是对您的代码进行一些黑客攻击,就我个人而言,我更喜欢有一个与单个 View /合约交互的 Controller ,它使它变得如此简单......

关于java - 为什么 ActionListener 在 Controller 中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29597973/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com