Java JFrame、JPanel、JButton和继承
因此,我创建了一个Java JFrame、JPanel、JButton和继承,java,swing,jframe,jbutton,jlabel,Java,Swing,Jframe,Jbutton,Jlabel,因此,我创建了一个JFrame类和一个JPanel类(这非常复杂,因为这个面板中有一些按钮)。在这个JFrame类中,我必须创建一个JPanel类的数组,所以它是这样的 public class frame extends JFrame { //SOME VARIABLES AND METHODS HERE int lines; public frame() { //SOME CODE HERE panelWithButton[]
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
错误如下:无法从静态上下文引用非静态变量行。
请帮帮我。对不起,我的英语不好,如果我的问题不够清楚,就问吧。提前感谢。:) “错误如下:
无法从静态上下文引用非静态变量行
”
出现此错误是因为您试图以静态方式访问行
,当行
不是静态
变量时,它是一个实例变量。所以,您要做的是获取对该实例变量的引用
一种方法是通过构造函数注入将帧
引用传递到panelWithButton
,然后您可以访问实例字段行
。差不多
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
,它可以访问实例成员,如方法设置行
。为了不违反封装规则,我将私有字段与setter
一起使用
不过,对于这种常见的情况,有更好的解决方案。这只是一个简单的修复(bu带孔)。此方法不必要地公开帧
类。在这种特殊情况下,我要做的是使用某种类型的。一个更简单的解决方案是使用接口
作为中间人,并让框架
实现它(例如,因为您只想操作数据,所以MVC设计是最好的方法)
旁注
- 使用Java命名约定。类名以大写字母开头
更新 下面是一个简单的MVC(模型、视图、控制器)设计示例,使用了您的一些编程思想。我将带您了解它 Model
LinesModel
类。唯一的属性是has是一个int-lines
。它有一个setLines
方法。该方法的特殊之处在于它触发一个属性更改事件,因此每当调用该方法时,都可以更改视图
public void setLines(int value) {
int oldValue = lines;
lines = value;
propertySupport.firePropertyChange(LINES_PROPERTY, oldValue, lines);
}
控制器带有按钮的面板
类。然后按下按钮,调用LinesModel
的设置行
方法,该方法触发属性更改并通知感兴趣的侦听器
fiveLines.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
lineModel.setLines(4);
}
});
视图绘制面板
类。它基本上从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;
}
}
@覆盖
受保护组件(图形g){
超级组件(g);
int y=50;
对于(int i=0;i
这是完整的运行程序。您可以运行它并尝试了解发生了什么
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);
}
}
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.beans.PropertyChangeEvent;
导入java.beans.PropertyChangeListener;
导入java.beans.PropertyChangeSupport;
导入java.io.Serializable;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
公共类框架扩展了JFrame{
私有线模型线模型;
私人画板;
带按钮的专用面板带按钮的面板;
公共框架(){
lineModel=新的LinesModel();
paintPanel=新的paintPanel();
panelWithButtons=新的panelWithButtons(线型);
lineModel.addPropertyChangeListener(新的PropertyChangeListener(){
@凌驾
公共作废属性更改(属性更改事件evt){
String prop=evt.getPropertyName();
if(LinesModel.LINES_属性等于(prop)){
paintPanel.repaint();
}
}
});
添加(油漆面板);
添加(带按钮的面板,边框布局。南);
setTitle(“MVC示例”);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(空);
包装();
setVisible(真);
}
公共类PaintPanel扩展了JPanel{
@凌驾
受保护组件(图形g){
超级组件(g);
int y=50;
对于(int i=0;i