Я очень стараюсь, и я снова и снова сталкиваюсь с такой же ошибкой.Как нарисовать линию на 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)
Имейте в виду, что рисунок должен быть проведен в обработчике события , Я пробовал некоторые методы, но сталкивался с ошибками «Невозможно сделать это с помощью мыши-события-обработчика», поэтому они не работали.
Я ценю любую помощь.
Спасибо.
* «Имейте в виду, что рисунок должен быть проведен в обработчик событий.» * Нет, рисунок выполняется в 'метод paintComponent' переопределять. 'this.getGraphics()' дает вам нулевой объект Graphics. Используйте объект Graphics, указанный в 'paintComponent', и не забудьте сделать вызов' super'. – TNT
Так что во всемогущем языке Java нельзя сделать соответствующий мероприятие ?! Или вы имеете в виду, что я должен разместить это внутри обработчика? –
После того как вы настроили свой метод 'paintComponent', вы можете вызвать' repaint' в обработчике событий, который планирует вызов 'paintComponent', что позволяет вам перерисовывать то, что находится на панели, используя любые обновленные поля. Тем не менее, вы должны создать свои экземпляры экземпляров объектов «Point» вместо того, чтобы они были локальными для метода. – TNT