jpanel 在尝试重新绘制时被移位。

huangapple go评论113阅读模式
英文:

jpanel is shifted over when trying to repaint

问题

I am trying to use Swing components to manipulate the elements i am painting, with swing stuff in a jpanel on the right of the screen, and my painting stuff in a jpanel on the left of the screen. I have a JButton named btn1 which when pressed, repaints my jpanel with a black rectangle moved over ten pixels. However when i repaint the gui, the entire gui seems to be shifted about 5 px down and 5 px to the right when the black rect moves 10 px to the right. Then eventually, the black rect stops appearing after moving half way across the jpanel. Is there something i am doing wrong with using painting and swing stufff? i went through the custom painting documentation as well as this article article tut here but when i tried to implement these concepts myself, i still had weird problems like this.

Thanks for your help! i am new to this so any clarification / links to other resources would help me a lot. jpanel 在尝试重新绘制时被移位。

Main.java

package p3p4;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class Main extends JFrame{
	
	private GamePanel gPnl;
	
	private JPanel contentPane;

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Main frame = new Main();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});

	}
	
	public Main() {
		gPnl = new GamePanel();
		
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(0, 0, 500, 500);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout());
		
		JPanel rightPnl = new JPanel();
		rightPnl.setBackground(Color.LIGHT_GRAY);
		contentPane.add(rightPnl, BorderLayout.EAST);
		
		JButton btn1 = new JButton("THIS IS A BUTTON");
		rightPnl.add(btn1);
		
		btn1.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				gPnl.setX(gPnl.getX() + 10);
				gPnl.repaint();
			}
		});
		
		contentPane.add(gPnl, BorderLayout.CENTER);
		
		setContentPane(contentPane);
		
	}

}

GamePanel.java

package p3p4;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JPanel;

public class GamePanel extends JPanel{
	private int x = 0, y = 0;
	
	public GamePanel() {
		setBackground(Color.gray);
	}
	
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.fillRect(x,  y,  50,  50);
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}
}
英文:

I am trying to use Swing components to manipulate the elements i am painting, with swing stuff in a jpanel on the right of the screen, and my painting stuff in a jpanel on the left of the screen. I have a JButton named btn1 which when pressed, repaints my jpanel with a black rectangle moved over ten pixels. However when i repaint the gui, the entire gui seems to be shifted about 5 px down and 5 px to the right when the black rect moves 10 px to the right. Then eventually, the black rect stops appearing after moving half way across the jpanel. Is there something i am doing wrong with using painting and swing stufff? i went through the custom painting documentation as well as this article article tut here but when i tried to implement these concepts myself, i still had weird problems like this.

Thanks for your help! i am new to this so any clarification / links to other resources would help me a lot. jpanel 在尝试重新绘制时被移位。

Main.java

package p3p4;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main extends JFrame{
private GamePanel gPnl;
private JPanel contentPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Main() {
gPnl = new GamePanel();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(0, 0, 500, 500);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout());
JPanel rightPnl = new JPanel();
rightPnl.setBackground(Color.LIGHT_GRAY);
contentPane.add(rightPnl, BorderLayout.EAST);
JButton btn1 = new JButton("THIS IS A BUTTON");
rightPnl.add(btn1);
btn1.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
gPnl.setX(gPnl.getX() + 10);
gPnl.repaint();
}
});
//		JPanel centerPnl = new JPanel();
//		centerPnl.setBackground(Color.gray);
//		contentPane.add(centerPnl);
contentPane.add(gPnl, BorderLayout.CENTER);
setContentPane(contentPane);
}
}

GamePanel.java

package p3p4;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class GamePanel extends JPanel{
private int x = 0, y = 0;
public GamePanel() {
setBackground(Color.gray);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillRect(x,  y,  50,  50);
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}

答案1

得分: 2

你的问题在于方法 getXgetY 被 Swing 用于布局管理。因此,你实际上让 Swing 感到困惑。

你可以只需更改这些方法的名称,例如 getRectangleX 或类似的名称。

我现在更倾向于使用组合而不是继承。尽管你可能确实希望为布局等目的扩展 JPanel。

public class GamePanel{
    private int x = 0, y = 0;
    JPanel panel;
    public GamePanel() {
        panel =  new JPanel(){
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.fillRect(x,  y,  50,  50);
            }
        };
        panel.setBackground(Color.gray);
    }
    
    

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
    public JPanel getJPanel(){
        return panel;
    }
}

然后,当你添加它时,contentPane.add(gPnl.getJPanel(), BorderLayout.CENTER);

以类似的方式,我建议停止扩展 JFrame,而只是创建一个 JFrame 实例。

英文:

Your issue is the methods getX and getY are used by swing to manage layout. So you're essentially confusing swing.

You could just change the names of those methods, maybe getRectangleX or something along those lines.

I prefer to use composition over inheritance these days. Although, you might actually want to extend JPanel for layout purposes etc.

public class GamePanel{
private int x = 0, y = 0;
JPanel panel;
public GamePanel() {
panel =  new JPanel(){
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillRect(x,  y,  50,  50);
}
};
panel.setBackground(Color.gray);
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public JPanel getJPanel(){
return panel;
}
}

Then when you add it, contentPane.add(gPnl.getJPanel(), BorderLayout.CENTER);

In a similar manner, I would stop extending JFrame, and just create a JFrame instance.

huangapple
  • 本文由 发表于 2020年7月29日 14:00:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/63147207.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定