简体   繁体   English

彩绘JPanel不会出现在JFrame中

[英]Painted JPanel won't show up in JFrame

When I run my code, I expect to see a JPanel in my JFrame , but nothing shows up. 当我运行我的代码时,我希望在我的JFrame看到一个JPanel ,但没有任何显示。 I had a button in the frame, and it shows up. 我在框架中有一个按钮,它出现了。 But the JPanel doesn't show up, I even colored it in red. JPanel没有出现,我甚至用红色着色。 Here is the code for my JPanel : 这是我的JPanel的代码:

import java.awt.*;
import javax.swing.JPanel;
public class graphic extends JPanel {
    private static final long serialVersionUID = -3458717449092499931L;
    public Game game;
    public graphic(Game game){
    this.game = game;
    this.setPreferredSize(new Dimension(400,400));
    this.setBackground(Color.RED);
}
public void paintComponent(Graphics g){
    for (Line l:game.mirrors){
        g.setColor(Color.BLACK);
        g.drawLine(l.start.x, l.start.y, l.end.x, l.end.y);
    }
}
}

And my JFrame code: 我的JFrame代码:

import java.awt.Container;
import java.awt.event.*;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.*;
public class Viewer implements ActionListener {
public JFrame frame;
public JButton drawShoot;
public boolean draw;
public Game game;
public graphic graphic;
public TimerTask timert;
public Timer timer;
public Viewer(){
    draw = true;
    game = new Game();
}
public static void main(String args[]){
    Viewer v = new Viewer();
    v.setup();
}
public void setup(){
    frame = new JFrame("Laser Stimulator");
    drawShoot = new JButton("Edit Mode");
    graphic = new graphic(game);
    graphic.repaint();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setBounds(300, 300, 600, 600);
    Container contentPane = frame.getContentPane();
    SpringLayout layout = new SpringLayout();
    contentPane.setLayout(layout);
    drawShoot.addActionListener(this);
    timert = new TimerTask() {
        @Override
        public void run() {

        }
    };
    timer =new Timer();
    timer.scheduleAtFixedRate(timert, 0, 1000/30);
    contentPane.add(graphic);
    layout.putConstraint(SpringLayout.NORTH, graphic, 0, SpringLayout.NORTH, contentPane);
    layout.putConstraint(SpringLayout.WEST, graphic, 0, SpringLayout.WEST, contentPane);
    frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource()==drawShoot){
        draw = !draw;
        drawShoot.setText((draw)?"Edit Mode":"Shoot Mode");
    }
}
}

So the basic problem is you failed to honor the paint chain. 所以基本的问题是你没有兑现油漆链。 You must call super.paintXxx when ever you override on the paint methods... 在覆盖绘制方法时,必须调用super.paintXxx ...

This method must call super.paintComponent(g) , because it's responsible for clearing the background ;) 此方法必须调用super.paintComponent(g) ,因为它负责清除背景;)

public void paintComponent(Graphics g) {
    for (Line l : game.mirrors) {
        g.setColor(Color.BLACK);
        g.drawLine(l.start.x, l.start.y, l.end.x, l.end.y);
    }
}

在此输入图像描述

public class QuickTestPaintPane {

    public static void main(String[] args) {
        new QuickTestPaintPane();
    }

    public QuickTestPaintPane() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                Viewer v = new Viewer();
                v.setup();

            }
        });
    }

    public class Viewer implements ActionListener {

        public JFrame frame;
        public JButton drawShoot;
        public boolean draw;
//        public Game game;
        public graphic graphic;
        public TimerTask timert;
        public Timer timer;

        public Viewer() {
            draw = true;
//            game = new Game();
        }

        public void setup() {
            frame = new JFrame("Laser Stimulator");
            drawShoot = new JButton("Edit Mode");
            graphic = new graphic();
//            graphic.repaint();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setBounds(300, 300, 600, 600);
//            Container contentPane = frame.getContentPane();
            SpringLayout layout = new SpringLayout();
            frame.setLayout(layout);
            drawShoot.addActionListener(this);
            timert = new TimerTask() {
                @Override
                public void run() {
                }
            };
            timer = new Timer();
            timer.scheduleAtFixedRate(timert, 0, 1000 / 30);
            frame.add(graphic);
            layout.putConstraint(SpringLayout.NORTH, graphic, 0, SpringLayout.NORTH, frame.getContentPane());
            layout.putConstraint(SpringLayout.WEST, graphic, 0, SpringLayout.WEST, frame.getContentPane());
            frame.setVisible(true);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == drawShoot) {
                draw = !draw;
                drawShoot.setText((draw) ? "Edit Mode" : "Shoot Mode");
            }
        }
    }

    public class graphic extends JPanel {

        private static final long serialVersionUID = -3458717449092499931L;
//        public Game game;

//        public graphic(Game game) {
        public graphic() {
//            this.game = game;
            this.setPreferredSize(new Dimension(400, 400));
            this.setBackground(Color.RED);
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g;
            g2d.setColor(Color.BLACK);
            g2d.drawLine(0, 0, getWidth(), getHeight());
//            for (Line l : game.mirrors) {
//                g.setColor(Color.BLACK);
//                g.drawLine(l.start.x, l.start.y, l.end.x, l.end.y);
//            }
        }
    }
}

@MadProgrammer has already answered this question (+1 to him). @MadProgrammer已经回答了这个问题(给他+1)。 In most overriden methods there are calls to their super do not forget to honor this or else these small hiccups begin to surface. 在大多数覆盖方法中,有超级方法的呼叫不要忘记尊重这一点,否则这些小小的打嗝开始出现。

On another note: 另一个注意事项:

  • Dont call setBounds(..) on JFrame ( i cannot see why you need it) rather call JFrame#pack() before setting the JFrame visible. 不要在JFrame上调用setBounds(..) (我看不出你为什么需要它)而是在设置JFrame可见之前调用JFrame#pack()

  • No need to do frame.getContentPane() as of Java 6. Simply use: frame.add() or frame.setLayout(..) . 从Java 6开始,无需执行frame.getContentPane() 。只需使用: frame.add()frame.setLayout(..)

    As a conveniance add and its variants, remove and setLayout have been overridden to forward to the contentPane as necessary. 作为一个commiance add及其变体, removesetLayout已被覆盖,以便在必要时转发到contentPane

  • You also have this: 你也有这个:

     graphic = new graphic(game); graphic.repaint(); 

    I cannnot see why the call to repaint() will be necessary repaint() will be called the first time the component is visible 我无法理解为什么调用repaint()将是必要的repaint()将在组件第一次可见时调用

  • Rather override getPreferredSize of JPanel than calling setPreferredSize() 而是覆盖JPanel getPreferredSize而不是调用setPreferredSize()

  • Do not implement an ActionListener in a class unless it will be accessed via other classes. 除非可以通过其他类访问,否则不要在类中实现ActionListener Rather use an anonymous Listener like so: 而是像这样使用匿名Listener

     refresh.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == drawShoot) { draw = !draw; drawShoot.setText((draw) ? "Edit Mode" : "Shoot Mode"); } } }); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM