0

我一直在开发一个程序,该程序需要在鼠标拖动事件触发时在图像上绘制线条,但是在我的代码中,当通过 repaint() 调用paintComponent 时,paintComponent 方法不会执行。我已经阅读了关于挥杆图形的教程,并且还从其他程序员那里得到了一些意见,但到目前为止还没有找到适合我的解决方案。

我发布了一个小的 SSCCE 来帮助从我的程序中查明没有按预期运行的代码区域,试图为我自己和任何查看我的代码的人简化这一点。

提前感谢任何花时间帮我检查的人。

下面是我正在使用的两个单独的类。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class TestGraphics {
private JLayeredPane contentPane;

public void newImage() {
    try {
        JFileChooser fileChooser = new JFileChooser(".");
        int status = fileChooser.showOpenDialog(null);

        if (status == JFileChooser.APPROVE_OPTION) {
            File selectedFile = fileChooser.getSelectedFile();
            System.out.println("The selected file is from the: " + selectedFile.getParent() + " Drive");
            System.out.println("Name of file: " + selectedFile.getName());
            System.out.println("Opening file");

            BufferedImage buffImage = ImageIO.read(new File(selectedFile.getAbsolutePath()));
            ImageIcon image = new ImageIcon(buffImage);
            JLabel label = new JLabel(image);
            label.setSize(label.getPreferredSize());

            label.setLocation(0, 0);

            contentPane = new JLayeredPane();
            contentPane.setBackground(Color.WHITE);
            contentPane.setOpaque(true);
            //getTabbedPane().setComponentAt(tabNum, contentPane);
            contentPane.add(label);
            contentPane.setPreferredSize(new Dimension(label.getWidth(), label.getHeight()));

            Segmentation segmentation = new Segmentation();
            segmentation.addListeners(label); //call to addListeners method

            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(contentPane);
            frame.setResizable(false);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);

        } else if(status == JFileChooser.CANCEL_OPTION) {
            JOptionPane.showMessageDialog(null, "Canceled");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            TestGraphics tg = new TestGraphics();
            tg.newImage();
        }
    });
}

}

和另一个。

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import javax.swing.JLabel;
import java.awt.event.MouseAdapter;

public class Segmentation extends JLabel {

private static final long serialVersionUID = -1481861667880271052L;  // unique id   
private static final Color LINES_COLOR = Color.red;
public static final Color CURRENT_LINE_COLOR = new Color(255, 200, 200);
ArrayList<Line2D> lineList = new ArrayList<Line2D>();
Line2D currentLine = null;
MyMouseAdapter mouse = new MyMouseAdapter();

public void addListeners(Component component) { 
    MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
    component.addMouseListener(myMouseAdapter);
    component.addMouseMotionListener(myMouseAdapter);
}

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

    System.out.println("repainting");

    g2.setColor(LINES_COLOR);
    for (Line2D line : lineList) {
        g2.draw(line);
    }
    if (currentLine != null) {
        g2.setColor(CURRENT_LINE_COLOR);
        g2.draw(currentLine);
    }
}

private class MyMouseAdapter extends MouseAdapter {
    Point p1 = null;

    @Override
    public void mousePressed(MouseEvent e) {
        p1 = e.getPoint();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        if (currentLine != null) {
            currentLine = new Line2D.Double(p1, e.getPoint());
            lineList.add(currentLine);
            currentLine = null;
            p1 = null;
            System.out.println("about to repaint");
            repaint();
        }
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if (p1 != null) {
            currentLine = new Line2D.Double(p1, e.getPoint());
            repaint();
        }
    }
}

}
4

1 回答 1

4

您永远不会将您的Segmentation实例添加到组件层次结构中。所以你paintComponent永远不会被召唤。

你应该有这样的地方:

Segmentation segmentation = new Segmentation();
// ...
component.add(segmentation); // assuming that component is part of a visible component hierarchy

编辑:

您没有在适当的组件上注册鼠标侦听器。以下代码似乎工作得很好:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class TestGraphics {
    private JLayeredPane contentPane;

    public void newImage() {
        try {
            JFileChooser fileChooser = new JFileChooser(".");
            int status = fileChooser.showOpenDialog(null);

            if (status == JFileChooser.APPROVE_OPTION) {
                File selectedFile = fileChooser.getSelectedFile();
                System.out.println("The selected file is from the: " + selectedFile.getParent() + " Drive");
                System.out.println("Name of file: " + selectedFile.getName());
                System.out.println("Opening file");

                BufferedImage buffImage = ImageIO.read(new File(selectedFile.getAbsolutePath()));
                ImageIcon image = new ImageIcon(buffImage);

                contentPane = new JLayeredPane();
                contentPane.setBackground(Color.WHITE);
                contentPane.setOpaque(true);
                // getTabbedPane().setComponentAt(tabNum, contentPane);
                Dimension d = new Dimension(image.getIconWidth(), image.getIconHeight());
                Segmentation segmentation = new Segmentation();
                segmentation.setIcon(image);
                segmentation.setSize(d);
                contentPane.setPreferredSize(d);
                contentPane.add(segmentation);

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setContentPane(contentPane);
                frame.setResizable(false);
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);

            } else if (status == JFileChooser.CANCEL_OPTION) {
                JOptionPane.showMessageDialog(null, "Canceled");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static class Segmentation extends JLabel {

        private static final long serialVersionUID = -1481861667880271052L; // unique id
        private static final Color LINES_COLOR = Color.red;
        public static final Color CURRENT_LINE_COLOR = new Color(255, 200, 200);
        ArrayList<Line2D> lineList = new ArrayList<Line2D>();
        Line2D currentLine = null;
        MyMouseAdapter mouse = new MyMouseAdapter();

        public Segmentation() {
            addMouseListener(mouse);
            addMouseMotionListener(mouse);
        }

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

            System.out.println("repainting");

            g2.setColor(LINES_COLOR);
            for (Line2D line : lineList) {
                g2.draw(line);
            }
            if (currentLine != null) {
                g2.setColor(CURRENT_LINE_COLOR);
                g2.draw(currentLine);
            }
        }

        private class MyMouseAdapter extends MouseAdapter {
            Point p1 = null;

            @Override
            public void mousePressed(MouseEvent e) {
                p1 = e.getPoint();
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                if (currentLine != null) {
                    currentLine = new Line2D.Double(p1, e.getPoint());
                    lineList.add(currentLine);
                    currentLine = null;
                    p1 = null;
                    System.out.println("about to repaint");
                    repaint();
                }
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                if (p1 != null) {
                    currentLine = new Line2D.Double(p1, e.getPoint());
                    repaint();
                }
            }
        }

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                TestGraphics tg = new TestGraphics();
                tg.newImage();
            }
        });
    }

}
于 2013-02-10T16:22:55.673 回答