【问题标题】:JButton only show up on mouseoverJButton 仅在鼠标悬停时显示
【发布时间】:2013-01-04 01:43:08
【问题描述】:

我正在开发一款“Tron”游戏,对于我的菜单,我使用了一种绘制方法来绘制菜单的背景。一切都很好,除了 3 个 JButtons “隐藏”在背景后面,直到我将鼠标放在它上面然后它出现。如果有办法让按钮保持可见,我将不胜感激!

我的代码:

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class Menu extends JFrame {
    private static final long serialVersionUID = 1L;
    String name;
    Image bk;
    public Menu() {
        super("TRON");
        // Set the size of window
        setSize(800, 800);
        // Set the default operation for the window
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        // Set a background
        ImageIcon ibk = new ImageIcon("background.jpg");
        bk = ibk.getImage();
        // Set a new panel
        JPanel p = new JPanel(new GridBagLayout());
        // Make buttons!
        JButton b = new JButton("Play!");
        JButton b2 = new JButton("High Scores");
        JButton b3 = new JButton("Exit");
        b.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new GameFrame();
            }
        });
        b2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new hsview();
            }
        });
        b3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        // Set the GridBagConstraints to organize the layout
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets (15, 15, 15, 15);
        // Use gbc to space out each button
        gbc.gridx = (0);
        gbc.gridy = (0);
        // Add them to the panel then to JFrame
        p.add(b, gbc);
        gbc.gridx = (0);
        gbc.gridy = (1);
        p.add(b2, gbc);
        gbc.gridx = (0);
        gbc.gridy = (2);
        p.add(b3, gbc);
        // Add to the frame at the bottom
        add(p, BorderLayout.SOUTH);
    }
    // Background stuff
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.drawImage(bk, 0, 0, null);
    }
}

【问题讨论】:

标签: java image swing background jbutton


【解决方案1】:

Swing 使用“分层”概念进行绘画...

paint 调用 paintComponentpaintBorderpaintChildren。通过覆盖paint 并且未能调用super.paint,您阻止了组件绘制它的各个层。

在 Swing 中,最好使用 paintComponent 来提供自定义绘制,这允许您在可能添加到组件的任何其他组件下方绘制。

public class TestPaint01 {

  public static void main(String[] args) {
    new TestPaint01();
  }

  public TestPaint01() {
    EventQueue.invokeLater(new Runnable() {
      @Override
      public void run() {
        try {
          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception ex) {
        }

        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new TestPane());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

      }
    });
  }

  public class TestPane extends JPanel {

    private Image backgroundImage;

    public TestPane() {
      try {
        BufferedImage background = ImageIO.read(new File("/path/to/image.jpg"));
        //backgroundImage = background.getScaledInstance(-1, background.getHeight() / 4, Image.SCALE_SMOOTH);
        backgroundImage = background;
      } catch (IOException ex) {
        ex.printStackTrace();
      }
      setLayout(new GridBagLayout());
      add(new JButton("Hello"));
    }

    @Override
    public Dimension getPreferredSize() {
      return backgroundImage == null ? super.getPreferredSize() : new Dimension(backgroundImage.getWidth(this), backgroundImage.getHeight(this));
    }

    @Override
    protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      int x = (getWidth() - backgroundImage.getWidth(this)) / 2;
      int y = (getHeight() - backgroundImage.getHeight(this)) / 2;
      g.drawImage(backgroundImage, x, y, this);
    }

  }

}

您可能会发现 A Closer look at the Paint MechanismPainting in AWT and Swing 信息丰富。

【讨论】:

    【解决方案2】:

    我认为你需要为你的框架调用 pack() 方法和这个显示。我认为 pack() 方法设置你的组件显示。

    以下是 JFrame 教程中列出的步骤。

    How to Make Frames

    //1. Create the frame.
    JFrame frame = new JFrame("FrameDemo");
    
    //2. Optional: What happens when the frame closes?
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    //3. Create components and put them in the frame.
    //...create emptyLabel...
    frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
    
    //4. Size the frame.
    frame.pack();
    
    //5. Show it.
    frame.setVisible(true);
    

    【讨论】:

    • 我认为 OP 需要停止使用paintpackJFrame 用于确定子组件的首选大小,因此您无需调用setSize "使此窗口的大小调整为适合其首选大小和布局子组件”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 2021-02-19
    • 1970-01-01
    • 1970-01-01
    • 2016-05-17
    • 2012-04-18
    相关资源
    最近更新 更多