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