简体   繁体   中英

How to draw a line on a JLabel in an event handler in Java?

I have been trying hard on this and I am facing the same error over and over.

I am basically trying to load a .png using and then draw a line after having two clicks.

public class GroundTruthMarker extends JPanel {

private JFrame frame;
boolean leftSideDone = false;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                GroundTruthMarker window = new GroundTruthMarker();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public GroundTruthMarker() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 1178, 844);
    frame.setResizable(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(null);

    // points to hold the clicked coordinates
    Point leftSide = new Point();
    Point rightSide = new Point();

    // status label
    JLabel lblStatus = new JLabel("");
    lblStatus.setBounds(373, 807, 134, 20);
    frame.getContentPane().add(lblStatus);

    JButton btnSave = new JButton("Save");
    btnSave.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            lblStatus.setText("Saved!");
        }
    });
    btnSave.setBounds(215, 807, 117, 25);
    frame.getContentPane().add(btnSave);

    JLabel lblpicture = new JLabel("");
    lblpicture.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {

            if (leftSideDone == false) {
                leftSide.x = e.getX();
                leftSide.y = e.getY();
                lblStatus.setText("Left Side Done!");
                leftSideDone = true;
            } else {
                rightSide.x = e.getX();
                rightSide.y = e.getY();
                lblStatus.setText("Right Side Done!");
                leftSideDone = false;

                Graphics g = getGraphics();
                g.setColor(Color.cyan);
                g.drawLine(leftSide.x, leftSide.y, rightSide.x, rightSide.y);
            }

        }
    });

    // picture label
    lblpicture.setBackground(Color.WHITE);
    lblpicture.setBounds(12, 12, 1154, 765);
    // create a line border with the specified color and width
    Border border = BorderFactory.createLineBorder(Color.BLUE, 1);
    // set the border of this component
    lblpicture.setBorder(border);
    frame.getContentPane().add(lblpicture);

    JButton btnLoadImages = new JButton("Load Images");
    btnLoadImages.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            // set up the file chooser
            JFileChooser fileChooser = new JFileChooser();
            // only directories
            fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
                File dir = fileChooser.getSelectedFile();
                // load from the directory
                System.out.println(dir.getName());
                // loop over the image directory
                if (dir.isDirectory()) { // make sure it's a directory
                    for (final File f : dir.listFiles()) {
                        BufferedImage img = null;
                        // read every image and display it in the gui
                        try {
                            lblStatus.setText("New Image!");
                            img = ImageIO.read(f);
                            lblpicture.setIcon(new ImageIcon(img));

                        } catch (final IOException e1) {
                            // handle errors here
                            System.out.println("Error:" + e1.getMessage());
                        }
                    }
                }
            }
        }
    });
    btnLoadImages.setBounds(23, 807, 144, 25);
    frame.getContentPane().add(btnLoadImages);
}

}

And this is the error I am getting on runtime, when I expect a line:

java.lang.NullPointerException
    at GroundTruthMarker$3.mouseClicked(GroundTruthMarker.java:101)
    at java.awt.Component.processMouseEvent(Component.java:6538)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    at java.awt.Component.processEvent(Component.java:6300)
    at java.awt.Container.processEvent(Container.java:2236)
    at java.awt.Component.dispatchEventImpl(Component.java:4891)
    at java.awt.Container.dispatchEventImpl(Container.java:2294)
    at java.awt.Component.dispatchEvent(Component.java:4713)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4534)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
    at java.awt.Container.dispatchEventImpl(Container.java:2280)
    at java.awt.Window.dispatchEventImpl(Window.java:2750)
    at java.awt.Component.dispatchEvent(Component.java:4713)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.awt.EventQueue$4.run(EventQueue.java:729)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Keep in mind that the drawing has to be conducted in the event handler. I tried some methods but faced with "You cannot do this in mouse-event-handler" kind of errors, so they didn't work.

I appreciate any kind of help.

Thanks.

Change your code like this

public class GroundTruthMarker extends JPanel {

    private BufferedImage img = null;  // ADD THIS LINE
    [...]
    private void initialize() {
        [...]
        // JLabel lblpicture = new JLabel("");  // REMOVE THIS LINE
        // ADD THE FOLLOWING INSTEAD
        JPanel lblpicture = new JPanel(){
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(img,0,0,null);
                g.setColor(Color.cyan);
                g.drawLine(leftSide.x, leftSide.y, rightSide.x, rightSide.y);
            }
        };
        [...]
        public void mouseClicked(MouseEvent e) {
            [...]
            // REMOVE THIS!
            //Graphics g = getGraphics();
            //g.setColor(Color.cyan);
            //g.drawLine(leftSide.x, leftSide.y, rightSide.x, rightSide.y);
            // ADD THIS INSTEAD
            lblpicture.repaint();
        }
        [...]
        public void actionPerformed(ActionEvent e) {
            [...]
            // REMOVE THIS LINE
            //BufferedImage img = null;
            [...]
            // REMOVE THIS LINE
            //lblpicture.setIcon(new ImageIcon(img));
            // ADD THIS LINE INSTEAD
            lblpicture.repaint();
            [...]
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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