当前位置: 首页 > 知识库问答 >
问题:

PaintComponent()绘制图形,但即使在调用repaint()时也不使用更新的值

上官和韵
2023-03-14

这里我的程序旨在创建一个GUI,允许用户通过在JPanel上单击和释放鼠标来绘制图形。其他选项包括更改颜色和是否填充形状。一旦绘制了形状,其他选项应该使用任何新的修饰符重新绘制相同的形状。例如,如果我画一个红色矩形,如果我选择蓝色,矩形应该只是改变颜色。到目前为止,我只实现了“矩形”选项。

public class WardA4 extends JFrame implements ActionListener{
     private String[] chooseShapeOptions = {"Rectangle", "Square", "Oval", "Circle", "Line",
                                "Rounded Rectangle", "3D Rectangle"};
     private JCheckBox chooseFill;
     private JComboBox chooseShape;
     private JButton chooseColor;
     private JPanel userInterface, displayPanel;
     private JLabel chooseFillLabel, chooseColorLabel;
     private Color color = Color.WHITE;
     private int shapeIndex = 0;
     private double xStart = 100, yStart = 100, xEnd = 200, yEnd = 200;
     private boolean isFilled;

public WardA4(){
    super("Sandbox");
    chooseShape = new JComboBox(chooseShapeOptions);
    chooseFill  = new JCheckBox();
    chooseColor = new JButton();
    chooseFillLabel = new JLabel("Fill");
    chooseColorLabel = new JLabel ("Color");

    userInterface = new JPanel(new FlowLayout());
    userInterface.add(chooseShape);
    userInterface.add(chooseFillLabel);
    userInterface.add(chooseFill);
    userInterface.add(chooseColorLabel);
    userInterface.add(chooseColor);

    displayPanel = new JPanel(){        
        public void paintComponent (Graphics g){
            super.paintComponent(g);
            System.out.println("Entering paint component");
            System.out.println("starting coordinates are (" + xStart + "," + yStart + ")\n width is " + (int)Math.abs(xStart-xEnd) + "\n height is " + (int)Math.abs(yStart-yEnd));
            g.setColor(color);
            //System.out.println("" + (int)xStart + " " + (int)yStart + " " + (int)Math.abs(xStart-xEnd) + " " + (int)Math.abs(yStart-yEnd));
            switch(shapeIndex){
                case 0:
                    if(isFilled){
                        System.out.println("Entering is filled");
                        g.fillRect((int)xStart, (int)yStart, (int)Math.abs(xStart-xEnd), (int)Math.abs(yStart-yEnd));
                        //g.fillRect(100,100,100,100);
                    }
                    else{
                        System.out.println("Entering is not filled");
                        g.drawRect((int)xStart, (int)yStart, (int)Math.abs(xStart-xEnd), (int)Math.abs(yStart-yEnd));
                        //g.drawRect(100,100,100,100);
                    }
                    break;
                case 1:
                    break;
                case 2:
                    break;
                case 3:
                    break;
                case 4:
                    break;
                case 5:
                    break;
                case 6:
                    break;
            }
        }
    };

    displayPanel.setBackground(Color.BLACK);

    add(displayPanel, BorderLayout.CENTER);
    add(userInterface, BorderLayout.SOUTH);

    chooseShape.addActionListener(this);
    chooseFill.addActionListener(this);
    chooseColor.addActionListener(this);

    displayPanel.addMouseListener(new MouseAdapter(){
        public void mousePressed (MouseEvent me){
            System.out.println("Entering mouse pressed");
            xStart = MouseInfo.getPointerInfo().getLocation().getX();
            yStart = MouseInfo.getPointerInfo().getLocation().getY();
            System.out.println("mouse pressed at (" + xStart + "," + yStart + ")");
        }
        public void mouseReleased (MouseEvent me){
            System.out.println("Entering mouse released");
            xEnd = MouseInfo.getPointerInfo().getLocation().getX();
            yEnd = MouseInfo.getPointerInfo().getLocation().getY();
            System.out.println("mouse released at (" + xEnd + "," + yEnd + ")");
            repaint();
        }
    });
}

public void actionPerformed(ActionEvent e){
    if (e.getSource() == chooseShape){
        shapeIndex = chooseShape.getSelectedIndex();
    }
    else if (e.getSource() == chooseFill){
        isFilled = chooseFill.isSelected();
    }
    else if (e.getSource() == chooseColor){
        color = JColorChooser.showDialog(null, "Choose color", color);
        if (color == null)
            color = Color.WHITE;
    }
    repaint();
}

public static void main(String[] args) {
    WardA4 frame = new WardA4();
    frame.setSize(400,300);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
}
Entering paint component
starting coordinates are (100.0,100.0)
 width is 100
 height is 100
Entering is not filled
Entering paint component
starting coordinates are (100.0,100.0)
 width is 100
 height is 100
Entering is not filled

Entering mouse pressed
mouse pressed at (906.0,449.0)
Entering mouse released
mouse released at (1092.0,612.0)
Entering paint component
starting coordinates are (906.0,449.0)
 width is 186
 height is 163
Entering is not filled

Entering mouse pressed
mouse pressed at (1092.0,612.0)
Entering mouse released
mouse released at (1092.0,612.0)
Entering paint component
starting coordinates are (1092.0,612.0)
 width is 0
 height is 0
Entering is not filled

共有1个答案

荀靖
2023-03-14

被查询的事件是错误的(使用错误的坐标)。例如。

xStart = MouseInfo.getPointerInfo().getLocation().getX(); // gets location ON SCREEN
yStart = MouseInfo.getPointerInfo().getLocation().getY();

应该是:

xStart = me.getX(); // gets location relative TO PANEL
yStart = me.getY();
 类似资料:
  • 我已经花了几天时间试图让Graphics2D类在我的代码中工作。我把它的结构化为这样一种方式,即当注册了一个单击事件时,调用reaint()就完成了,但是当它到达调用repaint()的阶段时,这只会产生一个空指针异常。 调试时,这一切都在按预期工作,而不是从油漆组件方法中调用,但是当试图使用油漆组件和reaint()正确调用代码以允许Graphics2D类显示每个点的行时,它不起作用。 我已经包

