- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
通常需要根据另一个 GUI 对象的状态来更改其他 GUI 对象的行为。例如。按下按钮时,标签应更改其名称。但是,当我使用像 JButton myButton = new JButton(myButtonAction);
这样的 AbstractAction 对象时,我需要在继承自 AbstractAction 的对象中引用 GUI 对象。我应该只在 GUI 中创建 AbstractAction 对象,然后将所有必要的 GUI 引用传递给 AbstractAction 对象,还是这会被认为是不好的风格?
为了使它更具体:
// AbstractAction
public class MyAction extends AbstractAction {
public MyAction(String name,
String description, Integer mnemonic, JLabel) {
super(name);
putValue(SHORT_DESCRIPTION, description);
putValue(MNEMONIC_KEY, mnemonic);
}
public void actionPerformed(ActionEvent e) {
// do something
}
}
}
public class GUI{
public Action myAction = null;
public GUI(){
JLabel label = new JLabel("text");
//This is not a good idea:
myAction = new MyAction("some text" , desc, new Integer(KeyEvent.VK_Q), label);
JButton myButton = new JButton(myAction);
}
}
最佳答案
您想尽可能地放松耦合,而不是像您的问题所暗示的那样加强耦合,为此,我认为您应该进一步抽象,将部分进一步分离成一个完整的 MVC 程序。然后监听器(Action)可以更改模型,而作为您的 GUI 的 View 可以监听模型的更改并做出相应的响应。
例如:
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);
}
}
}
}
在我看来,关键是模型对 View 一无所知,而 View 对模型知之甚少(此处为一无所知)。
关于Java:如何从 AbstractAction 对象引用 GUI 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17503652/
我想在运行时将一系列 Swing 操作加载到容器中,并通过常量名称访问它们,就像使用枚举一样。这样做的目的是限制可能的操作并提高可读性。 最初,我正在考虑一种动态枚举(请参阅 http://blog.
我的要求是添加两个图标到抽象操作示例:图标 + 操作名称 + 图标AbstractAction 有一个 super 构造函数来仅添加一个图标 最佳答案 通过将操作标签设置为 HTML 解决了此问题 关
我有一个 JMenuItem 绑定(bind)到一个 Action,我可以使用 item.getAction() 获取它。 Action 名称在构造 Action 时设置,例如使用匿名 new Abs
请原谅这个模糊的问题标题,但通常我不会做这样的事情。所以我有以下问题: 我正在为特定应用程序设计一个弹出菜单,其中每个菜单项都与特定操作相关联: public class CanvasMenu ext
我正在尝试使用子类 ColorAction 来扩展 AbstractAction 类。此类处理 ActionPerformed 方法的方法是获取用户的字符串格式输入,并将其与 colorKey 中的
这个问题在这里已经有了答案: event handling in java and the execution of actionPerformed method in java (5 个答案) 关
我试图通过使用 Action 对象将我的 GUI 应用程序中的功能与状态分开。我已经成功地使用它们来创建具有相同功能的菜单项和按钮。 我的问题是:我想对菜单中的“退出”项和框架的关闭按钮执行相同的操作
在主视图/详细 View 中,我有一系列文本字段(以及一个或两个其他控件),它们都与当前所选项目的详细信息有关。它们都共享相同的 DocumentListener,因此如果您更改其中任何一个,将启用一
在一个简单的计算器应用程序中,我使用抽象操作来处理用鼠标单击的按钮以及按下的相应数字键盘键(带有键绑定(bind))。我希望在使用键盘时发生某些外观更改,例如当我按下数字 1 键时更改 JButton
我正在尝试编写一个程序来创建 JPanel,当用户按下 W、A、S 和 D 时,绘制的立方体将在窗口中导航(每次按下某个键时都会导航一定量) Pressed),我创建了 MoveCubeUp 类,并重
我正在制作一款游戏,用户必须按键才能移动。我正在使用键绑定(bind),但它们不起作用。键绑定(bind)应该调用 Wp 类并打印“W按下”,但没有任何反应。代码如下: public class SO
类AbstractAction实现接口(interface)Action,但是在Action中,有一个方法actionPerformed(ActionEvent e),它继承自接口(interface
好的。我有一个大型项目,其中一个特定的 jtable 在启动时创建并且永远不会重建。根据各种用户操作刷新表格模型并重绘表格。 我添加了一个自定义的 TableCellListener 类以响应单元格更
我遇到了一个奇怪的问题。由于在 GUI 中按下按钮,我需要将一些文本导出到文件中。但是,我无法将 IOException 应用于事件调用的 AbstractAction 的 actionPerform
通用代码... 出于某种原因,我的 JMenuItem 没有执行操作。 我做了一个框架,一个JMenuBar和一个JMenuItem,一切都在它应该在的地方。我可以很好地单击 JMenuItem,它会
如果您创建 AbstractActivity 子类,则必须定义以下方法: @Override public void start(AcceptsOneWidget panel, EventBus ev
我正在创建一个ToolBar与一个JButton和一些JCheckBox隐藏或显示 JTable 中的列. JButton主要目的是一旦点击重置所有其他JCheckBox在 ToolBar全部选中或全
通常需要根据另一个 GUI 对象的状态来更改其他 GUI 对象的行为。例如。按下按钮时,标签应更改其名称。但是,当我使用像 JButton myButton = new JButton(myButto
我的 java swing 应用程序有一些在两个 JMenuItems 中使用的 AbstractActions和 JButton。我想将其中一些放入 JButton 内的 JToolbar 中,但是
当我尝试使用 table.setValueAt() 粘贴到 JTable 单元格时,我粘贴的单元格保持空白,但是 setValueAt() 似乎在工作。此外,当我尝试从一个单元格中剪切或复制时,当我想
我是一名优秀的程序员,十分优秀!