gpt4 book ai didi

java - 图像在 swing 中的 MouseEvent 上无法正确显示

转载 作者:行者123 更新时间:2023-12-01 14:23:25 24 4
gpt4 key购买 nike

3x3 check board

我有一个在 JPanel 上渲染的 3x3 检查板状图像,该图像被添加到 JFrame 上。然后我还有 9 个 JPanel(每个方 block 顶部有 1 个),单击后需要在相应的方 block 上绘制一些内容。我的问题是它只适用于左上角的方 block 。其余的绘图似乎是在棋盘图像下方绘制的。因此,如果我注释掉加载棋盘图像的部分,然后单击它们,就像它们在那里一样,那么绘图就会正确显示。我使用分层 Pane 得到了相同的结果。使用绝对定位,并且坐标似乎是正确的,因为如果我删除棋盘图像,则绘图将出现在应有的位置,并且绘图不会占用超过一个正方形。我的代码结构如下:

“main”类创建框架并添加另一个类的实例,该类扩展 JPanel 并使用 PaintComponent(Graphics g) 绘制棋盘图像。“main”类还添加了 9 个类实例,该类扩展了 JPanel,并使用 PaintComponent(Graphics g) 在鼠标单击时绘制一些内容。每个实例都放置在一个正方形的顶部

请注意,因为我打算仅使用矩形来完成此操作,所以我将第二类命名为矩形,但它是矩形 JPanel,而不是 java 矩形实例

代码:

public class Main3
{
private JFrame frame=new JFrame("");
private Rectangles rect00=new Rectangles(0,0,129,129);
private Rectangles rect01=new Rectangles(136,0,129,129);
private Rectangles rect02=new Rectangles(268,0,129,129);
private Rectangles rect10=new Rectangles(0,136,129,129);
private Rectangles rect11=new Rectangles(134,136,129,129);
private Rectangles rect12=new Rectangles(269,137,129,129);
private Rectangles rect20=new Rectangles(0,270,129,129);
private Rectangles rect21=new Rectangles(136,269,129,129);
private Rectangles rect22=new Rectangles(269,270,129,129);

public void Display()
{
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLayout(null);
frame.setSize(600,400);
sub inter=new sub();
inter.setLayout(null);
inter.setBounds(0,0,600,400);
inter.setSize(600,400);

rect00.setBounds(rect00.getX(),rect00.getY(),rect00.getWidth(),rect00.getHeight());
rect01.setBounds(rect01.getX(),rect01.getY(),rect01.getWidth(),rect01.getHeight());
rect02.setBounds(rect02.getX(),rect02.getY(),rect02.getWidth(),rect02.getHeight());
rect10.setBounds(rect10.getX(),rect10.getY(),rect10.getWidth(),rect10.getHeight());
rect11.setBounds(rect11.getX(),rect11.getY(),rect11.getWidth(),rect11.getHeight());
rect12.setBounds(rect12.getX(),rect12.getY(),rect12.getWidth(),rect12.getHeight());
rect20.setBounds(rect20.getX(),rect20.getY(),rect20.getWidth(),rect20.getHeight());
rect21.setBounds(rect21.getX(),rect21.getY(),rect21.getWidth(),rect21.getHeight());
rect22.setBounds(rect22.getX(),rect22.getY(),rect22.getWidth(),rect22.getHeight());
rect00.setOpaque(false);
rect01.setOpaque(false);
rect02.setOpaque(false);
rect10.setOpaque(false);
rect11.setOpaque(false);
rect12.setOpaque(false);
rect20.setOpaque(false);
rect21.setOpaque(false);
rect22.setOpaque(false);

inter.add(rect00);
inter.add(rect01);
inter.add(rect02);
inter.add(rect10);
inter.add(rect11);
inter.add(rect12);
inter.add(rect20);
inter.add(rect21);
inter.add(rect22);
frame.add(inter);
frame.setResizable(false);
frame.setVisible(true);
}

public static void main(String args[])
{
new main().Display();
}


private class sub extends JPanel
{

private BufferedImage image;

public sub ()
{

try
{
image=ImageIO.read(new File("image.jpg"));

}
catch (IOException e)
{

e.printStackTrace();
}
}

@Override
public Dimension getPreferredSize()
{
return (new Dimension(600,400));
}


@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}


}
}

