2016-03-02 4 views
0

Я очень стараюсь, и я снова и снова сталкиваюсь с такой же ошибкой.Как нарисовать линию на JLabel в обработчике событий в Java?

В основном я пытаюсь загрузить .png, используя, а затем нарисую строку после двух щелчков.

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

}

И это ошибка я получаю во время выполнения, когда я ожидаю линии:

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) 

Имейте в виду, что рисунок должен быть проведен в обработчике события , Я пробовал некоторые методы, но сталкивался с ошибками «Невозможно сделать это с помощью мыши-события-обработчика», поэтому они не работали.

Я ценю любую помощь.

Спасибо.

+0

* «Имейте в виду, что рисунок должен быть проведен в обработчик событий.» * Нет, рисунок выполняется в 'метод paintComponent' переопределять. 'this.getGraphics()' дает вам нулевой объект Graphics. Используйте объект Graphics, указанный в 'paintComponent', и не забудьте сделать вызов' super'. – TNT

+0

Так что во всемогущем языке Java нельзя сделать соответствующий мероприятие ?! Или вы имеете в виду, что я должен разместить это внутри обработчика? –

+0

После того как вы настроили свой метод 'paintComponent', вы можете вызвать' repaint' в обработчике событий, который планирует вызов 'paintComponent', что позволяет вам перерисовывать то, что находится на панели, используя любые обновленные поля. Тем не менее, вы должны создать свои экземпляры экземпляров объектов «Point» вместо того, чтобы они были локальными для метода. – TNT

ответ

0

Измените код, как этот

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(); 
      [...] 
     } 
    } 
} 
+0

Да, это делает линию, однако таким образом я теряю изображение, которое я загружаю через filechooser. Я хочу, чтобы эта строка была нарисована на загружаемом изображении. –

+1

Вам также нужно удалить строку 'BufferedImage img = null' в вашем методе' actionPerformed' или он не будет использовать ваш глобальный img var. Я отредактировал свой ответ. – ArcticLord

+0

Это сделало. Отлично. Благодарю. –