有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java重绘似乎不调用paintComponent

我试图用单选按钮模拟交通灯。无论我在哪里调用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());
    }   
}

共 (1) 个答案

  1. # 1 楼答案

    代码的一些改进

    • 不要从JFrame继承。您不向该类添加任何值(组合重于继承)
    • 您的ActionListener不需要是命名类,因为它没有任何状态
    • 在您的案例中不需要字段
    • Color常量与大写字母一起使用,即Color.BLACK
    • 将Swing应用程序排队到EDT
    • 对类和变量使用更多描述性名称

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

    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);
          }
        });
      }
    }