【问题标题】:repaint does not seem to call paintComponentrepaint 似乎没有调用paintComponent
【发布时间】:2015-11-18 05:54:12
【问题描述】:

我正在尝试使用单选按钮模拟交通信号灯。无论我在哪里调用repaint(),它似乎都没有调用paintComponent 方法。任何帮助,将不胜感激。这是我的代码。对不起,如果这有点长。

package trafficlight;

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

public class Frame extends JFrame{
   Drawing ob = new Drawing();
   private JPanel buttonPanel;
   private JRadioButton red;
   private JRadioButton yellow;
   private JRadioButton green;

   public Frame(String title, int width, int height) {
        super(title);                       
        setSize(width, height);     

        buttonPanel = new JPanel();

        //creating JFrame components
        red = new JRadioButton("Red");
        yellow = new JRadioButton("Yellow");
        green = new JRadioButton("Green");

        buttonPanel.add(red);
        buttonPanel.add(yellow);
        buttonPanel.add(green);

        //JRadioButton group allows only one button to be selected at a time
        ButtonGroup group = new ButtonGroup();
        group.add(red);
        group.add(yellow);
        group.add(green);

        //adding components to frame
        add(buttonPanel, BorderLayout.SOUTH);

        //Adding action listeners
        red.addActionListener(new Listener());
        yellow.addActionListener(new Listener());
        green.addActionListener(new Listener());

        setLocationRelativeTo(null);        
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

   }

   //Listener class to handle action events
    private class Listener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e){            

            if(red.isSelected()){ 
                ob.setRed(true);
                ob.setYellow(false);
                ob.setGreen(false);
                ob.repaint();
            }

            else if(yellow.isSelected()){
                ob.setYellow(true);
                ob.setGreen(false);
                ob.setRed(false);
                ob.repaint();
            }

            else if(green.isSelected()){
                ob.setGreen(true);
                ob.setYellow(false);
                ob.setRed(false);
                ob.repaint();
            }    
        }
   }
}  

这是我的第二节课

package trafficlight;

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

public class Drawing extends JPanel{

    private boolean red = false;
    private boolean yellow = false;
    private boolean green = false;

    public void setRed(boolean clicked){
        this.red = clicked; 
    }

    public void setYellow(boolean clicked){
        this.yellow = clicked;
    }

    public void setGreen(boolean clicked){
        this.green = clicked;    
    }

   @Override
    public void paintComponent(Graphics g) { 
        super.paintComponent(g);
        g.setColor(Color.black); 
        g.drawRect(85, 20, 60, 110);

        if(!red){
            g.setColor(Color.black);                
            g.drawOval(100, 25, 30, 30);          
        }
        else{
            g.setColor(Color.red);
            g.fillOval(100, 25, 30, 30);    
        }

        if(!yellow){
            g.setColor(Color.black);                
            g.drawOval(100, 60, 30, 30);
        }
        else{
            g.setColor(Color.yellow);                   
            g.fillOval(100, 60, 30, 30);  
        }

        if(!green){
            g.setColor(Color.black);                
            g.drawOval(100, 95, 30, 30);
        }
        else{
            g.setColor(Color.green);                
            g.fillOval(100, 95, 30, 30);        
        }
    }  
}

这是主要方法

package trafficlight;


public class TrafficLight  {


    public static void main(String[] args) {
        Frame test = new Frame("TrafficLight", 250, 250);
        test.add(new Drawing());
    }   
}

【问题讨论】:

  • paint 实际上调用了paintComponent 但你的错误是你需要覆盖paintComponent 而不是paint 并在那里你做了一个超级调用。
  • 哦,我的错,当我对我的代码进行故障排除时,我正在搞乱paint,我忘记将它改回paintComponent。它仍然无法与paintComponent 一起使用。
  • 您正在使用Drawing 的两个实例。您需要将字段 ob 添加到您的框架中,而不是新的。
  • 谢谢!我不敢相信我没有早点注意到。
  • 有关代码改进,请参阅我的答案。

标签: java radio-button paintcomponent repaint graphic


【解决方案1】:

对代码的一些改进

  • 不要从JFrame 继承。您不会向此类添加任何值(组合优于继承)
  • 您的 ActionListener 不需要是命名类,因为它没有任何状态
  • 在您的情况下不需要字段
  • 使用带有大写字母的Color 常量,即Color.BLACK
  • EDT 中加入 Swing 应用程序
  • 为类和变量使用更具描述性的名称

那么你的程序可能如下所示:

public class TrafficLightUI {

  public TrafficLightUI(String title, int width, int height) {
    JFrame frame = new JFrame(title);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(width, height);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);

    JPanel mainPanel = new JPanel(new BorderLayout());

    JPanel buttonPanel = new JPanel();

    JRadioButton redRadioButton = new JRadioButton("Red");
    JRadioButton yellowRadioButton = new JRadioButton("Yellow");
    JRadioButton greenRadioButton = new JRadioButton("Green");
    buttonPanel.add(redRadioButton);
    buttonPanel.add(yellowRadioButton);
    buttonPanel.add(greenRadioButton);

    //JRadioButton group allows only one button to be selected at a time
    ButtonGroup buttonGroup = new ButtonGroup();
    buttonGroup.add(redRadioButton);
    buttonGroup.add(yellowRadioButton);
    buttonGroup.add(greenRadioButton);

    TrafficLightPanel trafficLight = new TrafficLightPanel();

    //adding components to frame
    mainPanel.add(buttonPanel, BorderLayout.SOUTH);
    mainPanel.add(trafficLight, BorderLayout.CENTER);

    //Adding action listeners
    redRadioButton.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        setTrafficLight(true, false, false, trafficLight);
      }
    });
    yellowRadioButton.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        setTrafficLight(false, true, false, trafficLight);
      }
    });
    greenRadioButton.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        setTrafficLight(false, false, true, trafficLight);
      }
    });

    frame.add(mainPanel);
    frame.setVisible(true);
  }

  private void setTrafficLight(boolean red, boolean yellow, boolean green, TrafficLightPanel trafficLight) {
    trafficLight.setGreen(green);
    trafficLight.setYellow(yellow);
    trafficLight.setRed(red);
    trafficLight.repaint();
  }
}

交通灯面板

public class TrafficLightPanel extends JPanel {
  private static final long serialVersionUID = 1L;
  private boolean red = false;
  private boolean yellow = false;
  private boolean green = false;

  public void setRed(boolean isRed) {
    this.red = isRed;
  }

  public void setYellow(boolean isYellow) {
    this.yellow = isYellow;
  }

  public void setGreen(boolean isGreen) {
    this.green = isGreen;
  }

  @Override
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.BLACK);
    g.drawRect(85, 20, 60, 110);

    if (!red) {
      g.setColor(Color.BLACK);
      g.drawOval(100, 25, 30, 30);
    } else {
      g.setColor(Color.RED);
      g.fillOval(100, 25, 30, 30);
    }

    if (!yellow) {
      g.setColor(Color.BLACK);
      g.drawOval(100, 60, 30, 30);
    } else {
      g.setColor(Color.YELLOW);
      g.fillOval(100, 60, 30, 30);
    }

    if (!green) {
      g.setColor(Color.BLACK);
      g.drawOval(100, 95, 30, 30);
    } else {
      g.setColor(Color.GREEN);
      g.fillOval(100, 95, 30, 30);
    }
  }
}

主要

public class TrafficLight {

  public static void main(String... args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        new TrafficLightUI("TrafficLight", 250, 250);
      }
    });
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 2017-01-03
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多