- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在开发一个程序,该程序需要在由鼠标拖动事件触发时在图像上绘制线条,但是在我的代码中,当通过 repaint() 调用paintComponent 时,paintComponent 方法不会执行。我已经阅读了有关 swing 图形的教程,并且还从其他程序员那里得到了一些意见,但到目前为止还无法找到适合我的解决方案。
我发布了一个小 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();
}
}
}
}
最佳答案
您永远不会将 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();
}
});
}
}
关于java - 重绘时不调用paintComponent(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14799764/
我是 Java 的新手。下面是两个类,一个类扩展JComponent,需要重写paintComponent方法。另一个类扩展了JPanel,同样需要重写paintComponent方法。 为什么Dra
我想知道 paintcomponent() 和 paintcomponents() 有什么不同? 当我从 paintcomponent 使用它时,它显示了我们想要的一切,但是 paintcompone
public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2 = (Gr
我稍后在我的主方法中使用这样的调用: public static void main(String[] args) { SwingUtilities.invokeLater(new Runna
所以我正在开发一款由两个网格组成的游戏。每个网格都是一个 JPanel,我在其中(可能)在网格中的每个空间上绘制一个对象。我发现绘制对象正在减慢应用程序的速度,我想知道是否有办法防止这种情况发生。 详
这个问题已经有答案了: paintComponent is not being called in JPanel (1 个回答) 已关闭 4 年前。 很抱歉,这个问题可能已经解决了,但我已经到处搜索但
我的问题非常简单:我有这个小程序,它只是没有显示我正在尝试制作的红框: 主要 public class Main { public static void main(String[] args
我正在尝试编写一个类似这样的应用程序: - 显示对话框 - 当用户单击“确定”时,关闭对话框,转到主应用程序 以下是相关代码片段: public class Owari extends JPanel
这应该是一个抽象类,可以扩展以绘制连接 JPanel 上某些坐标点的线。 但是,永远不会调用专门的 PaintComponents() 方法。我已经看到其他答案并尝试使用他们的解决方案,例如检查我是否
我有以下结构: method1 method2 ... methodn methodX 方法x包含: JFrame frame = new JFrame("Sample"); frame.setDef
我在使用矩形时遇到一些问题 这是我的代码: import java.awt.*; import javax.swing.*; import java.util.*; public class squa
我正在尝试制作西洋跳棋游戏,但以下架构没有在 JFrame 上显示我做错了什么 //基类 import java.awt.event.MouseEvent; import java.awt.event
问题涉及我项目中的 2 个类:主类和绘图类。主类创建 JFrame 并在其中放置 2 个 JPanel。第一个 JPanel 包含用于输入数字的 JTextFields 和用于选择不同选项的 JBut
我已经处理学校作业有一段时间了。但我无法真正理解我应该做什么。作业明天就要交了,我感觉压力很大。 任务是,我将获取一些图片,将它们放在窗口中,然后能够在它们周围移动并能够旋转。 最大的问题是我不知道如
我在使用 PaintComponent 绘制形状时遇到不清楚的问题。 public class Shape extends JPanel { private String shape; private
据我了解,Swing 将决定何时需要重新绘制,这可以解释为什么 paintComponent() 执行两次。但我制作了一个 hibernate 16 毫秒、重绘、 hibernate 16 毫秒、重绘
这是我的代码,它工作完美,并在 JFrame 中绘制形状。每个方法都通过其名称进行调用,在我的程序中我没有调用任何 paintComponent() 方法。那么paintComponent()方法的调
我正在尝试在 JPanel 上绘制一些内容,但似乎我遇到了 paint 和 paintComponent 方法的问题。可能与双缓冲有关,但我不确定。 public void PaintComponen
我是 Swing 新手,正在尝试将图像背景添加到我的 JFrame 中。但是我的 paintComponent 方法不起作用。您能否就如何修复我的代码以便在背景中绘制图像提供一些建议? 代码如下: /
我正在尝试编写简单的程序,当鼠标拖动时绘制圆圈,但paintComponent方法仅被调用一次(启动后)。 在这个类中,我有一些在拖动鼠标时绘制圆圈的方法。 import javax.swing.*;
我是一名优秀的程序员,十分优秀!