  • 在试图制作一个非常简单的子弹地狱游戏来学习java时,我遇到了一个障碍: repaint()没有调用油漆组件()。 这是整个程序,目前只需将我每秒创建50次的图像绘制到JFrame上的JPanel上。 在使用断点和println方法进行了一些调试之后,我可以确认正在读取正确的图像,gameTimerAction中的计时器每秒被调用50次,并且repaint()根本没有调用paintComponen

  • 对于我的程序,我目前希望使用open按钮打开JFileChooser并选择一个图像,然后在applet左侧的JPanel上绘制它,我知道该文件正在被检索,但当我重新绘制图形上下文时,什么也没有发生。提前谢了。

  • 首先,请不要因为创建一个问题而将我置于火刑柱上,而其他具有类似名称和内容的人却存在。我把它们都看了一遍,但没有找到解决办法。 调用repaint()绝对不会调用paintComponent(),不管我似乎尝试了什么。下面是与问题相关的所有代码: 按照预期,“创建的级别面板和设置的内容窗格”被打印到控制台。 从不打印“油漆组件级油漆”。“计时器重新绘制”每2秒打印一次,正如预期的那样。

  • 我想做一个象棋游戏,我想在游戏循环中的一个jFrame上调用方法。这个特殊的JFrame显示了每个玩家的总击杀数。我很确定确实调用了repaint(),但由于某种原因,它似乎没有正确更新我的jlabel,jlabel应该保存每个玩家的击杀数值。 这是我为自定义JFrame扩展类编写的代码,该类包含代表kill的JLabel。 然后我只是在不同类的main方法中调用这个框架的repaint(): 非

  • 我正在遵循我上一篇关于绘画的帖子中的建议,即Oracle Swing教程。现在我对何时以及如何调用paintComponent()方法感到困惑。 下面是课程: 教程说,两种重绘方法都是重绘以前的鼠标位置以及新的鼠标位置。我明白,但是paintComponent从何而来?当我们说重绘时,它被调用了吗?如果是这样,为什么不在前面的位置也画一个矩形呢?