将变量与paintComponent一起使用

Mas*_*240 1 java swing paintcomponent

对于家庭作业,我试图paintComponent使用用户输入的变量绘制一个框.我已经能够使用固定数字构建我需要做的事情.我整天都在研究这个问题,但却找不到实现变量的方法.这是我正在研究的精简版:

import javax.swing.*;
import java.awt.*;

public class Problem3 extends JFrame{

  public static void main(String[] args) {  
    int xCoord = Integer.parseInt(
            JOptionPane.showInputDialog("Enter an X cord."));

    JFrame gd = new JFrame();
    gd.setLocationRelativeTo(null);
    gd.setSize(300, 300);
    gd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    gd.setVisible(true);

    gd.add(new NewPanel());   
  }

  public int getX(){
    return xCoord;
  }
}

class NewPanel extends JPanel {

  int xCoord = getX();

  protected void paintComponent(Graphics g){
    super.paintComponent(g);

    g.drawRect(10,10,xCoord,50);
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑

自从发布在这里以来,我尝试在NewPanel类中使用setter方法

public void setX() {
    xCoord = Integer.parseInt(
            JOptionPane.showInputDialog("Enter an X cord."));
}
Run Code Online (Sandbox Code Playgroud)

运行这导致一个我从未见过的奇怪错误:我得到一个StackOverFlow错误然后对话框弹出多次/数百次并且不会停止弹出.

编辑3使用气垫船完整的鳗鱼解决方案,我让它工作!感谢Full Of Eels的时间,帮助和耐心.

public class Problem3 extends JFrame{
    public static void main(String[] args) {  

        JFrame gd = new JFrame();
        gd.setLocationRelativeTo(null);
        gd.setSize(300, 300);
        gd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        gd.setVisible(true);

        NewPanel panel = new NewPanel();

        panel.setX(50); 
        gd.add(panel);
    } 
}
class NewPanel extends JPanel {

    int xCoord;

    public void setX(int x){
        xCoord = x;
    }

    public int getX(){
        return xCoord;
    }

    protected void paintComponent(Graphics g){
        super.paintComponent(g);

        g.drawRect(10,10,xCoord,50);
    }

}
Run Code Online (Sandbox Code Playgroud)

Hov*_*els 6

就像更基本的Java类一样,您经常使用mutator和accessor方法(也称为setter和getter)来更改对象的状态.在您的情况下,您需要为NewPanel类提供一个setter方法,public void setXCoor(int x) {...}如果需要,可能为yCoord提供类似的方法,以便外部类(包含NewPanel对象的GUI)可以更改NewPanel的值.一旦更改了xCoord,您将需要在同一个NewPanel对象上调用repaint(),以便JVM可以调用其paintComponent方法来显示更改的xCoord值的效果.

编辑1
还有一个问题:为什么你的Problem3类扩展了JFrame?这似乎没必要.

编辑2
此外,我不会在主方法中执行此代码:

int xCoord = Integer.parseInt(
        JOptionPane.showInputDialog("Enter an X cord."));

JFrame gd = new JFrame();
gd.setLocationRelativeTo(null);
gd.setSize(300, 300);
gd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gd.setVisible(true);

gd.add(new NewPanel()); 
Run Code Online (Sandbox Code Playgroud)

而是在一个完整阶级的构造函数中.

另外,我给该类一个NewPanel类字段,并且我将该字段持有的对象放入JFrame,允许我引用NewPanel对象,这样我就可以在类的其他地方调用它的方法.

编辑3
关于此代码:

public void setX() {
    xCoord = Integer.parseInt(
            JOptionPane.showInputDialog("Enter an X cord."));
}
Run Code Online (Sandbox Code Playgroud)

我不会在绘图类中进行用户输入.相反,我将setter方法设置为一个真正的 setter方法,类似于我确定你之前已经多次使用这种方法:

public void setX(int xCoord) {
   // set your field in here like you always do
}
Run Code Online (Sandbox Code Playgroud)

然后进行用户交互,无论是JOptionPane还是主GUI或程序中的其他任何内容.一旦用户提供了他的输入,然后在NewPanel变量上调用上面的setter方法,传递用户的输入(当然是int).

编辑4

关于这段代码:

public static void main(String[] args) {
    // ....
    gd.add(new NewPanel());   

    NewPanel.setX(50); 
}
Run Code Online (Sandbox Code Playgroud)

您在NewPanel类上调用setX方法,而不是在NewPanel对象上调用setX方法,这就是编译器正在抱怨的原因.这就是为什么我在上面的一个编辑中建议在GUI类中创建一个NewPanel变量,在GUI类的构造函数中创建GUI,而不是在main方法(主要应该调用GUI类的构造函数)中创建GUI,并使用将相同的NewPanel变量放入GUI的JFrame并调用setX(...)方法.