这是另一个类

public class Rectangles extends JPanel implements MouseListener
{

private int Posx;
private int Posy;
private int width;
private int height;
private boolean selected=false;
public Rectangles(int Posx,int Posy,int width,int height)
{
this.Posx=Posx;
this.Posy=Posy;
this.width=width;
this.height=height;
this.addMouseListener(this);
}

@Override
protected void paintComponent(Graphics g)
{
if(selected==true)
{
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g2);
g2.setColor(new Color(250, 235, 215));
g2.drawRect(Posx,Posy,width,height);
Graphics2D g3=(Graphics2D)g;
g2.setColor(new Color(0,0,0));
g3.setStroke(new BasicStroke(20));
g3.drawLine(Posx,Posy,Posx+width,Posy+height);
g3.drawLine(Posx+width,Posy,Posx,Posy+height);

}

}

public int getX()
{
return Posx;
}

public int getY()
{
return Posy;
}


public int getWidth()
{
return width;
}


public int getHeight()
{
return height;
}


public void setSelected()
{
selected=true;
}

@Override
public void mouseClicked(MouseEvent arg0)
{

}

@Override
public void mouseEntered(MouseEvent arg0)
{

}

public void mouseExited(MouseEvent arg0)
{

}
@Override
public void mousePressed(MouseEvent arg0)
{

}

@Override
public void mouseReleased(MouseEvent arg0)
{
selected=true;
repaint();

}
}

最佳答案

1) 您不尊重组件绘制链

根据 paintComponent(Graphics g) 的 java 文档:

 Further, if you do not invoker super's implementation you must honour the opaque property, that is if this component is opaque, you must completely fill in the background in a non-opaque color. If you do not honor the opaque property you will likely see visual artifacts.

2) super.paintComponent在大多数情况下,这是方法中的第一次调用。

3)但是还有更多,你两次转换为 Graphics2D ,这是不应该做的:

Graphics2D g2 = (Graphics2D) g;
...
Graphics2D g3=(Graphics2D)g;

省略g3不需要您已经将其转换为 Graphics2D对象

4) 另一个问题就在 sub 中类(class)。您可以在主代码中执行此操作:

inter.add(rect00);
inter.add(rect01);
...

但是在 inter这是 sub 实例的变量名称你只有的类(class):

@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}

因此,无论您添加多少个矩形,它都只会绘制单个图像!

也不要这样做 g2.drawLine(Posx, Posy, Posx + width, Posy + height);相当 g2.drawLine(0, 0, Posx + width, Posy + height);因为 JPanel 已添加到坐标 xy在其容器上,当您在 JPanel 上绘制时,我们希望从左上角(即 0,0)开始,更改该值将使图像在其容器上进一步向下移动

