Java JPanel getGraphics()

后端 未结 2 1494
旧时难觅i
旧时难觅i 2020-12-17 01:14

Since Java only supports single inheritance, I desire to paint directly on an instance of a JPanel that is a member of the class

相关标签:
2条回答
  • 2020-12-17 01:49
    class SomeComponent extends JComponent {
    
        private Graphics2D g2d;
    
        public void paintComponent(Graphics g) {
            g2d = (Graphics2D) g.create();
            g2d.setColor(Color.BLACK);
            g2d.scale(scale, scale);
            g2d.drawOval(0, 0, importance, importance);
    
        }
    
        public Graphics2D getG2d() {
            return g2d;
        }
        public void setG2d(Graphics2D g2d) {
            this.g2d = g2d;
        }
    }
    

    then you can do the following get the SomeComponent instance in the panel and modify it

    Graphics2D x= v.getPanel().get(i).getG2d;
    x.setColor(Color.BLUE);
    v.getPanel().get(i).setG2d(x);
    v.getPanel().repaint();
    v.getPanel().revalidate();
    

    V is a class that extends JFrame and contains the panel in it AND i is instance of SomeComponent

    0 讨论(0)
  • 2020-12-17 01:57

    Here are some very simple examples which show how to paint outside paintComponent.

    The drawing actually happens on a java.awt.image.BufferedImage, and we can do that anywhere, as long as we're on the Event Dispatch Thread. (For discussion of multithreading with Swing, see here and here.)

    Then, I'm overriding paintComponent, but only to paint the image on to the panel. (I also paint a little swatch in the corner.)

    This way the drawing is actually permanent, and Swing is able to repaint the panel if it needs to without causing a problem for us. We could also do something like save the image to a file easily, if we wanted to.

    import javax.swing.*;
    import java.awt.*;
    import java.awt.image.*;
    import java.awt.event.*;
    
    /**
     * Holding left-click draws, and
     * right-clicking cycles the color.
     */
    class PaintAnyTime {
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new PaintAnyTime();
                }
            });
        }
    
        Color[]    colors = {Color.red, Color.blue, Color.black};
        int  currentColor = 0;
        BufferedImage img = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
        Graphics2D  imgG2 = img.createGraphics();
    
        JFrame frame = new JFrame("Paint Any Time");
        JPanel panel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                // Creating a copy of the Graphics
                // so any reconfiguration we do on
                // it doesn't interfere with what
                // Swing is doing.
                Graphics2D g2 = (Graphics2D) g.create();
                // Drawing the image.
                int w = img.getWidth();
                int h = img.getHeight();
                g2.drawImage(img, 0, 0, w, h, null);
                // Drawing a swatch.
                Color color = colors[currentColor];
                g2.setColor(color);
                g2.fillRect(0, 0, 16, 16);
                g2.setColor(Color.black);
                g2.drawRect(-1, -1, 17, 17);
                // At the end, we dispose the
                // Graphics copy we've created
                g2.dispose();
            }
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(img.getWidth(), img.getHeight());
            }
        };
    
        MouseAdapter drawer = new MouseAdapter() {
            boolean rButtonDown;
            Point prev;
    
            @Override
            public void mousePressed(MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton(e)) {
                    prev = e.getPoint();
                }
                if (SwingUtilities.isRightMouseButton(e) && !rButtonDown) {
                    // (This just behaves a little better
                    // than using the mouseClicked event.)
                    rButtonDown  = true;
                    currentColor = (currentColor + 1) % colors.length;
                    panel.repaint();
                }
            }
    
            @Override
            public void mouseDragged(MouseEvent e) {
                if (prev != null) {
                    Point  next = e.getPoint();
                    Color color = colors[currentColor];
                    // We can safely paint to the
                    // image any time we want to.
                    imgG2.setColor(color);
                    imgG2.drawLine(prev.x, prev.y, next.x, next.y);
                    // We just need to repaint the
                    // panel to make sure the
                    // changes are visible
                    // immediately.
                    panel.repaint();
                    prev = next;
                }
            }
    
            @Override
            public void mouseReleased(MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton(e)) {
                    prev = null;
                }
                if (SwingUtilities.isRightMouseButton(e)) {
                    rButtonDown = false;
                }
            }
        };
    
        PaintAnyTime() {
            // RenderingHints let you specify
            // options such as antialiasing.
            imgG2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);
            imgG2.setStroke(new BasicStroke(3));
            //
            panel.setBackground(Color.white);
            panel.addMouseListener(drawer);
            panel.addMouseMotionListener(drawer);
            Cursor cursor =
                Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
            panel.setCursor(cursor);
            frame.setContentPane(panel);
            frame.pack();
            frame.setResizable(false);
            frame.setLocationRelativeTo(null);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    }
    

    It's also possible to set up a JLabel with an ImageIcon, although personally I don't like this method. I don't think JLabel and ImageIcon are required by their specifications to see changes we make to the image after we've passed it to the constructors.

    This way also doesn't let us do stuff like painting the swatch. (For a slightly more complicated paint program, on the level of e.g. MSPaint, we'd want to have a way to select an area and draw a bounding box around it. That's another place we'd want to be able to paint directly on the panel, in addition to drawing to the image.)

    import javax.swing.*;
    import java.awt.*;
    import java.awt.image.*;
    import java.awt.event.*;
    
    /**
     * Holding left-click draws, and
     * right-clicking cycles the color.
     */
    class PaintAnyTime {
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new PaintAnyTime();
                }
            });
        }
    
        Color[]    colors = {Color.red, Color.blue, Color.black};
        int  currentColor = 0;
        BufferedImage img = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
        Graphics2D  imgG2 = img.createGraphics();
    
        JFrame frame = new JFrame("Paint Any Time");
        JLabel label = new JLabel(new ImageIcon(img));
    
        MouseAdapter drawer = new MouseAdapter() {
            boolean rButtonDown;
            Point prev;
    
            @Override
            public void mousePressed(MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton(e)) {
                    prev = e.getPoint();
                }
                if (SwingUtilities.isRightMouseButton(e) && !rButtonDown) {
                    // (This just behaves a little better
                    // than using the mouseClicked event.)
                    rButtonDown  = true;
                    currentColor = (currentColor + 1) % colors.length;
                    label.repaint();
                }
            }
    
            @Override
            public void mouseDragged(MouseEvent e) {
                if (prev != null) {
                    Point  next = e.getPoint();
                    Color color = colors[currentColor];
                    // We can safely paint to the
                    // image any time we want to.
                    imgG2.setColor(color);
                    imgG2.drawLine(prev.x, prev.y, next.x, next.y);
                    // We just need to repaint the
                    // label to make sure the
                    // changes are visible
                    // immediately.
                    label.repaint();
                    prev = next;
                }
            }
    
            @Override
            public void mouseReleased(MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton(e)) {
                    prev = null;
                }
                if (SwingUtilities.isRightMouseButton(e)) {
                    rButtonDown = false;
                }
            }
        };
    
        PaintAnyTime() {
            // RenderingHints let you specify
            // options such as antialiasing.
            imgG2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);
            imgG2.setStroke(new BasicStroke(3));
            //
            label.setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
            label.setBackground(Color.white);
            label.setOpaque(true);
            label.addMouseListener(drawer);
            label.addMouseMotionListener(drawer);
            Cursor cursor =
                Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
            label.setCursor(cursor);
            frame.add(label, BorderLayout.CENTER);
            frame.pack();
            frame.setResizable(false);
            frame.setLocationRelativeTo(null);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    }
    
    0 讨论(0)
提交回复
热议问题