英文:
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.
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.
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
你的问题在于方法 getX
和 getY
被 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论