对不起,如果这对你来说是另一个愚蠢的问题,但我仍然是Java编程语言的新手。
我有 3 个类:InputClass
、PreviewClass
和 MainClass
。
MainClass
包含运行程序的main method
。 InputClass
包含一个用于输入的private JTextField
和一个用于将文本设置到PreviewClass
JTextField
中的JButton
。 PreviewClass
包含一个专用JTextField
,用于在InputClass
中显示输入的文本。
我究竟如何做到这一点(在 PreviewClass
中为 JTextField
赋值(,而无需创建InputClass
的实例,然后使用 getter-method-like
获取它的值,或者,如果不使JTextField
在InputClass
中成为static
变量,以便我可以通过一些static method
访问它?
只是为了向您展示我的观点,这是代码:
-
输入类
import javax.swing.*; import java.awt.*; import java.awt.event.*; public class InputClass extends JPanel implements ActionListener{ private JTextField inputName; private JButton inputButton; public InputClass() { setLayout(new FlowLayout()); inputName=new JTextField(15); inputButton=new JButton("INPUT"); inputButton.addActionListener(this); add(inputName); add(inputButton); } @Override public void actionPerformed(ActionEvent event) { // How do I change/assign a text to the PreviewClass from here? } }
-
预览类
import javax.swing.*; import java.awt.*; public class PreviewClass extends JPanel{ private JTextField namePreview; public PreviewClass() { setLayout(new FlowLayout()); namePreview=new JTextField(15); namePreview.setEditable(false); add(namePreview); } }
-
主类
import javax.swing.*; import java.awt.*; public class MainClass extends JFrame{ private static final int FRAME_WIDTH=250; private static final int FRAME_HEIGHT=150; private static final int FRAME_X_ORIGIN=400; private static final int FRAME_Y_ORIGIN=300; private InputClass inputPanel; private PreviewClass previewPanel; private JTabbedPane tabbedPane; private Container contentPane; public MainClass() { contentPane=getContentPane(); contentPane.setLayout(new BorderLayout()); setTitle("How to Assign Value from Another Class"); setSize(FRAME_WIDTH, FRAME_HEIGHT); setLocation(FRAME_X_ORIGIN, FRAME_Y_ORIGIN); inputPanel=new InputClass(); previewPanel=new PreviewClass(); tabbedPane=new JTabbedPane(); tabbedPane.add("Input Name", inputPanel); tabbedPane.add("Preview Name", previewPanel); contentPane.add(tabbedPane, BorderLayout.CENTER); setDefaultCloseOperation(EXIT_ON_CLOSE); } public static void main(String[] args) { MainClass frame=new MainClass(); frame.setVisible(true); } }
您有任意数量的可能解决方案,都有优点和缺点。
如果我遇到这样的问题,我会很想创建一个interface
来描述可以更改的内容以及如何更改,甚至可以在interface
的内部状态更改时提供事件通知。
然后,我将创建此interface
的实例并将其传递给每个类。 那些需要从中取值的类将从中读取它们需要的值,如果可用,附加某种更改/属性侦听器,以便它们可以监视对interface
的更改。
那些需要对interface
进行更改的类将根据需要进行更改。
当它被更改时,interface
会触发更新,让任何正在收听的人知道已经进行了更改。
通过这种方式,您可以将类与每个类分离,并减少其他类的不必要暴露。
这是 MVC 范式中的"模型",描述了观察者模式
在 InputClass 中,访问父 JFrame 并获取它的预览对象并设置字符串值:
@Override
public void actionPerformed(ActionEvent event) {
// How do I change/assign a text to the PreviewClass from here?
((MainClass)SwingUtilities.getWindowAncestor(this)).getPreviewPanel().setValue(inputName.getText());
}
在 PreviewClass 中(公开用于更改文本的 setter 方法(:
public void setValue(String s){
namePreview.setText(s);
}
在 MainClass 中(公开用于访问预览面板对象的 getter 方法(:
public PreviewClass getPreviewPanel(){
return previewPanel;
}
避免将其设置为静态是对的 - 这将是一个坏主意。
此处的解决方案是在创建输入类时将对预览类的引用传递到输入类中。
输入类存储该引用,然后可以在文本字段更改时执行preview.inputRecieved(str)
创建 inputRecieved
方法,然后可以更新JLabel
和/或执行所需的任何其他处理。
请注意,这也意味着您可以更改预览窗口的显示和组织方式,而无需更改输入窗口。这种封装是一个重要的面向对象设计原则。
将 previewClass 的引用传递给 Inputclass 的构造函数以设置所需的值。
输入类
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class InputClass extends JPanel implements ActionListener{
private JTextField inputName;
private JButton inputButton;
public InputClass(final PreviewClass perviewClassObj) {
setLayout(new FlowLayout());
inputName=new JTextField(15);
inputButton=new JButton("INPUT");
inputButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
perviewClassObj.setNamePreview(inputName.getText());
}
});
add(inputName);
add(inputButton);
}
@Override
public void actionPerformed(ActionEvent event) {
// How do I change/assign a text to the PreviewClass from here?
}
}
预览类
import javax.swing.*;
import java.awt.*;
public class PreviewClass extends JPanel{
private JTextField namePreview;
/**
* @param namePreview the namePreview to set
*/
public void setNamePreview(String textContent) {
this.namePreview.setText(textContent);
}
public PreviewClass() {
setLayout(new FlowLayout());
namePreview=new JTextField(15);
namePreview.setEditable(false);
add(namePreview);
}
}
主类
import javax.swing.*;
import java.awt.*;
public class MainClass extends JFrame{
private static final int FRAME_WIDTH=250;
private static final int FRAME_HEIGHT=150;
private static final int FRAME_X_ORIGIN=400;
private static final int FRAME_Y_ORIGIN=300;
private InputClass inputPanel;
private PreviewClass previewPanel;
private JTabbedPane tabbedPane;
private Container contentPane;
public MainClass() {
contentPane=getContentPane();
contentPane.setLayout(new BorderLayout());
setTitle("How to Assign Value from Another Class");
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setLocation(FRAME_X_ORIGIN, FRAME_Y_ORIGIN);
previewPanel=new PreviewClass();
inputPanel=new InputClass(previewPanel);
tabbedPane=new JTabbedPane();
tabbedPane.add("Input Name", inputPanel);
tabbedPane.add("Preview Name", previewPanel);
contentPane.add(tabbedPane, BorderLayout.CENTER);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
MainClass frame=new MainClass();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
您可以设置InputClass
abstract
类,在实例化时重写 actionPerformed
方法,并在PreviewClass
中创建 setter :
预览类
public class PreviewClass extends JPanel{
...
public void setNamePreview(String name) {
inputName.setText(name);
}
}
输入类
public abstract class InputClass extends JPanel implements ActionListener{
private JTextField inputName;
private JButton inputButton;
public InputClass() {
setLayout(new FlowLayout());
inputName=new JTextField(15);
inputButton=new JButton("INPUT");
inputButton.addActionListener(this);
add(inputName);
add(inputButton);
}
public String getInputNameValue(){
return inputName.getText();
}
}
主类
...
previewPanel=new PreviewClass();
inputPanel=new InputClass() {
@Override
public void actionPerformed(ActionEvent event) {
previewPanel.setNamePreview(inputPanel.getInputNameValue());
}
};
...