Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我的方法被调用了,但它没有画线_Java_Swing - Fatal编程技术网

Java 我的方法被调用了,但它没有画线

Java 我的方法被调用了,但它没有画线,java,swing,Java,Swing,下面是我画一个游泳池的代码,同时计算它的体积 所讨论的方法是paintswimingpool(),当stateChanged()监听器方法调用它时,它可以正常工作。然而,问题是我想在启动程序时绘制矩形。我添加了一些控制台消息来帮助调试,它告诉我该方法是从createGUI()方法正确调用的。但是为什么paintswimingpool()不在面板上绘制任何东西呢?对不起,我花了很长时间来解决这个问题,但没有找到解决的地方 提前感谢您的指点 import java.awt.Color; import

下面是我画一个游泳池的代码,同时计算它的体积

所讨论的方法是paintswimingpool(),当stateChanged()监听器方法调用它时,它可以正常工作。然而,问题是我想在启动程序时绘制矩形。我添加了一些控制台消息来帮助调试,它告诉我该方法是从createGUI()方法正确调用的。但是为什么paintswimingpool()不在面板上绘制任何东西呢?对不起,我花了很长时间来解决这个问题,但没有找到解决的地方

提前感谢您的指点

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class SwimingPoolCalculator implements ChangeListener {

    private JFrame frame;
    private JPanel primaryJPanel, drawingJPanel;
    private JLabel deepJLabel, shallowJLabel;
    private JSlider deepJSlider, shallJSlider;
    private JTextField resultTextField;

    final private int xPos = 20;
    final private int yPos = 20;
    final private int swimmingPoolLength = 200;
    final private int swimmingPoolWidth = 50;

    public static void main(String[] args) {

        SwimingPoolCalculator swimingPoolCalculator = new SwimingPoolCalculator();

        swimingPoolCalculator.createGUI();

    }

    private void createGUI(){

        frame = new JFrame("Swiming Pool Calculator");

        primaryJPanel = new JPanel();
        primaryJPanel.setPreferredSize(new Dimension(250, 500));

        drawingJPanel = new JPanel();
        drawingJPanel.setPreferredSize(new Dimension(250, 300));
        drawingJPanel.setBackground(Color.yellow);

        shallowJLabel = new JLabel("S End");
        deepJLabel = new JLabel("D End");

        shallJSlider = new JSlider(JSlider.HORIZONTAL, 10, 100, 10);
        deepJSlider = new JSlider(JSlider.HORIZONTAL, 50, 200, 100);

        shallJSlider.addChangeListener(this);
        deepJSlider.addChangeListener(this);

        resultTextField = new JTextField(15);

        primaryJPanel.add(drawingJPanel);
        primaryJPanel.add(shallowJLabel);
        primaryJPanel.add(shallJSlider);
        primaryJPanel.add(deepJLabel);
        primaryJPanel.add(deepJSlider);
        primaryJPanel.add(resultTextField);

        frame.getContentPane().add(primaryJPanel);
        frame.pack();
        frame.setVisible(true);

        // why the first call does not draw any line?
        paintSwimmingPool(deepJSlider.getValue(), shallJSlider.getValue());

    }

    private void paintSwimmingPool(int deepEnd, int shallowEnd){

        Graphics drawingBoard = drawingJPanel.getGraphics();

        drawingBoard.setColor(Color.yellow);
        drawingBoard.fillRect(0, 0, 250, 250);
        drawingBoard.setColor(Color.black);

        drawingBoard.drawLine(xPos, yPos, xPos + swimmingPoolLength, yPos);  // the top line
        drawingBoard.drawLine(xPos, yPos, xPos, yPos + deepEnd); // the left line
        drawingBoard.drawLine(xPos + swimmingPoolLength, yPos, xPos + swimmingPoolLength, yPos + shallowEnd); // the right line
        drawingBoard.drawLine(xPos, yPos + deepEnd, xPos + swimmingPoolLength, yPos + shallowEnd); // the bottom line

    }

    private void calculateVolume(double averageDepth){

        int swimmingPoolVolume = (int)(averageDepth * swimmingPoolLength * swimmingPoolWidth);

        resultTextField.setText("Volume: " + swimmingPoolVolume);

    }

    @Override
    public void stateChanged(ChangeEvent e) {

        int shallowEnd = shallJSlider.getValue();
        int deepEnd = deepJSlider.getValue();

        double averageDepth = (shallowEnd + deepEnd) / 2;

        paintSwimmingPool(deepEnd, shallowEnd);

        calculateVolume(averageDepth);

    }

}

Swing可能是在您在JPanel上绘制后重新绘制的。Swing可以在任何时候,出于任何原因重新绘制组件。因此,您不应该使用
getGraphics

相反,您需要创建自己的组件类(扩展现有组件,例如
JPanel
),并覆盖
paintComponent


有关更多详细信息,请参阅。

您不能这样绘制,正确的方法是

  • 重写JPanel子类中的paintComponent()方法,并改用Graphics参数
  • 调用repaint()来触发重新绘制,而不是paintswimingpool()方法
  • 将参数(如deepEnd和shallowEnd)移动到字段中,并从paintComponent()方法引用这些参数-我们可以“看到”这些字段的内部类。理想情况下,这些将在一个单独的模型中,由绘图面板和控制代码共享,但是内部类完成了任务
  • 看这张照片
