当我在类别按钮之后单击 select 按钮时,为什么不打印 String 而是打印 null?
When I click select button after category button, why isn't the String being printed and null being printed instead?
package simpleclass;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
public class SimpleClass extends BaseClass {
JButton b1 = new JButton("Category");
JButton b2 = new JButton("Select");
JFrame f = new JFrame();
SimpleClass() {
f.add(b1);
f.add(b2);
f.setLayout(new GridLayout(1, 2));
f.setSize(200, 200);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
new SubClass();
} catch (IOException ex) {
}
}
});
b2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(astring);
}
});
}
public static void main(String[] args) {
new SimpleClass();
}
}
class BaseClass {
String astring;
public void setString(String astring) {
this.astring = astring;
}
}
class SubClass extends BaseClass {
SubClass() throws FileNotFoundException {
super.setString("WHYnull");
}
}
在此代码中有一个基 class BaseClass
和两个子 class SimpleClass
和 SubClass
。有两个按钮。当按下按钮 "Category" 时,字符串 "astring" 被设置为 "WHYnull"。现在我的问题是,当我之后按下 "Select" 按钮时,为什么会打印 "null"?变量"astring"不是独占吗?
您说:
When the button "Category" is pressed, then the String "astring" is being set to "WHYnull".
是的,这是正确的,但仅适用于您在第一个 ActionListoner 中创建(和丢弃)的 new SubClass()
。对原程序的字段aString没有影响,当前的this
.
我的建议:这不是应该用继承来解决的问题。将继承完全排除在这幅图之外。
我愿意:
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// try {
// new SubClass();
// } catch (IOException ex) {
//
// }
setString("Fubar");
}
});
另请注意,您的代码不应包含空的 catch 块,因为那 Java 相当于闭着眼睛开车。是的,令人兴奋,但也非常危险。
您询问了使用多个 类 的 GUI,一个常见的例子是模型-视图-控制或 MVC 类型的程序设计,其中程序的逻辑驻留在模型中,GUI 驻留在视图中,并且两者在控件中的交互。例如,以您的小程序为例,可以这样做:
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class SimpleMCV {
private static void createAndShowGui() {
final SimpleView simpleView = new SimpleView();
final SimpleModel simpleModel = new SimpleModel("");
MainControl mainControl = new MainControl();
mainControl.setUp(simpleView, simpleModel);
JFrame frame = new JFrame("Simple GUI");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(simpleView);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
@SuppressWarnings("serial")
class SimpleView extends JPanel {
private JTextField textField = new JTextField(10);
public SimpleView() {
textField.setFocusable(false);
add(textField);
}
public void setTextFieldText(String text) {
textField.setText(text);
}
public void addAction(Action action) {
add(new JButton(action));
}
}
class MainControl {
public void setUp(final SimpleView simpleView, final SimpleModel simpleModel) {
simpleView.addAction(new SimpleControl(simpleModel, "Fubar"));
simpleView.addAction(new SimpleControl(simpleModel, "Snafu"));
simpleView.addAction(new SimpleControl(simpleModel, "Bohica"));
simpleModel.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
simpleView.setTextFieldText(simpleModel.getSomeText());
}
});
}
}
@SuppressWarnings("serial")
class SimpleControl extends AbstractAction {
private SimpleModel simpleModel;
public SimpleControl(SimpleModel simpleModel, String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
this.simpleModel = simpleModel;
}
@Override
public void actionPerformed(ActionEvent e) {
simpleModel.setSomeText(e.getActionCommand());
}
}
class SimpleModel {
private List<ChangeListener> listenerList = new ArrayList<>();
private String someText;
public SimpleModel(String someText) {
this.someText = someText;
}
public String getSomeText() {
return someText;
}
// change text and notify all listeners
public void setSomeText(String someText) {
this.someText = someText;
for (ChangeListener changeListener : listenerList) {
changeListener.stateChanged(new ChangeEvent(this));
}
}
// allow outside classes to add a ChangeListener
public void addChangeListener(ChangeListener cl) {
listenerList.add(cl);
}
}
package simpleclass;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
public class SimpleClass extends BaseClass {
JButton b1 = new JButton("Category");
JButton b2 = new JButton("Select");
JFrame f = new JFrame();
SimpleClass() {
f.add(b1);
f.add(b2);
f.setLayout(new GridLayout(1, 2));
f.setSize(200, 200);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
new SubClass();
} catch (IOException ex) {
}
}
});
b2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(astring);
}
});
}
public static void main(String[] args) {
new SimpleClass();
}
}
class BaseClass {
String astring;
public void setString(String astring) {
this.astring = astring;
}
}
class SubClass extends BaseClass {
SubClass() throws FileNotFoundException {
super.setString("WHYnull");
}
}
在此代码中有一个基 class BaseClass
和两个子 class SimpleClass
和 SubClass
。有两个按钮。当按下按钮 "Category" 时,字符串 "astring" 被设置为 "WHYnull"。现在我的问题是,当我之后按下 "Select" 按钮时,为什么会打印 "null"?变量"astring"不是独占吗?
您说:
When the button "Category" is pressed, then the String "astring" is being set to "WHYnull".
是的,这是正确的,但仅适用于您在第一个 ActionListoner 中创建(和丢弃)的 new SubClass()
。对原程序的字段aString没有影响,当前的this
.
我的建议:这不是应该用继承来解决的问题。将继承完全排除在这幅图之外。
我愿意:
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// try {
// new SubClass();
// } catch (IOException ex) {
//
// }
setString("Fubar");
}
});
另请注意,您的代码不应包含空的 catch 块,因为那 Java 相当于闭着眼睛开车。是的,令人兴奋,但也非常危险。
您询问了使用多个 类 的 GUI,一个常见的例子是模型-视图-控制或 MVC 类型的程序设计,其中程序的逻辑驻留在模型中,GUI 驻留在视图中,并且两者在控件中的交互。例如,以您的小程序为例,可以这样做:
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class SimpleMCV {
private static void createAndShowGui() {
final SimpleView simpleView = new SimpleView();
final SimpleModel simpleModel = new SimpleModel("");
MainControl mainControl = new MainControl();
mainControl.setUp(simpleView, simpleModel);
JFrame frame = new JFrame("Simple GUI");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(simpleView);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
@SuppressWarnings("serial")
class SimpleView extends JPanel {
private JTextField textField = new JTextField(10);
public SimpleView() {
textField.setFocusable(false);
add(textField);
}
public void setTextFieldText(String text) {
textField.setText(text);
}
public void addAction(Action action) {
add(new JButton(action));
}
}
class MainControl {
public void setUp(final SimpleView simpleView, final SimpleModel simpleModel) {
simpleView.addAction(new SimpleControl(simpleModel, "Fubar"));
simpleView.addAction(new SimpleControl(simpleModel, "Snafu"));
simpleView.addAction(new SimpleControl(simpleModel, "Bohica"));
simpleModel.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
simpleView.setTextFieldText(simpleModel.getSomeText());
}
});
}
}
@SuppressWarnings("serial")
class SimpleControl extends AbstractAction {
private SimpleModel simpleModel;
public SimpleControl(SimpleModel simpleModel, String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
this.simpleModel = simpleModel;
}
@Override
public void actionPerformed(ActionEvent e) {
simpleModel.setSomeText(e.getActionCommand());
}
}
class SimpleModel {
private List<ChangeListener> listenerList = new ArrayList<>();
private String someText;
public SimpleModel(String someText) {
this.someText = someText;
}
public String getSomeText() {
return someText;
}
// change text and notify all listeners
public void setSomeText(String someText) {
this.someText = someText;
for (ChangeListener changeListener : listenerList) {
changeListener.stateChanged(new ChangeEvent(this));
}
}
// allow outside classes to add a ChangeListener
public void addChangeListener(ChangeListener cl) {
listenerList.add(cl);
}
}