无法通过第二页调用第三页
我想创建一个有三个页面的软件:“主页”(在JFrame“框架”上绘制),“第2页”和“第3页”。
第2页和第3页绘制在“框架”上。
一个使用位于页面左侧的导航窗格,主要内容保存在右侧。
我目前只能导航到第2页。 调用在JFrame上绘制第2页的类似乎无法调用第3页。
我的代码如下:
// The Home Page package Try; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class HomePage { JPanel panelHomeWrapper = new JPanel(); JPanel panelNavigation = new JPanel(); JPanel panelDisplay = new JPanel(); JButton buttonNavigation = new JButton("Button Home = Menu Items"); JButton buttonBody = new JButton("Button body Page Home = Home body Items"); public static void main (String[] args) { HomePage home = new HomePage(); home.homePanel(); } public void homePanel () { JFrame frame = new JFrame("Home"); JButton button = new JButton("Button"); ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { System.out.println("Panel 2 was called."); Page2 panel2 = new Page2(); panelNavigation.remove(buttonNavigation); panelDisplay.remove(buttonBody); panelNavigation.add(panel2.buttonNavigation); panelDisplay.add(panel2.buttonBody); panelNavigation.validate(); panelNavigation.repaint(); panelDisplay.validate(); panelDisplay.repaint(); } }; button.addActionListener(actionListener); buttonNavigation.addActionListener(actionListener); panelNavigation.add(buttonNavigation); panelDisplay.add(buttonBody); panelHomeWrapper.add(panelNavigation); panelHomeWrapper.add(panelDisplay); frame.add(panelHomeWrapper); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(455, 355); frame.setVisible(true); } } // End of Home Page
第2页
// Page 2 package Try; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JPanel; public class Page2 { JButton buttonNavigation = new JButton("Button 2 = Menu Items"); JButton buttonBody = new JButton("Button body Page 2 = Page 2 body Items"); ActionListener actionListenerCallAnotherPage = new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { System.out.println("Button Body 3 was called."); HomePage home = new HomePage(); Page3 panel3 = new Page3(); home.panelDisplay.remove(buttonBody); home.panelDisplay.add(panel3.buttonBody3); home.panelDisplay.validate(); home.panelDisplay.repaint(); } }; public void addAction () { buttonNavigation.addActionListener(actionListenerCallAnotherPage); } }
第3页
// Page 3 package Try; import javax.swing.JButton; public class Page3 { JButton buttonBody3 = new JButton("Page 3"); } // End of Page 3
请帮我弄清楚如何让第二课(第2页)拨打第三课(第3页)。 谢谢大家。
问题似乎是你的Page2
类中的方法addAction
永远不会被调用。 它似乎负责将actionListenerCallAnotherPage
注册到buttonNavigation
JButton
….
现在,已经说过……这似乎是一项很难获得的努力。
您应该使用某种管理导航的模型,而不是尝试以这种方式硬链接导航。
基本上,您可以依次将此模型的引用传递给每个页面,并且每个页面在准备好后,请求模型移动到下一页。 该模型将触发某种更改事件,以向主视图指示当前页面已更改,并且视图将相应地更新自身。
您可以与CardLayout
,这意味着您甚至不需要向模型提供组件的引用,而是使用与CardLayout
关联的“页面名称”,进一步解耦程序。 。
基于模型的方法
基本的想法是将你的观点彼此分开,即使他们需要共享数据,我仍然使用某种数据模型,但让我们专注于导航模型。
你需要什么……
- 了解所有可用视图及其应显示的顺序
- 当前的“活跃”视图
- 一些改变视图的方法,例如上一个/下一个…
- 某种方式提供有关状态变化的通知……
- 您还希望将模型与实际组件分离。 虽然“严格地”说它并没有错,但我只是不喜欢让我的组件开始转移到他们可能在我不知情的情况下修改的地方,如果我可以帮助它。 更新视图也不是模型的责任,这是控制器的责任……这也意味着过去在屏幕上显示的实际组件与模型无关……
就像是…
public interface ViewModel { /** * Returns the name of the current "active" view name * @return */ public String getCurrentView(); /** * Instructs the model to move to the next view if one is * available... */ public void nextView(); /** * Instructs the model to move to the previous view if one is * available... */ public void previousView(); /** * Returns the number of views in this model */ public int size(); /** * Returns the name of the view at the specified index... * @param index * @return */ public String getViewAt(int index); /** * Adds a ChangeListeners to the model, which will be notified when * the current view changes */ public void addChangeListener(ChangeListener listener); /** * Remove a ChangeListeners from the model */ public void removeChangeListener(ChangeListener listener); }
…例如
现在,我喜欢有一个抽象的实现,它可以完成所有无聊,重复的工作……
public abstract class AbstractViewModel implements ViewModel { private EventListenerList listenerList; private List views; public void addView(String name) { getViews().add(name); } public void removeView(String name) { getViews().remove(name); } @Override public int size() { return views.size(); } @Override public String getCurrentView() { return getViewAt(getCurrentViewIndex()); } protected abstract int getCurrentViewIndex(); protected List getViews() { if (views == null) { views = new ArrayList<>(25); } return views; } @Override public String getViewAt(int index) { return index >= 0 && index < size() ? getViews().get(index) : null; } @Override public void addChangeListener(ChangeListener listener) { getListenerList().add(ChangeListener.class, listener); } @Override public void removeChangeListener(ChangeListener listener) { getListenerList().remove(ChangeListener.class, listener); } protected EventListenerList getListenerList() { if (listenerList == null) { listenerList = new EventListenerList(); } return listenerList; } protected void fireStateChanged() { ChangeListener[] listeners = getListenerList().getListeners(ChangeListener.class); if (listeners.length > 0) { ChangeEvent evt = new ChangeEvent(this); for (ChangeListener listener : listeners) { listener.stateChanged(evt); } } } }
这允许我设计不同的实现来满足我的需求……
例如,在这里,我提供了一个“线性”视图模型,该模型将一直移动到最后一个视图并停止或一直到第一个视图和停止。 创建一个圆形视图模型并不需要太多,当它到达模式的任何一端时,会翻转到另一端……
public class LinearViewModel extends AbstractViewModel { private int currentIndex; @Override protected int getCurrentViewIndex() { return currentIndex; } @Override public void nextView() { if (currentIndex + 1 < size()) { currentIndex++; fireStateChanged(); } } @Override public void previousView() { if (currentIndex - 1 >= 0) { currentIndex--; fireStateChanged(); } } }
首先,您需要一些方法将视图名称映射到代表组件。 你还需要一些方法来监控模型的变化……
private Map mapViews; private Component currentView; private LinearViewModel model; public ViewModelTest() { // Maps the view name to the component... mapViews = new HashMap<>(25); model = new LinearViewModel(); mapViews.put("Page01", new Page01()); mapViews.put("Page02", new Page02()); mapViews.put("Page03", new Page03()); mapViews.put("Page04", new Page04()); // Add the view names to the model... model.addView("Page01"); model.addView("Page02"); model.addView("Page03"); model.addView("Page04"); // Initialise out view with the first page... currentView = mapViews.get("Page01"); add(currentView); // Monitor for changes... model.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { remove(currentView); currentView = mapViews.get(model.getCurrentView()); add(currentView); revalidate(); } }); }
现在,您可能想知道,我的视图如何转移到下一个/上一个视图……?
它没有。 相反,我会创建一个导航栏,它将存在于主屏幕上,用于与模型本身交互…让每个页面/视图与整个过程分离…