java - 从另一个类访问变量的最佳方法?
问题描述
我需要从另一个类访问变量,我已经使用下面描述的 2 种不同方法完成了它。
我的问题是两者中哪一个更可取,为什么因为两者都工作得很好 - 或者还有其他更好的方法吗?我也使用内部类完成了它,但是当代码行数变得越来越大时,这很不方便。
在以下测试代码中,带注释的星号表示不同的文件:
import java.awt.EventQueue;
import javax.swing.JFrame;
public class Test {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MainFrame f = new MainFrame("Testing",50,50);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}
//**********************************************************************
import java.awt.BorderLayout;
import javax.swing.JFrame;
public class MainFrame extends JFrame {
public MainFrame(String title,int x,int y) {
setTitle(title);
this.setLocation(x, y);
UpperPanel pUp=new UpperPanel();
add(pUp, BorderLayout.NORTH);
LowerPanel pLow=new LowerPanel();
add(pLow, BorderLayout.SOUTH);
pack();
}
}
现在正如您在下面看到的,UpperPanel 必须从 LowerPanel 访问 JButton,而 LowerPanel 必须从 UpperPanel 访问菜单。出于这个原因,我可以将 pUp 作为参数传递给 LowerPanel 构造函数,但我不能将 pLow 作为参数传递给 UpperPanel,因为它尚未创建。
因此,我使用了 2 种方法,一种声明相关类的实例,另一种使用静态变量。上面的前两个类在每种方法中都是相同的。
以下是第一种情况下的面板代码:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JPanel;
public class LowerPanel extends JPanel implements ActionListener {
static JButton butEnableMenu;
static JButton butEnableBut1;
public LowerPanel() {
setLayout(new FlowLayout(FlowLayout.LEFT));
butEnableMenu=new JButton("Enable menu");
butEnableMenu.setEnabled(true);
butEnableMenu.addActionListener(this);
add(butEnableMenu);
butEnableBut1=new JButton("Enable first button");
butEnableBut1.setEnabled(false);
butEnableBut1.addActionListener(this);
add(butEnableBut1);
}
public void actionPerformed(ActionEvent e) {
UpperPanel up = null;
Object clicked=e.getSource();
JMenu mnu=up.myMenuBar.getMenu(0);
if(clicked.equals(butEnableMenu)) {
mnu.setEnabled(true);
butEnableMenu.setEnabled(false);
}
else if(clicked.equals(butEnableBut1)) {
butEnableMenu.setEnabled(true);
butEnableBut1.setEnabled(false);
}
}
}
//**********************************************************************
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
public class UpperPanel extends JPanel {
static JMenuBar myMenuBar;
public UpperPanel() {
setLayout(new FlowLayout(FlowLayout.LEFT));
myMenuBar=new JMenuBar();
JMenu but2=new JMenu("2nd button");
JMenuItem enableBut2=new JMenuItem("Enable");
but2.setEnabled(false);
enableBut2.addActionListener(new menuActionListener());
myMenuBar.add(but2);
but2.add(enableBut2);
add(myMenuBar);
}
}
class menuActionListener implements ActionListener {
static String clickedMenuItem=null;
LowerPanel lp;
public void actionPerformed(ActionEvent e) {
clickedMenuItem=e.getActionCommand();
JMenuItem mnuItm=(JMenuItem)e.getSource();
JPopupMenu pmen = (JPopupMenu)mnuItm.getParent();
JMenu pmnu =(JMenu)pmen.getInvoker();
if(clickedMenuItem.equals("Enable")) {
pmnu.setEnabled(false);
lp.butEnableBut1.setEnabled(true);
}
}
}
这些是第二种情况下的面板:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
public class UpperPanel extends JPanel {
static JMenuBar myMenuBar;
public UpperPanel() {
setLayout(new FlowLayout(FlowLayout.LEFT));
myMenuBar=new JMenuBar();
JMenu but2=new JMenu("2nd button");
JMenuItem enableBut2=new JMenuItem("Enable");
but2.setEnabled(false);
enableBut2.addActionListener(new menuActionListener());
myMenuBar.add(but2);
but2.add(enableBut2);
add(myMenuBar);
}
}
class menuActionListener implements ActionListener {
static String clickedMenuItem=null;
public void actionPerformed(ActionEvent e) {
clickedMenuItem=e.getActionCommand();
JMenuItem mnuItm=(JMenuItem)e.getSource();
JPopupMenu jpm = (JPopupMenu)mnuItm.getParent();
JMenu pmnu =(JMenu)jpm.getInvoker();
if(clickedMenuItem.equals("Enable")) {
pmnu.setEnabled(false);
LowerPanel.butEnableBut1.setEnabled(true);
}
}
}
//**********************************************************************
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JPanel;
public class LowerPanel extends JPanel implements ActionListener {
static JButton butEnableMenu;
static JButton butEnableBut1;
public LowerPanel() {
setLayout(new FlowLayout(FlowLayout.LEFT));
butEnableMenu=new JButton("Enable menu");
butEnableMenu.setEnabled(true);
butEnableMenu.addActionListener(this);
add(butEnableMenu);
butEnableBut1=new JButton("Enable first button");
butEnableBut1.setEnabled(false);
butEnableBut1.addActionListener(this);
add(butEnableBut1);
}
public void actionPerformed(ActionEvent e) {
Object clicked=e.getSource();
JMenu mnu=UpperPanel.myMenuBar.getMenu(0);
if(clicked.equals(butEnableMenu)) {
mnu.setEnabled(true);
butEnableMenu.setEnabled(false);
}
else if(clicked.equals(butEnableBut1)) {
butEnableMenu.setEnabled(true);
butEnableBut1.setEnabled(false);
}
}
}
解决方案
一般来说,有两种方法可以从另一个类访问变量:
- 您创建该类的对象。然后这个对象具有分配给它的该类范围内的所有变量。例如:
Test t = new Test();
t.name = "test";
- 您还可以创建静态变量。然后将变量分配给类而不是该类的对象。这样你就不需要创建一个对象,但是类的所有实例都将共享同一个变量。
//In the scope of the class
static String name;
-------------------------
//when classing the class
Test.name = "The Name of the Test";
如果你不想每次都创建一个类的新实例,并且总是使用同一个实例,你可以创建一个单例对象。您编写一个获取对象的 getter 方法。它看起来像这样:
public class Test {
Test t;
public static void main(String[] args) {
t = new Test();
}
public Test getTest() {
if (t != null) {
return t;
} else {
t = new Test();
return t;
}
}
}
我看到您使用 JFrame。然后你可能想把它变成一个单例。否则每次调用 JFrame 时都会打开一个新实例,不推荐这样做。这回答了你的问题了吗?
推荐阅读
- delphi - Delphi中的划分混乱
- elasticsearch - 是否可以在运行时更改 ElasticSearch 设置?
- angular - 将 Spring Boot - Angular 2 应用程序升级到 Angular 8 给出空白屏幕
- javascript - iOS Safari:使用深度链接,安装应用程序时如何防止打开应用程序商店?
- python - 提高代码性能并摆脱循环
- c# - 数据不会在所有绑定上更新
- javascript - 有没有办法在反应传单的标记上添加徽章?
- tcl - “package require”命令在 TCL 线程中不起作用
- mongodb - 如何在mongo嵌套数组中进行“replace into”操作?
- elasticsearch - Kibana 和 elasticsearch 状态处于活动状态,我可以通过浏览器访问 elasticsearch,但 kibana 出现错误