如何在 Java 中的事件处理程序中的 JLabel 上画一条线?
How to draw a line on a JLabel in an event handler in 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.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.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:709)
at java.awt.EventQueue.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.run(EventQueue.java:731)
at java.awt.EventQueue.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)
请记住,绘图必须在事件处理程序中进行。我尝试了一些方法,但遇到了 "You cannot do this in mouse-event-handler" 种错误,所以它们没有用。
感谢任何形式的帮助。
谢谢。
像这样更改您的代码
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();
[...]
}
}
}
我一直在努力解决这个问题,但我一遍又一遍地面临同样的错误。
我基本上是在尝试加载 .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.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.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:709)
at java.awt.EventQueue.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.run(EventQueue.java:731)
at java.awt.EventQueue.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)
请记住,绘图必须在事件处理程序中进行。我尝试了一些方法,但遇到了 "You cannot do this in mouse-event-handler" 种错误,所以它们没有用。
感谢任何形式的帮助。
谢谢。
像这样更改您的代码
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();
[...]
}
}
}