所以,我创建了一个JFrame
类和一个JPanel
类(由于此面板中有一些按钮,因此非常复杂)。在这个JFrame
类中,我必须创建一个JPanel
类的数组,所以它就像这样
public class frame extends JFrame
{
//SOME VARIABLES AND METHODS HERE
int lines;
public frame()
{
//SOME CODE HERE
panelWithButton[] pwb = new panelWithButton[5];
//SOME CODE HERE
}
}
问题是,此JPanel
中的按钮对于每个按钮都有不同的ActionListeners
,它应该更改JFrame
类中的变量
public class panelWithButton extends JPanel
{
//SOME VARIABLES AND METHOD
Jbutton aButton = new JButton();
Jbutton bButton = new JButton();
Jbutton cButton = new JButton();
public button()
{
//SOME CODE HERE
add(aButton);
aButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
frame.lines = 4;
}
});
add(bButton);
aButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
frame.lines = 5;
}
});
add(cButton);
aButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
frame.lines = 6;
}
});
//SOME CODE HERE
}
}
所以,那就是它。每个按钮将以不同方式更改框架的变量。但它不起作用。我认为问题在于此代码,但我不知道应该将其更改为:
frame.lines
以下是错误:non-static variable lines cannot be referenced from a static context.
请帮我。抱歉我的英语不好,如果我的问题不够明确,请问。提前致谢。 :)
答案 0 :(得分:2)
“这是错误:
non-static variable lines cannot be referenced from a static context
。”
您收到此错误是因为您尝试以静态方式访问lines
,当lines
不是static
变量时,它是一个实例变量。那么你想要做的是获得对该实例变量的引用。
一种方法是通过构造函数注入将frame
引用传递给panelWithButton
,然后您可以访问实例字段lines
。像
public class frame extends JFrame {
private int lines; // private for encapsulation. getter/setter below
...
panelWithButton panel = new panelWithButton(frame.this);
...
public void setLines(int lines) {
this.lines = lines;
}
}
public class panelWithButton extends JPanel {
private frame f;
public panelWithButton(final frame f) {
this.f = f;
}
public void button() {
...
public void actionPerformed(ActionEvent e) {
f.setLines(5);
}
}
}
通过将frame
的同一实例传递给panelWithButton
,它可以访问实例成员,例如方法setLines
。我使用setter
的私有字段来打破封装规则。
但这种常见情况有更好的解决方案。这个只是一个简单的修复(带孔)。此方法不必要地公开frame
类。在这种特殊情况下我会做的是使用某种MVC architecture。一个更简单的解决方案是使用interface
作为中间人并让frame
实现它(例如here,但由于您只想操作数据,因此MVC设计是最佳方法。
附注
<强>更新强>
这是一个简单的MVC(模型,视图,控制器)设计的示例,使用您的一些程序想法。我会引导你完成它。
模型 LinesModel
课程。唯一的属性是int lines
。它有一个setLines
方法。关于此方法的特殊之处在于它会触发属性更改事件,因此无论何时调用该方法,都可以更改视图
public void setLines(int value) {
int oldValue = lines;
lines = value;
propertySupport.firePropertyChange(LINES_PROPERTY, oldValue, lines);
}
控制器 PanelWithButtons
课程。然后按下按钮,调用setLines
的{{1}}方法,激活属性更改并通知感兴趣的听众。
LinesModel
查看 fiveLines.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
lineModel.setLines(4);
}
});
课程。它基本上取PaintPanel
的行数并绘制该行数。
LinesModel
这是完整的运行程序。您可以浏览它并尝试了解正在发生的事情。
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int y = 50;
for (int i = 0; i < lineModel.getLines(); i++) {
g.drawLine(50, y, 200, y);
y += 20;
}
}