透明面板

时间:2016-05-22 14:18:04

标签: java swing jframe jpanel

我正在制作一个游戏,用户必须绘制线条以使球弹回目标。我无法让球和线同时出现,我只能出现一个或另一个。在我看来,面板相互阻挡,即使我让它们透明。我希望他们两个出现在同一帧上。截至本文,线条面板覆盖球面板。

import javax.swing.Timer;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.Graphics;
import java.awt.Color;
import javax.swing.JPanel;
import javax.swing.JFrame;

public class Game
{
  public static void main(String args[]) throws Exception 
  {
        JFrame f = new JFrame("Let's Play");
        f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        f.setSize(1280, 720);
        f.setLocation(300, 300);
        f.setResizable(false);

        //this part draws a ball that bounces around the screen
        BallPanel ballPanel = new BallPanel()
        {
           // draw rectangles and arcs

           public void paintComponent(Graphics g)
           {
            super.paintComponent(g); // call superclass's paintComponent 
            g.setColor(Color.red);

            // check for boundaries
            if (x < radius)         dx = Math.abs(dx);
            if (x > getWidth() - radius)    dx = -Math.abs(dx);
            if (y < radius)         dy = Math.abs(dy);
            if (y > getHeight() - radius)   dy = -Math.abs(dy);

            // adjust ball position
            x += dx;
            y += dy;
            g.fillOval(x - radius, y - radius, radius*2, radius*2);
           }

        };
        ballPanel.setOpaque(false);
        f.add(ballPanel);

        //this part allows you to draw lines on the frame with your mouse
        JPanel lineP = new JPanel()
        {
            Point pointStart = null;
            Point pointEnd   = null;

            {
                addMouseListener(new MouseAdapter() 
                {
                    public void mousePressed(MouseEvent me) 
                    {
                        pointStart = me.getPoint();
                    }

                    public void mouseReleased(MouseEvent me) 
                    {
                        pointStart = null;
                    }
                });
                addMouseMotionListener(new MouseMotionAdapter() 
                {
                    public void mouseMoved(MouseEvent me) 
                    {
                        pointEnd = me.getPoint();
                    }

                    public void mouseDragged(MouseEvent me) 
                    {
                        pointEnd = me.getPoint();
                        repaint();
                    }
                });
            }
            public void paint(Graphics dline) 
            {
              super.paint(dline);
                if (pointStart != null) 
                {
                    dline.setColor(Color.RED);
                    dline.drawLine(pointStart.x, pointStart.y, pointEnd.x, pointEnd.y);

              }
            }
        };
        lineP.setOpaque(false); //attempted to enable to see ball panel here
        f.add(lineP);
        f.setVisible(true); 
    }
}

class BallPanel extends JPanel implements ActionListener
{
private int delay = 10;
protected Timer timer;

public int x = 30;      // x position
public int y = 30;      // y position
public int radius = 15; // ball radius

public int dx = 10;     // increment amount (x coord)
public int dy = 10;     // increment amount (y coord)

public BallPanel()
{
     timer = new Timer(delay, this);
    timer.start();      // start the timer
}

public void actionPerformed(ActionEvent e)
// will run when the timer fires
{
     repaint();
   }


}

1 个答案:

答案 0 :(得分:2)

你有几个问题,但主要的问题是你过度使用了GUI组件。您应该只有一个用于绘图的单个组件JPanel,一个DrawingPanel,而不是一个球面板和一个线条面板。而Ball和Line应该是逻辑类,而不是GUI类,它们的显示应该在同一个DrawingPanel中。

其他问题包括:

  • 代码太多的主要方法。大多数代码应该卸载到它所属的OOP世界中。
  • GUI组件类,也实现了侦听器接口。这给了班级太多的责任,使调试和升级变得困难。将这些问题分开。
  • 您的一个类会覆盖paint方法,应该避免这种情况。覆盖paintComponent。
  • 覆盖paintComponent的另一个类在paintComponent中具有程序逻辑,应该避免这种情况,因为您对何时或是否调用此方法的控制有限。从该类获取逻辑并进入鼠标侦听器代码或游戏循环代码(Swing Timer)。