请参阅此处的固定代码:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Test {

private JFrame frame = new JFrame("");
private Rectangles rect00 = new Rectangles(0, 0, 129, 129);
private Rectangles rect01 = new Rectangles(136, 0, 129, 129);
private Rectangles rect02 = new Rectangles(268, 0, 129, 129);
private Rectangles rect10 = new Rectangles(0, 136, 129, 129);
private Rectangles rect11 = new Rectangles(134, 136, 129, 129);
private Rectangles rect12 = new Rectangles(269, 137, 129, 129);
private Rectangles rect20 = new Rectangles(0, 270, 129, 129);
private Rectangles rect21 = new Rectangles(136, 269, 129, 129);
private Rectangles rect22 = new Rectangles(269, 270, 129, 129);

public void Display() {
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLayout(null);
frame.setSize(600, 400);
sub inter = new sub();
inter.setLayout(null);
inter.setBounds(0, 0, 600, 400);
inter.setSize(600, 400);

rect00.setBounds(rect00.getX(), rect00.getY(), rect00.getWidth(), rect00.getHeight());
rect01.setBounds(rect01.getX(), rect01.getY(), rect01.getWidth(), rect01.getHeight());
rect02.setBounds(rect02.getX(), rect02.getY(), rect02.getWidth(), rect02.getHeight());
rect10.setBounds(rect10.getX(), rect10.getY(), rect10.getWidth(), rect10.getHeight());
rect11.setBounds(rect11.getX(), rect11.getY(), rect11.getWidth(), rect11.getHeight());
rect12.setBounds(rect12.getX(), rect12.getY(), rect12.getWidth(), rect12.getHeight());
rect20.setBounds(rect20.getX(), rect20.getY(), rect20.getWidth(), rect20.getHeight());
rect21.setBounds(rect21.getX(), rect21.getY(), rect21.getWidth(), rect21.getHeight());
rect22.setBounds(rect22.getX(), rect22.getY(), rect22.getWidth(), rect22.getHeight());
rect00.setOpaque(false);
rect01.setOpaque(false);
rect02.setOpaque(false);
rect10.setOpaque(false);
rect11.setOpaque(false);
rect12.setOpaque(false);
rect20.setOpaque(false);
rect21.setOpaque(false);
rect22.setOpaque(false);

inter.addPanel(rect00);
inter.addPanel(rect01);
inter.addPanel(rect02);
inter.addPanel(rect10);
inter.addPanel(rect11);
inter.addPanel(rect12);
inter.addPanel(rect20);
inter.addPanel(rect21);
inter.addPanel(rect22);
frame.add(inter);
frame.setResizable(false);
frame.setVisible(true);
}

public static void main(String args[]) {
new Test().Display();
}

private class sub extends JPanel {

private BufferedImage image;
private ArrayList<Rectangles> rects = new ArrayList<>();

public sub() {

try {
image = ImageIO.read(new File("c:/image.png"));

} catch (IOException e) {

e.printStackTrace();
}
}

@Override
public Dimension getPreferredSize() {
return (new Dimension(600, 400));
}

void addPanel(Rectangles r) {
rects.add(r);
add(r);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Rectangles r : rects) {
g.drawImage(image, r.getX(), r.getY(), null);
}
}
}
}

class Rectangles extends JPanel implements MouseListener {

private int Posx;
private int Posy;
private int width;
private int height;
private boolean selected = false;

public Rectangles(int Posx, int Posy, int width, int height) {
this.Posx = Posx;
this.Posy = Posy;
this.width = width;
this.height = height;
this.addMouseListener(this);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (selected == true) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(new Color(250, 235, 215));
g2.drawRect(0,0, width, height);
g2.setColor(new Color(0, 0, 0));
g2.setStroke(new BasicStroke(20));
g2.drawLine(0,0, width,height);
g2.drawLine(getWidth(),0, 0, height);
}

}

public int getX() {
return Posx;
}

public int getY() {
return Posy;
}

public int getWidth() {
return width;
}

public int getHeight() {
return height;
}

public void setSelected() {
selected = true;
}

@Override
public void mouseClicked(MouseEvent arg0) {
}

@Override
public void mouseEntered(MouseEvent arg0) {
}

public void mouseExited(MouseEvent arg0) {
}

@Override
public void mousePressed(MouseEvent arg0) {
}

@Override
public void mouseReleased(MouseEvent arg0) {
selected = true;
repaint();


}
}

其他一些提示:

  • 不要使用Absolute/Null布局。一个GridLayoutGridBagLayout会很好地满足你的需求。 (有关更多信息,请参阅here。)
  • 不要这样做JFrame#setSize(...);而是使用正确的LayoutManager并调用pack()JFrame在将其设置为可见之前。
  • 请勿调用setSize在您的Rectangles上实例,只需覆盖 getPreferredSize就像你对 sub 所做的那样面板??
  • 无需实现 MouseListener ,只需使用 MouseAdapter从而使您可以自由选择要重写的方法,而不仅仅是重写所有方法。
  • Have a read on Concurrency in Swing特别是Event-Dispatch-Thread

关于java - 图像在 swing 中的 MouseEvent 上无法正确显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17362396/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com