从另一个类调用时 Java 重绘方法不起作用

标签 java swing methods repaint

我使用 Netbeans 编写 Java 代码已有大约一年的时间,并且编写了大量在屏幕上绘制图表的数据操作代码。我通常在主窗口中放置一个 JPanel 对象,编写自定义绘画代码,并根据需要调用 repaint() 方法。

但是今天,我第一次尝试从包含面板的类(对象)之外的类(对象)调用面板上的重绘。尽管编译器没有发现任何问题,并且在 Debug模式下,它正确地单步执行到对重绘的外部调用,但实际上没有发生重绘,并且代码实际上并没有单步执行到重绘方法。

我编写了一个极简程序来演示该问题,如下所示(省略了 Main,因为它只包含设置两个屏幕面板的代码。)

--- 类的描述,首先包含绘图表面,其他重绘调用 ---

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

public class Panel1 extends JComponent
{
   GraphPnl graphPnl;
   boolean colorFlag;

   public Panel1()
   {
     setLayout(null);
     colorFlag = true;

     graphPnl = new GraphPnl();
     graphPnl.setBounds(10, 10, 110, 110);
     graphPnl.setBackground(Color.black);
     add(graphPnl);

}//Panel1()

public class GraphPnl extends JPanel
{
  //just draws a line segment, toggling color

  @Override
  public void paint(Graphics g)
  {
      super.paint(g);
      Graphics2D g2 = (Graphics2D) g;
  g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);

      if (colorFlag) {g2.setColor(Color.red);} else {g2.setColor(Color.green);}
      g2.drawLine(10, 10, 50, 50);
   }//paint
 }//GraphPnl
}//Panel1

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

public class Panel2 extends JComponent
{
   JButton testBtn;
   TestAction testAction;
   Panel1 p1;

   public Panel2()
   {
      p1 = new Panel1();
      testBtn = new JButton("Click");
      testBtn.setBounds(10, 10, 80, 30);
      add(testBtn);
      testAction = new TestAction();
      testBtn.addActionListener(testAction);
   }//Panel2()


   public class TestAction implements ActionListener
   {
     public void actionPerformed(ActionEvent evt)
     {
       p1.colorFlag = ! p1.colorFlag;
       p1.graphPnl.repaint();
     }
   }//TestAction
}//Panel2

如果有人对此有任何见解,或者知道解决方法,我会很高兴听到 来自你。

预先感谢您提供任何见解。

约翰·多纳

最佳答案

Main is ommitted, since it only contains code to set up the two on-screen panels.)

嗯,根据定义,当你遇到问题时,你不知道哪些代码是相关的,哪些不是相关的,直到问题得到解决。如此完整的SSCCE应该发布。

作为一个疯狂的猜测,我会说你的组件的大小为 0,所以没有什么可绘制的。

I generally plant a JPanel object in my main window, write custom painting code, and call the repaint() method as needed

您可能很幸运,因为您将面板添加到了 BorderLayout 的中心,它会自动为面板提供框架的所有可用空间。

trashgod 的示例展示了设置自定义组件的首选大小的一种方法。另一种方法是重写 getPreferredSize() 方法以返回正确的值。

你真的应该学习如何使用布局管理器而不是使用空布局,这样你将来就会避免类似的问题。除非您有拖放类型的应用程序,否则无需使用空布局。

关于从另一个类调用时 Java 重绘方法不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4282159/

相关文章:

java - 无法从 String 反序列化 java.time.LocalDateTime 类型的值

java - 在非事件调度线程中调用 fireTableRowsUpdated() 是否安全?

Java-从数组方法返回一个数组到Main函数

java - 从被调用的方法中捕获异常

python - 我可以替换 Python 中对象的现有方法吗?

java - 使用第 1、2 或 3 步计算到达第 4 个楼梯的方式

java - 如何用Java从数据库中检索每一行和每一列的数据

java - 使用 kubernetes -conf 文件/环境变量部署 java 应用程序

java - JPanel 没有出现在使用 BorderLayout 的 JFrame 中

Java 包不调整大小