Java 为什么我的paintComponent方法在JButton上绘制?我怎样才能使JPanel既有JButton又有图形?
我正在使用两个带有cardLayout的JPanel,它们都被添加到contentPane中。每个面板上都有一个JButton,可以切换到另一个面板,但在我的gridPanel上,它上面有图形,它们似乎覆盖了JButton,尽管当您单击它的位置时它仍然工作,但它是不可见的。如何获得一个既有图形又有JButton的JPanel?非常感谢你的帮助 主要类别:Java 为什么我的paintComponent方法在JButton上绘制?我怎样才能使JPanel既有JButton又有图形?,java,swing,Java,Swing,我正在使用两个带有cardLayout的JPanel,它们都被添加到contentPane中。每个面板上都有一个JButton,可以切换到另一个面板,但在我的gridPanel上,它上面有图形,它们似乎覆盖了JButton,尽管当您单击它的位置时它仍然工作,但它是不可见的。如何获得一个既有图形又有JButton的JPanel?非常感谢你的帮助 主要类别: public class ProjectileGame extends JPanel { private static JFra
public class ProjectileGame extends JPanel
{
private static JFrame frame = new JFrame("MyGame");
private static JPanel panelContent = new JPanel();
MenuPanel menuPanel = new MenuPanel();
GridPanel gridPanel = new GridPanel();
Ball ball = new Ball();
static CardLayout card = new CardLayout();
public ProjectileGame()
{
frame.setTitle("ProjectileGame");
frame.add(panelContent);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.pack();
frame.setSize(900, 700);
panelContent.setLayout(card);
panelContent.add(menuPanel, "1");
panelContent.add(gridPanel, "2");
card.show(panelContent, "1"); //First JPanel to be shown is that of the main menu.
frame.setVisible(true);
}
public static void menuButtonPressed()
{
card.show(panelContent, "2");
}
public static void gridButtonPressed()
{
card.show(panelContent, "1");
}
public static void main(String args[])
{
new ProjectileGame();
}
}
gridPanel类:
public class GridPanel extends JPanel implements ActionListener
{
private static final Graphics2D g2 = null;
Ball ball = new Ball();
JButton backToTheMenu = new JButton("To the Menu");
Timer timer = new Timer(14, this);
public GridPanel()
{
setOpaque(true);
setBackground(Color.WHITE);
setPreferredSize(new Dimension(900, 710));
add(ball);
add(backToTheMenu);
backToTheMenu.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
ProjectileGame.gridButtonPressed();
}
});
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d1 = (Graphics2D)g;
ball.paintComponent(g2d1);
g.setColor(Color.RED);
g.fillRect(0, 649, 30, 33);
g.setColor(Color.BLUE);
for (int i = 0; i < 35; i++)
{
g.setColor(Color.GREEN);
g.drawLine(0, (20+(30*i)), 900, (20+(30*i)));
g.drawLine((30+(30*i)), 0, (30+(30*i)), 1000);
}
g.setColor(Color.RED);
g.drawLine(0, 650, 900, 650);
g.drawLine(30, 0, 30, 1000);
g.setColor(Color.BLACK);
g2d1.drawString("X Displacement (metres)", 400, 667);
AffineTransform at = new AffineTransform();
at.setToRotation(Math.PI / -1.97);
g2d1.setTransform(at);
g2d1.drawString("Y Displacement (metres)", -380, 8);
}
public void actionPerformed(ActionEvent e)
{
ball.ballPhysics();
repaint();
timer.restart();
}
}
公共类GridPanel扩展JPanel实现ActionListener
{
专用静态最终图形2d g2=null;
球=新球();
JButton backToTheMenu=新JButton(“到菜单”);
计时器=新的计时器(14,此);
公众谘询委员会(
{
set不透明(true);
挫折地面(颜色:白色);
设置首选尺寸(新尺寸(900710));
添加(球);
添加(返回菜单);
backToTheMenu.addActionListener(新建ActionListener())
{
已执行的公共无效操作(操作事件arg0)
{
ProjectleName.gridButtonPressed();
}
});
}
公共组件(图形g)
{
超级组件(g);
Graphics2D g2d1=(Graphics2D)g;
钢球.油漆组件(g2d1);
g、 setColor(Color.RED);
g、 fillRect(0649,30,33);
g、 setColor(Color.BLUE);
对于(int i=0;i<35;i++)
{
g、 setColor(Color.GREEN);
g、 抽绳(0,(20+(30*i)),900,(20+(30*i));
g、 抽绳((30+(30*i)),0,(30+(30*i)),1000);
}
g、 setColor(Color.RED);
g、 抽绳(0650900650);
g、 抽绳(30,0,30,1000);
g、 设置颜色(颜色为黑色);
g2d1.抽绳(“X位移(米)”,400667;
AffineTransform at=新的AffineTransform();
at.设置旋转(Math.PI/-1.97);
g2d1.setTransform(at);
g2d1.抽绳(“Y位移(米)”,-380,8);
}
已执行的公共无效操作(操作事件e)
{
ball.ball物理学();
重新油漆();
timer.restart();
}
}
不要将变换和旋转等添加到传递给paintComponent()
方法的Graphics
对象中。绘制时,此图形对象将传递给所有其他组件
相反,您应该创建一个临时的图形对象来进行绘制:
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g.create();
// do custom painting
g2d.dispose();
}
现在,您需要能够将多个组件添加到面板中。请注意,您始终可以将另一个面板添加到面板中,以便可以有无限嵌套级别的面板。因此,您可以轻松地为您的CardLayout创建两张“卡片”,每张卡片上都添加了不同数量的组件
基本情况如下:
JButton button1 = new JButton("Back to Card2")
JPanel gridPanel = new GridPanel();
JPanel card1 = new JPanel(new BorderLayout());
card1.add(button1, BorderLayout.PAGE_START);
card1.add(gridPanel, BorderLayout.CENTER);
JButton button2 = new JButton("Back to Card1");
JPanel card2 = new JPanel();
card2.add(button2);
JPanel cardPanel = new JPanel();
cardPanel.setLayout( new CardLayout(...) );
cardPanel.add(card1, ...);
cardPanel.add(card2, ...);
frame.add(cardPanel);
不要向传递给paintComponent()
方法的Graphics
对象添加变换和旋转等。绘制时,此图形对象将传递给所有其他组件
相反,您应该创建一个临时的图形对象来进行绘制:
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g.create();
// do custom painting
g2d.dispose();
}
现在,您需要能够将多个组件添加到面板中。请注意,您始终可以将另一个面板添加到面板中,以便可以有无限嵌套级别的面板。因此,您可以轻松地为您的CardLayout创建两张“卡片”,每张卡片上都添加了不同数量的组件
基本情况如下:
JButton button1 = new JButton("Back to Card2")
JPanel gridPanel = new GridPanel();
JPanel card1 = new JPanel(new BorderLayout());
card1.add(button1, BorderLayout.PAGE_START);
card1.add(gridPanel, BorderLayout.CENTER);
JButton button2 = new JButton("Back to Card1");
JPanel card2 = new JPanel();
card2.add(button2);
JPanel cardPanel = new JPanel();
cardPanel.setLayout( new CardLayout(...) );
cardPanel.add(card1, ...);
cardPanel.add(card2, ...);
frame.add(cardPanel);
什么是“球”?如果它是Swing组件,则不应直接调用其paintComponent方法。另外,请张贴一个有效的。球是我创建的对象。我现在如何发布一个最小的、完整的和可验证的示例?我如何获得一个既有图形又有JButton的JPanel?
-通常你不会。我猜你想让一个“球”物体在屏幕上移动。因此,您通常会使用一个面板来制作球的动画。如果ball是一个Swing组件,那么您可以在面板上使用空布局,然后使用setLocation()
方法移动球。因此,您将有一个父面板,可能使用了BorderLayout。您可以将JButton添加到BorderLayout.PAGE_START,将animation面板添加到BorderLayout.CENTER。关于MCVE
,您的问题是关于带有图形和组件的面板。所以你只需要一个JFrame和一个panel。。然后在面板上添加一个按钮并重写paintComponent()方法,只需在面板上绘制一个字符串。现在您有了一个带有图形和按钮的面板。所以整个MCVE
大约需要20行代码。关于MCVE,我明白了,谢谢。作为对camickr的回复,您知道我如何做到每个面板都有自己的JButton吗?如果我不想有一个带有永久按钮的主屏幕,而按钮下面的面板却在不断变化,那该怎么办?什么是“球”?如果它是Swing组件,则不应直接调用其paintComponent方法。另外,请张贴一个有效的。球是我创建的对象。我现在如何发布一个最小的、完整的和可验证的示例?我如何获得一个既有图形又有JButton的JPanel?
-通常你不会。我猜你想让一个“球”物体在屏幕上移动。因此,您通常会使用一个面板来制作球的动画。如果ball是一个Swing组件,那么您可以在面板上使用空布局,然后使用setLocation()
方法移动球。因此,您将有一个父面板,可能使用了BorderLayout。您可以将JButton添加到BorderLayout.PAGE_START,将animation面板添加到BorderLayout.CENTER。关于MCVE
,您的问题是关于带有图形和组件的面板。所以你只需要一个JFrame和一个panel。。然后将一个按钮添加到面板并覆盖