充分发挥作用的例子

public class SwimingPoolCalculator implements ChangeListener {

    private JFrame frame;
    private JPanel primaryJPanel, drawingJPanel;
    private JLabel deepJLabel, shallowJLabel;
    private JSlider deepJSlider, shallJSlider;
    private JTextField resultTextField;

    final private int xPos = 20;
    final private int yPos = 20;
    final private int swimmingPoolLength = 200;
    final private int swimmingPoolWidth = 50;
    private int deepEnd;   // <== moved to fields
    private int shallowEnd;  // <== moved to fields

    private class InnerDrawingPanel extends JPanel {
        @Override
        protected void paintComponent(Graphics drawingBoard) {
            drawingBoard.setColor(Color.yellow);   // <== drawing code now here
            drawingBoard.fillRect(0, 0, 250, 250);
            drawingBoard.setColor(Color.black);

            drawingBoard.drawLine(xPos, yPos, xPos + swimmingPoolLength, yPos);  // the top line
            drawingBoard.drawLine(xPos, yPos, xPos, yPos + deepEnd); // the left line
            drawingBoard.drawLine(xPos + swimmingPoolLength, yPos, xPos + swimmingPoolLength, yPos + shallowEnd); // the right line
            drawingBoard.drawLine(xPos, yPos + deepEnd, xPos + swimmingPoolLength, yPos + shallowEnd); // the bottom line
        }
    }

    public static void main(String[] args) {

        SwimingPoolCalculator swimingPoolCalculator = new SwimingPoolCalculator();

        swimingPoolCalculator.createGUI();

    }

    private void createGUI(){

        frame = new JFrame("Swiming Pool Calculator");

        primaryJPanel = new JPanel();
        primaryJPanel.setPreferredSize(new Dimension(250, 500));

        drawingJPanel = new InnerDrawingPanel();  // <== use inner class
        drawingJPanel.setPreferredSize(new Dimension(250, 300));
        drawingJPanel.setBackground(Color.yellow);

        shallowJLabel = new JLabel("S End");
        deepJLabel = new JLabel("D End");

        shallJSlider = new JSlider(JSlider.HORIZONTAL, 10, 100, 10);
        deepJSlider = new JSlider(JSlider.HORIZONTAL, 50, 200, 100);

        shallJSlider.addChangeListener(this);
        deepJSlider.addChangeListener(this);

        resultTextField = new JTextField(15);

        primaryJPanel.add(drawingJPanel);
        primaryJPanel.add(shallowJLabel);
        primaryJPanel.add(shallJSlider);
        primaryJPanel.add(deepJLabel);
        primaryJPanel.add(deepJSlider);
        primaryJPanel.add(resultTextField);

        frame.getContentPane().add(primaryJPanel);
        frame.pack();
        frame.setVisible(true);

        // why the first call does not draw any line?
        shallowEnd = deepJSlider.getValue(); // <== now update fields
        deepEnd = shallJSlider.getValue();
        drawingJPanel.repaint();        // <== trigger repaint

    }


    private void calculateVolume(double averageDepth){

        int swimmingPoolVolume = (int)(averageDepth * swimmingPoolLength * swimmingPoolWidth);

        resultTextField.setText("Volume: " + swimmingPoolVolume);

    }

    @Override
    public void stateChanged(ChangeEvent e) {

        shallowEnd = shallJSlider.getValue();  // <== update fields
        deepEnd = deepJSlider.getValue();

        double averageDepth = (shallowEnd + deepEnd) / 2;


        drawingJPanel.repaint();   // <== trigger repaint
        calculateVolume(averageDepth);

    }

}
公共类SwimingPoolCalculator实现ChangeListener{
私有JFrame;
private JPanel primaryJPanel,drawingJPanel;
私人JLabel deepJLabel,shallowJLabel;
私人JSlider deepJSlider,shallJSlider;
私有JTextField resultTextField;
最终私有int xPos=20;
最终私有int yPos=20;
最终专用游泳池长度=200;
最终私用游泳池宽度=50;

private int deepEnd;//查看和(cough)
super.paintComponent
(cough)
g.drawImage(image,0,0,null);
应该是
g.drawImage(image,0,0,this)
as
JPanel
通过
JComponent
实现
ImageObserver
接口。如果不处理您创建的
图形
上下文(
image.getGraphics();
),也可能会出现问题在某些系统上,但这是一个工作流问题。嗨@Adam,但我还有另一个问题。我设置了另一个类并尝试在其中绘制游泳池。但是,我如何将所需的参数(如xPos、YPO)传递给paintComponent(图形g)?我无法使用您上面显示的技术进行计算。您能更具体一点吗?谢谢。我重新修改了我的答案,以向您展示如何使用参数,即不使用参数,而是使用共享状态。理想情况下,这些将在一个由绘图面板和控制代码共享的正式模型中,但我使用的内部类是g完成这项工作。