action对象 java_Java:如何从AbstractAction对象引用GUI组件?

你想尽可能地松开耦合,而不是像你的问题所暗示的那样收紧耦合,为了做到这一点,我认为你应该进一步抽象,通过将部分进一步分离成一个成熟的MVC程序.然后,侦听器(Action)可以更改模型,作为GUI的视图可以监听模型的更改并进行相应的响应.

例如:

import java.awt.BorderLayout;

import java.awt.Component;

import java.awt.Dimension;

import java.awt.GridBagLayout;

import java.awt.event.ActionEvent;

import java.awt.event.KeyEvent;

import java.beans.PropertyChangeEvent;

import java.beans.PropertyChangeListener;

import javax.swing.*;

import javax.swing.event.SwingPropertyChangeSupport;

public class MvcEg {

private static void createAndShowGui() {

View view = new MvcEgView();

Model model = new MvcEgModel();

new MvcEgControl(model,view);

JFrame frame = new JFrame("MvcEg");

frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);

frame.getContentPane().add(view.getMainPanel());

frame.pack();

frame.setLocationByPlatform(true);

frame.setVisible(true);

}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

createAndShowGui();

}

});

}

}

interface View {

void setMyButtonAction(Action action);

Component getMainPanel();

void setStatusLabelText(String text);

}

@SuppressWarnings("serial")

class MvcEgView implements View {

private static final int PREF_W = 500;

private static final int PREF_H = 400;

private static final String STATUS_TEXT = "Status: ";

private JPanel mainPanel = new JPanel() {

@Override

public Dimension getPreferredSize() {

return new Dimension(PREF_W,PREF_H);

}

};

private JLabel statusLabel = new JLabel(STATUS_TEXT,SwingConstants.CENTER);

private JButton myButton = new JButton();

public MvcEgView() {

JPanel btnPanel = new JPanel(new GridBagLayout());

btnPanel.add(myButton);

mainPanel.setLayout(new BorderLayout());

mainPanel.add(btnPanel,BorderLayout.CENTER);

mainPanel.add(statusLabel,BorderLayout.SOUTH);

}

@Override

public void setMyButtonAction(Action action) {

myButton.setAction(action);

}

@Override

public void setStatusLabelText(String text) {

statusLabel.setText(STATUS_TEXT + text);

}

@Override

public Component getMainPanel() {

return mainPanel;

}

}

interface Model {

public static final String MOD_FIVE_STATUS = "mod five status";

void incrementStatus();

ModFiveStatus getModFiveStatus();

void removePropertyChangeListener(PropertyChangeListener listener);

void addPropertyChangeListener(PropertyChangeListener listener);

void setModFiveStatus(ModFiveStatus modFiveStatus);

}

class MvcEgModel implements Model {

private ModFiveStatus modFiveStatus = ModFiveStatus.ZERO;

private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(

this);

@Override

public void incrementStatus() {

int value = modFiveStatus.getValue();

value++;

value %= ModFiveStatus.values().length;

setModFiveStatus(ModFiveStatus.getValuesStatus(value));

}

@Override

public void setModFiveStatus(ModFiveStatus modFiveStatus) {

ModFiveStatus oldValue = this.modFiveStatus;

ModFiveStatus newValue = modFiveStatus;

this.modFiveStatus = modFiveStatus;

pcSupport.firePropertyChange(MOD_FIVE_STATUS,oldValue,newValue);

}

@Override

public ModFiveStatus getModFiveStatus() {

return modFiveStatus;

}

@Override

public void addPropertyChangeListener(PropertyChangeListener listener) {

pcSupport.addPropertyChangeListener(listener);

}

@Override

public void removePropertyChangeListener(PropertyChangeListener listener) {

pcSupport.removePropertyChangeListener(listener);

}

}

enum ModFiveStatus {

ZERO(0,"Zero"),ONE(1,"One"),TWO(2,"Two"),THREE(3,"Three"),FOUR(4,"Four");

private int value;

private String text;

private ModFiveStatus(int value,String text) {

this.value = value;

this.text = text;

}

public int getValue() {

return value;

}

public String getText() {

return text;

}

public static ModFiveStatus getValuesStatus(int value) {

if (value < 0 || value >= values().length) {

throw new ArrayIndexOutOfBoundsException(value);

}

for (ModFiveStatus modFiveStatus : ModFiveStatus.values()) {

if (modFiveStatus.getValue() == value) {

return modFiveStatus;

}

}

// default that should never happen

return null;

}

}

@SuppressWarnings("serial")

class MvcEgControl {

private Model model;

private View view;

public MvcEgControl(final Model model,final View view) {

this.model = model;

this.view = view;

view.setMyButtonAction(new MyButtonAction("My Button",KeyEvent.VK_B));

view.setStatusLabelText(model.getModFiveStatus().getText());

System.out.println("model's status: " + model.getModFiveStatus());

System.out.println("model's status text: " + model.getModFiveStatus().getText());

model.addPropertyChangeListener(new ModelListener());

}

private class MyButtonAction extends AbstractAction {

public MyButtonAction(String text,int mnemonic) {

super(text);

putValue(MNEMONIC_KEY,mnemonic);

}

@Override

public void actionPerformed(ActionEvent e) {

model.incrementStatus();

System.out.println("button pressed");

}

}

private class ModelListener implements PropertyChangeListener {

@Override

public void propertyChange(PropertyChangeEvent evt) {

if (evt.getPropertyName().equals(Model.MOD_FIVE_STATUS)) {

String status = model.getModFiveStatus().getText();

view.setStatusLabelText(status);

System.out.println("status is: " + status);

}

}

}

}

在我看来,关键是模型对视图一无所知,并且视图对模型知之甚少(这里没有).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值