【问题标题】:How to access multiple JPanels inside JFrame?如何访问 JFrame 中的多个 JPanel?
【发布时间】:2008-11-26 10:08:01
【问题描述】:
我有一个JFrame,其中包含一个“显示”JPanel 和一个JTextField 和一个“控件”JPanel,其中的按钮应该可以访问显示JPanel 的内容。我认为我的问题与如何使用观察者模式有关,原则上我理解。您需要放置侦听器并更新消息,但我不知道将这些放在哪里,如何从一个面板访问另一个面板,并且可能在必要时引入“数据模型”类。例如,我想从控制面板访问JTextField 的内容,我使用匿名动作监听器如下:
JButton openfile = new JButton("Convert file");
openfile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openButtonPressed();
}
});
【问题讨论】:
标签:
java
design-patterns
swing
controller
jpanel
【解决方案1】:
你需要减少这些对象之间的耦合。
您可以拥有一个主对象,它拥有所有文本字段和按钮(面板无关)
然后是那个主对象中的一个单独的动作监听器(我称之为调解器,参见调解器模式)
该动作侦听器在中介上执行一个方法,该方法反过来从文本字段中获取值并可能创建一个传输对象。
这样可以减少面板、文本字段等之间的耦合,并将控件放在一个地方(中介),也就是说,您不会让它们彼此认识。
你可以看看这个问题中的代码:
https://stackoverflow.com/questions/324554/#324559
它在运行代码中显示了这些概念。
顺便说一句,观察者模式已经在 JTextField、JButton、ActionListener 等中实现了。你只需要添加钩子。
我希望这会有所帮助。
编辑将两个答案合二为一。
这是代码。
class App { // this is the mediator
// GUI components.
private JFrame frame;
private JTextField name;
private JTextField count;
private JTextField date;
// Result is displayed here.
private JTextArea textArea;
// Fired by this button.
private JButton go;
private ActionListener actionListener;
public App(){
actionListener = new ActionListener(){
public void actionPerformed( ActionEvent e ){
okButtonPressed();
}
};
}
private void okButtonPressed(){
// template is an object irrelevant to this code.
template.setData( getData() );
textArea.setText( template.getTransformedData() );
}
public void initialize(){
frame = new JFrame("Code challenge v0.1");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
name = new JTextField();
count = new JTextField();
date = new JTextField();
textArea = new JTextArea();
go = new JButton("Go");
go.addActionListener( actionListener ); // prepare the button.
layoutComponents(); // a lot of panels are created here. Irrelevant.
}
}
完整的运行代码可以检索here:
在可能的情况下,优先考虑组合而不是继承是很重要的。
【解决方案2】:
如果您在一层中创建模型并在上面添加一两层来创建组件和布局,它确实会使代码更清晰。当然不要扩展JFrame和JPanel之类的东西。
感觉不需要让模型层中的合成层次与显示完全匹配。那么就只需要从Document中取出文本并进行相关操作即可。
好吧,也许没那么简单。摇摆模型有点乱。尤其是ButtonModel脑残,控制器区的代码可能不完全纯。
【解决方案3】:
我们有所谓的构建器,它将用子面板构建父面板。在此构建器中,您将可以访问您需要收听的所有子组件,因此可以在那里实现任何逻辑。
最后,构建器将返回包含完整逻辑的父面板。
一旦你有了父面板,就真的很麻烦,要让子组件做任何事情。
【解决方案4】:
谢谢。我添加了一个数据模型层,它以某种方式处理面板之间的通信。
我还在 JTextField 上的 Listeners 上发现此链接很有用:
link text