[英]JFrame, JPanel, JButton, and Inheritance
So, I made a JFrame
class and a JPanel
class (which is pretty complicated beacuse there are some buttons in this panel). 因此,我制作了一个
JFrame
类和一个JPanel
类(这很复杂,因为此面板中有一些按钮)。 In this JFrame
class, I have to make an array of the JPanel
class, so it goes like this 在这个
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
}
}
And the problem is, the buttons in this JPanel
have different ActionListeners
for each button where it should change the variables in that JFrame
class 问题是,此
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
}
}
So, that's it. 就是这样了。 Each button will change the variable of the frame differently.
每个按钮将不同地更改框架的变量。 But it's not working.
但这不起作用。 I think the problem is with this code, but I don't know what should I change it to:
我认为问题出在此代码上,但是我不知道应该将其更改为什么:
frame.lines
Here is the error: non-static variable lines cannot be referenced from a static context.
这是错误:
non-static variable lines cannot be referenced from a static context.
Please help me. 请帮我。 Sorry for my broken English and if my question is not clear enough, just ask.
对不起,我的英语不好,如果我的问题不清楚,请问。 Thanks in advance.
提前致谢。 :)
:)
"Here is the error:
non-static variable lines cannot be referenced from a static context
."“这里是错误:
non-static variable lines cannot be referenced from a static context
。”
You're getting this error because you're trying to access the lines
in a static way, when lines
isn't a static
variable, it's an instance variable. 之所以出现此错误,是因为您试图以静态方式访问
lines
,而当lines
不是static
变量时,它是一个实例变量。 So what to you want to do is get a reference to that instance variable. 因此,您要做的就是获取对该实例变量的引用。
One way is to pass the frame
reference to the panelWithButton
through constructor injection, then you can access the instance field lines
. 一种方法是通过构造函数注入将
frame
引用传递给panelWithButton
,然后可以访问实例字段lines
。 Something like 就像是
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);
}
}
}
By passing the same instance of frame
to panelWithButton
, it's able to access the instance members, like the method setLines
. 通过将相同的
frame
实例传递给panelWithButton
,它可以访问实例成员,如setLines
方法。 I used the private field with the setter
as to not break the rules of encapsulation. 我将私有字段与
setter
是为了不破坏封装规则。
There are better solutions to this common scenario though. 但是,对于这种常见情况有更好的解决方案。 This one is just one simple fix (bu with holes).
这只是一个简单的解决方法(带有孔)。 This method exposes the
frame
class unnecesarily. 此方法不必要地公开了
frame
类。 What I would do in this particular situation is use some sort of MVC architecture . 在这种特殊情况下,我将使用某种MVC体系结构 。 An easier solution would be to use an
interface
as a middleman and have the frame
implement it (example here , but since all you want to do is manipulate data, the MVC design is the best approach. 一个简单的解决方案是使用一个
interface
作为中间人并让frame
实现它( 这里是示例,但是由于您要做的只是操纵数据,因此MVC设计是最好的方法。
Side Notes 旁注
UPDATE UPDATE
Here's an example of a simple MVC (Model, View, Controller) design, using some of your program ideas. 这是一个使用一些程序思想的简单MVC(模型,视图,控制器)设计的示例。 I'll walk you through it.
我会引导您完成。
Model LinesModel
class. 模型
LinesModel
类。 The only property is has is an int lines
. 唯一的属性是具有
int lines
。 It has a setLines
method. 它具有
setLines
方法。 The special thing about this method is that it fires a property change event so when ever the method is called, the view can be changed 此方法的特殊之处在于它会触发属性更改事件,因此,无论何时调用该方法,都可以更改视图
public void setLines(int value) {
int oldValue = lines;
lines = value;
propertySupport.firePropertyChange(LINES_PROPERTY, oldValue, lines);
}
Controller PanelWithButtons
class. 控制器
PanelWithButtons
类。 Then button , when pressed, calls the setLines
method of the LinesModel
, which fires the property change and notifies the interested listener. 然后按钮,按下时,调用
setLines
的方法LinesModel
,它将触发属性变化,并通知感兴趣的听众。
fiveLines.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
lineModel.setLines(4);
}
});
View PaintPanel
class. 查看
PaintPanel
类。 It basically takes the number of lines from the LinesModel
and paints that number of lines. 它基本上从
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;
}
}
Here's the complete running program. 这是完整的运行程序。 You can run through it and try and learn what's going on.
您可以运行它并尝试了解发生了什么。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Frame extends JFrame {
private LinesModel lineModel;
private PaintPanel paintPanel;
private PanelWithButtons panelWithButtons;
public Frame() {
lineModel = new LinesModel();
paintPanel = new PaintPanel();
panelWithButtons = new PanelWithButtons(lineModel);
lineModel.addPropertyChangeListener(new PropertyChangeListener(){
@Override
public void propertyChange(PropertyChangeEvent evt) {
String prop = evt.getPropertyName();
if (LinesModel.LINES_PROPERTY.equals(prop)) {
paintPanel.repaint();
}
}
});
add(paintPanel);
add(panelWithButtons, BorderLayout.SOUTH);
setTitle("MVC Example");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
pack();
setVisible(true);
}
public class PaintPanel extends JPanel {
@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;
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new Frame();
}
});
}
}
class PanelWithButtons extends JPanel {
private final JButton fourLines = new JButton("FOUR");
private final JButton fiveLines = new JButton("FIVE");
private LinesModel lineModel;
public PanelWithButtons(LinesModel lineModel) {
this.lineModel = lineModel;
fiveLines.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
PanelWithButtons.this.lineModel.setLines(4);
}
});
fourLines.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
PanelWithButtons.this.lineModel.setLines(5);
}
});
add(fourLines);
add(fiveLines);
}
}
class LinesModel implements Serializable {
public static final String LINES_PROPERTY = "linesProperty";
private int lines;
private PropertyChangeSupport propertySupport;
public LinesModel() {
propertySupport = new PropertyChangeSupport(this);
}
public int getLines() {
return lines;
}
public void setLines(int value) {
int oldValue = lines;
lines = value;
propertySupport.firePropertyChange(LINES_PROPERTY, oldValue, lines);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertySupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertySupport.removePropertyChangeListener(listener);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.