在绘画上分层按钮

时间:2013-02-14 01:30:06

标签: java swing

有一个窗口,我想在其中放置一个按钮,然后在其下面绘制整个区域。换句话说,按钮应该覆盖一块画。

import java.awt.*;
import javax.swing.*;

class Window
{
    private JFrame frame;
    private JButton launchButton;
    private JPanel pnllaunchButton;
    private JPanel paintingPanel;
    //width and height of client area
    private Rectangle dim;

    //w,h - width and height of the whole window 
    public Window(String title,int w,int h)
    {  
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(0,0);
        frame.setMinimumSize( new Dimension(110,110));
        frame.setSize(w, h);
        frame.setVisible(true);
        frame.setTitle(title);           
        frame.setResizable(false);

        addLaunchButton();
    }        

    private void addLaunchButton()
    {   
        pnllaunchButton = new JPanel();
        launchButton = new JButton("Plot!");
        dim = new Rectangle();

        frame.getContentPane().getBounds(dim);

        pnllaunchButton.setBounds(dim.width-100,dim.height-25,100,25);

        launchButton.setBounds(dim.width-100,dim.height-25,100,25);

        pnllaunchButton.setLayout(null);

        pnllaunchButton.add(launchButton);

        frame.getContentPane().add(pnllaunchButton);          
        frame.getContentPane().setComponentZOrder(pnllaunchButton, new Integer(2));    
    }    
    public void drawCoordinateSystem()
    {      
        paintingPanel = new JPanel();

        paintingPanel.add(new CoordinateSystem());

        frame.getContentPane().add(paintingPanel);
        frame.getContentPane().setComponentZOrder(paintingPanel,new Integer(3));

    }

 }   

class CoordinateSystem extends JPanel 
{
    @Override 
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Dimension size = this.getSize();

        g.setColor(Color.BLACK);
        g.drawLine(0,size.height/2,size.width, size.height/2);

        g.drawLine(size.width/2, 0, size.width/2, size.height);

    }
}        

public class GC {

    public static void main(String[] args) 
    {
        Window h = new Window("GC",800,600);        
        h.drawCoordinateSystem();    
    }
}

此代码不符合规范。程序创建一个空窗口并输出:

 run:
Exception in thread "main" java.lang.IllegalArgumentException: illegal component position
    at java.awt.Container.checkAdding(Container.java:504)
    at java.awt.Container.setComponentZOrder(Container.java:759)
    at Window.addLaunchButton(Window.java:46)
    at Window.<init>(Window.java:26)
    at GC.main(GC.java:10)
你可以指出我的错误吗?似乎没有在javadoc中精确描述setComponentZOrder()方法。

2 个答案:

答案 0 :(得分:5)

  • 重命名你的班级。 Window类已经是标准核心Java库的一部分,您的类名可能会导致当前或未来的问题。
  • 请注意我们的布局和setBounds(...)。这很糟糕,糟糕,糟糕,并且很难维护或升级您的应用程序。相反,请了解并使用布局管理器。
  • 考虑将一个JLabel作为contentPane,使其不透明,给它一个布局和一个ImageIcon,然后将组件添加到它。
  • ImageIcon可以保存带网格的BufferedImage。

例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.*;

public class MyWindow {
   private static final int PREF_W = 800;
   private static final int PREF_H = 600;
   private static final Color COLOR0 = Color.red;
   private static final Color COLOR1 = Color.blue;
   private static final float COLOR_REPEAT_DIST = 30f;
   private JLabel backGroundLabel = new JLabel();

   public MyWindow() {
      backGroundLabel.setOpaque(true);
      backGroundLabel.setLayout(new BorderLayout());
      int eb = 15;
      BufferedImage bkgrndImg = createBkgrndImage();
      ImageIcon icon = new ImageIcon(bkgrndImg);
      backGroundLabel.setIcon(icon);

      JPanel bottomPanel = new JPanel();
      bottomPanel.setLayout(new FlowLayout(SwingConstants.RIGHT, eb, eb));
      bottomPanel.setOpaque(false);
      bottomPanel.add(new JButton("Plot"));
      backGroundLabel.add(bottomPanel, BorderLayout.PAGE_END);
   }

   private BufferedImage createBkgrndImage() {
      BufferedImage img = new BufferedImage(PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = img.createGraphics();
      g2.setPaint(new GradientPaint(0f, 0f, COLOR0, COLOR_REPEAT_DIST, COLOR_REPEAT_DIST, COLOR1, true));
      g2.fillRect(0, 0, PREF_W, PREF_H);
      g2.dispose();
      return img;
   }

   public JComponent getMainPane() {
      return backGroundLabel;
   }

   private static void createAndShowGui() {
      MyWindow mainPanel = new MyWindow();

      JFrame frame = new JFrame("MyWindow");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel.getMainPane());
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

看起来如此:
enter image description here

答案 1 :(得分:1)

int而不是Integer传递给setComponentZOrder方法。

private void addLaunchButton()
{   
    pnllaunchButton = new JPanel();
    launchButton = new JButton("Plot!");
    dim = new Rectangle();

    frame.getContentPane().getBounds(dim);

    pnllaunchButton.setBounds(dim.width-100,dim.height-25,100,25);

    launchButton.setBounds(dim.width-100,dim.height-25,100,25);

    pnllaunchButton.setLayout(null);


    pnllaunchButton.add(launchButton);

    frame.getContentPane().add(pnllaunchButton);    
    frame.getContentPane().setComponentZOrder(pnllaunchButton, 2);    
}