你好,我有类似的东西
public class GUI{
public JCheckBox box;
public boolean value;
void init(){
box.addActionListener(new BoxListener(this));
}
}
public class BoxListener implements ActionListener{
GUI gui;
public BoxListener(GUI gui){
this.gui = gui;
}
@override
public void actionperformed(ActionEvent a){
gui.value = true;
}
}
现在我想在单击复选框时更改bool的值。 我正在寻找更好的解决方案,而不是将类GUI作为自编写侦听器的输入参数。
有没有更好的解决方案?
答案 0 :(得分:2)
我会投入一些MVC它需要做更多的工作,但它可以实现更灵活的编码。
首先ModelBean
boolean checked
和propertyChangeSupport
用于触发属性更改事件
import java.beans.*;
import java.io.Serializable;
public class ModelBean implements Serializable {
private boolean checked;
private PropertyChangeSupport propertySupport;
public ModelBean() {
propertySupport = new PropertyChangeSupport(this);
}
public boolean getChecked() {
return checked;
}
public void setChecked(boolean checked) {
boolean oldValue = this.checked;
this.checked = checked;
propertySupport.firePropertyChange("checked", oldValue, this.checked);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertySupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertySupport.removePropertyChangeListener(listener);
}
}
然后你有一个以GUI
为参数的主ModelBean
类
class GUI extends JFrame {
private ModelBean model;
private JCheckBox cbox;
public GUI(ModelBean model) {
this.model = model;
cbox = new JCheckBox("Check and watch me print");
cbox.addItemListener(new CheckListener(model));
setLayout(new GridBagLayout());
add(cbox);
setSize(300, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
}
您ItemListener
的课程采用相同的ModelBean
作为参数,并将PropertyChangeListener
添加到model
class CheckListener implements ItemListener {
private ModelBean model;
public CheckListener(ModelBean newModel) {
this.model = newModel;
model.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
System.out.println(model.getChecked());
}
});
}
@Override
public void itemStateChanged(ItemEvent e) {
JCheckBox source = (JCheckBox) e.getSource();
if (source.isSelected()) {
model.setChecked(true);
} else {
model.setChecked(false);
}
}
}
然后你上课来运行程序
public class TestMVC {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final ModelBean model = new ModelBean();
GUI gui = new GUI(model);
}
});
}
}
对于一个愚蠢的boolean
而言似乎需要做很多工作,但这个概念对于大型程序来说是一个更好的整体设计,在这些程序中需要操作和收听大量不同的数据。
<强>更新强>
另一个选择,如果您的GUI是父容器,并且您不想通过引用传递它来公开它,您可以创建interface
并让GUI
实现它
public interface BooleanInterface {
public void setBoolean(boolean bool);
}
public class GUI extends JFrame implements BooleanInterface {
boolean bool;
@Override
public void setBoolean(boolean bool) {
this.bool = bool;
}
}
public BoxListener implements ActionListener {
BooleanInterface boolFace;
public BoxListener(BooleanInterface boolFace) {
this.boolFace = boolFace;
}
}
然后,您可以将GUI
传递给侦听器。虽然它看起来和你正在做的一样,但它实际上不是,因为它不再公开GUI
,而是使用接口。
答案 1 :(得分:1)
为什么我们不拿你拥有的东西并稍微修改它:
首先,创建一个控制器(DefaultController
)类,它将处理初始化应用程序并将保留对GUI的引用(或查看)
public class DefaultController
{
private final GUI view = new GUI(); // The view
private void init()
{
// ...
this.view.addBoxListener(new BoxListener(this.view));
// ...
}
public static void main(String[] args)
{
// ... Start up code ...
}
}
接下来,修改您的GUI
类以包含与JCheckBox
交互的方法并注册一个监听器:
public class GUI
{
private JCheckBox box;
// ...
public void addBoxListener(ItemListener listener)
{
box.addItemListener(listener);
}
public void setBoxValue(boolean selected)
{
box.setSelected(selected);
}
// ...
}
现在您的BoxListener
有一个视图实例(GUI
),可以调用通过提供的界面设置复选框的值。您不再直接访问box
成员变量(封装)。这样您就可以在不影响调用者的情况下对setBoxValue
方法进行更改。
在BoxListener
课程中:
@Override
public void itemStateChanged(ItemEvent evt)
{
view.setBoxValue(true); // For example...
}
注意:view
是BoxListener
的成员变量 - private GUI view;