Java Swing FocusListener的MVC实现 [英] MVC implementation of Java Swing FocusListener

查看:164
本文介绍了Java Swing FocusListener的MVC实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用MVC体系结构模式构建一个简单的Java Swing应用程序。我所做的是在我的视图中创建用户界面组件(如私人),并有公共方法返回组件。这些方法然后由控制器调用,通过它我可以为事件/动作侦听器编写方法。下面是一个示例:

查看:

  private JButton btnAdd ; 

public JButton getBtnAdd(){
return btnAdd;

code


控制:

  myGuiFrame gui = new myGuiFrame(); 

$ b $ //添加按钮点击
gui.getBtnAdd()。addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
//调用模型
}
});

这是否正确?

所以,那么我有一个FocusListeners的问题。当我在我的视图中创建FocusListener时,focusLost和focusGained方法在视图中创建。

  private FocusListener l; 

someComponent.addFocusListener(l);

l = new FocusListener(){

@Override
public void focusLost(FocusEvent e){
// TODO自动生成方法存根


@Override
public void focusGained(FocusEvent e){
// TODO自动生成的方法存根

}
};

我希望所有的事件处理程序都在我的控制器中。我的问题是...有没有一种方法可以调用/从我的控制器声明focusLost和focusGained方法?我尝试将FocusListener定义为public,以便我可以在控制器中定义它:

view:

  public FocusListener l; 
public someComponentType someComponent;

控制器:

  gui.l = new FocusListener(){
@Override
public void focusLost(FocusEvent e){
// TODO自动生成的方法存根



@Override
public void focusGained(FocusEvent e){
// TODO自动生成的方法存根
gui.someComponent.addFocusListener(gui.l );

$ b $ / code $ / pre
$ b $ p

$ p
$ b

是否可以从控制器处理FocusEvent?



编辑:



天哪,我的不好。不太明白罗宾是怎么回事。我太注意FocusListener明确定义的地方。一个简单的例子:

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ @ $
public void focusLost(FocusEvent e){
// TODO自动生成的方法存根


$ b @Override
public void focusGained (FocusEvent e){
// TODO自动生成的方法存根
System.out.println(YES !!!);
}
});在控制器中的

在我打算做的事情方面工作得很好,不过我很喜欢没关系了。只是出于好奇,是否有一个标准的或广泛接受的方式在Swing应用上实现MVC?

解决方案

据我了解,你这样做的方式是这样的。更好的是,我更喜欢匿名类,他们尊重封装的概念。这里试试看这个代码,看看你能用这个理解什么:

  import java.awt。*; 
import java.awt.event。*;
import javax.swing。*;

public class View
{
private JButton focusButton;
私人JButton spareButton;
$ b $ private void createAndDisplayGUI()
{
JFrame frame = new JFrame(VIEW);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

JPanel contentPane = new JPanel();
contentPane.setLayout(new FlowLayout(FlowLayout.LEFT,5,5));

focusButton = new JButton(GAINED / LOST);
focusButton.addFocusListener(new ButtonController(this));

spareButton = new JButton(SPARE);
spareButton.setOpaque(true);
spareButton.addActionListener(new ButtonController(this));
spareButton.addFocusListener(new ButtonController(this));

contentPane.add(focusButton);
contentPane.add(spareButton);

frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}

public JButton getFocusButton()
{
return focusButton;
}

public JButton getSpareButton()
{
return spareButton;


public static void main(String ... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new View()。createAndDisplayGUI();
}
});



类ButtonController实现了FocusListener,ActionListener
{
private View View;
私人JButton focusButton;
私人JButton spareButton;

public ButtonController(View v)
{
view = v;
focusButton = view.getFocusButton();
spareButton = view.getSpareButton();

$ b $ public void actionPerformed(ActionEvent ae)
{
JButton button =(JButton)ae.getSource();

if(button == spareButton)
{
spareButton.setBackground(Color.BLUE);
focusButton.setEnabled(true);


$ b public void focusGained(FocusEvent fe)
{
JButton button =(JButton)fe.getSource();

if(button == focusButton)
{
focusButton.setEnabled(true);
}
else if(button == spareButton)
{
spareButton.setBackground(Color.WHITE);


$ b public void focusLost(FocusEvent fe)
{
JButton button =(JButton)fe.getSource();

if(button == focusButton)
{
focusButton.setEnabled(false);

else if(button == spareButton)
{
spareButton.setBackground(Color.DARK_GRAY.darker());





$ b另一个方法,如果你觉得(> getters / setters )并发送引用的方法是定义一个内部类,如下所示(前面例子的一个简单的解决方法):

  import java.awt。*; 
import java.awt.event。*;
import javax.swing。*;

public class View
{
private JButton focusButton;
私人JButton spareButton;
$ b $ private void createAndDisplayGUI()
{
JFrame frame = new JFrame(VIEW);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

JPanel contentPane = new JPanel();
contentPane.setLayout(new FlowLayout(FlowLayout.LEFT,5,5));

focusButton = new JButton(GAINED / LOST);
focusButton.addFocusListener(new ButtonController());

spareButton = new JButton(SPARE);
spareButton.setOpaque(true);
spareButton.addActionListener(new ButtonController());
spareButton.addFocusListener(new ButtonController());

contentPane.add(focusButton);
contentPane.add(spareButton);

frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);

$ b $ private class ButtonController实现了FocusListener,ActionListener
{

public void actionPerformed(ActionEvent ae)
{
JButton button =(JButton)ae.getSource();

if(button == spareButton)
{
spareButton.setBackground(Color.BLUE);
focusButton.setEnabled(true);


$ b public void focusGained(FocusEvent fe)
{
JButton button =(JButton)fe.getSource();

if(button == focusButton)
focusButton.setEnabled(true);
else if(button == spareButton)
spareButton.setBackground(Color.WHITE);

$ b $ public void focusLost(FocusEvent fe)
{
JButton button =(JButton)fe.getSource();

if(button == focusButton)
focusButton.setEnabled(false);
else if(button == spareButton)
spareButton.setBackground(Color.DARK_GRAY.darker());


$ b $ public static void main(String ... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new View()。createAndDisplayGUI();
}
});
}
}


I'm trying to build a simple Java Swing application using the MVC architecture pattern. What I've done is create the user interface components (as private) in my views, and have public methods that return the components. These methods are then called by the controllers, through which I can write methods for event/action listeners. Below is a sample example:

View:

private JButton btnAdd;

    public JButton getBtnAdd(){
        return btnAdd;
    }

Control:

myGuiFrame gui = new myGuiFrame();


        //on add button clicked
    gui.getBtnAdd().addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            //calls to model
        }
    });

Is this implementation correct?

If so, then I'm having a problem with FocusListeners. When I create a FocusListener in my view, the focusLost and focusGained methods are created within the view.

private FocusListener l;

someComponent.addFocusListener(l);

        l = new FocusListener() {

            @Override
            public void focusLost(FocusEvent e) {
                // TODO Auto-generated method stub
            }

            @Override
            public void focusGained(FocusEvent e) {
                // TODO Auto-generated method stub

            }
        };

I want all the event handlers to be in my controllers. My question is ... is there a way I can call/declare the focusLost and focusGained methods from my controller? I tried to define the FocusListener as public so that I can define it in my controller:

view:

public FocusListener l;
public someComponentType someComponent;

controller:

gui.l = new FocusListener() {
    @Override
    public void focusLost(FocusEvent e) {
        // TODO Auto-generated method stub

}

@Override
public void focusGained(FocusEvent e) {
    // TODO Auto-generated method stub
    gui.someComponent.addFocusListener(gui.l);

    }   

};

This however does not work.

Is it possible to handle FocusEvents from the controller?

EDIT:

Gosh, my bad. Didn't quite understand what Robin was all about. I was too fixated on having the FocusListener explicitly defined somewhere. A simple:

    gui.getTextFieldEmployeeCode().addFocusListener(new FocusListener() {

        @Override
        public void focusLost(FocusEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void focusGained(FocusEvent e) {
            // TODO Auto-generated method stub
            System.out.println("YES!!!");
        }
    });

in the controller would work just fine in the manner I planned to do it, though I quite like how nIcE cOw's gone about it. Just out of curiosity, is there a standard or widely accepted manner of implementing MVC on Swing Apps?

解决方案

As far as I understood, the way you doing is this. Better still, I prefer the Anonymous Classes, they respect the concept of Encapsulation. Here try your hands on this code, see what you can grasp with this :

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class View
{
    private JButton focusButton;
    private JButton spareButton;

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("VIEW");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));

        focusButton = new JButton("GAINED/LOST");
        focusButton.addFocusListener(new ButtonController(this));

        spareButton = new JButton("SPARE");
        spareButton.setOpaque(true);
        spareButton.addActionListener(new ButtonController(this));
        spareButton.addFocusListener(new ButtonController(this));

        contentPane.add(focusButton);
        contentPane.add(spareButton);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public JButton getFocusButton()
    {
        return focusButton;
    }

    public JButton getSpareButton() 
    {
        return spareButton;
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new View().createAndDisplayGUI();
            }
        });
    }
}

class ButtonController implements FocusListener, ActionListener
{
    private View view;
    private JButton focusButton;
    private JButton spareButton;

    public ButtonController(View v)
    {
        view = v;
        focusButton = view.getFocusButton();
        spareButton = view.getSpareButton();
    }

    public void actionPerformed(ActionEvent ae)
    {
        JButton button = (JButton) ae.getSource();

        if (button == spareButton)
        {
            spareButton.setBackground(Color.BLUE);
            focusButton.setEnabled(true);
        }
    }

    public void focusGained(FocusEvent fe)
    {
        JButton button = (JButton) fe.getSource();

        if (button == focusButton)
        {
            focusButton.setEnabled(true);
        }
        else if (button == spareButton)
        {
            spareButton.setBackground(Color.WHITE);
        }
    }

    public void focusLost(FocusEvent fe)
    {
        JButton button = (JButton) fe.getSource();

        if (button == focusButton)
        {
            focusButton.setEnabled(false);
        }
        else if (button == spareButton)
        {
            spareButton.setBackground(Color.DARK_GRAY.darker());
        }
    }
}

Another approach, if you feel irritated by getters/setters and sending references around, is to define one inner class as follows (A Simple workaround for the previous example) :

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class View
{
    private JButton focusButton;
    private JButton spareButton;

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("VIEW");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));

        focusButton = new JButton("GAINED/LOST");
        focusButton.addFocusListener(new ButtonController());

        spareButton = new JButton("SPARE");
        spareButton.setOpaque(true);
        spareButton.addActionListener(new ButtonController());
        spareButton.addFocusListener(new ButtonController());

        contentPane.add(focusButton);
        contentPane.add(spareButton);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private class ButtonController implements FocusListener, ActionListener
    {

        public void actionPerformed(ActionEvent ae)
        {
            JButton button = (JButton) ae.getSource();

            if (button == spareButton)
            {
                spareButton.setBackground(Color.BLUE);
                focusButton.setEnabled(true);
            }
        }

        public void focusGained(FocusEvent fe)
        {
            JButton button = (JButton) fe.getSource();

            if (button == focusButton)
                focusButton.setEnabled(true);
            else if (button == spareButton)
                spareButton.setBackground(Color.WHITE);
        }

        public void focusLost(FocusEvent fe)
        {
            JButton button = (JButton) fe.getSource();

            if (button == focusButton)
                focusButton.setEnabled(false);
            else if (button == spareButton)
                spareButton.setBackground(Color.DARK_GRAY.darker());
        }
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new View().createAndDisplayGUI();
            }
        });
    }
}

这篇关于Java Swing FocusListener的MVC实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