【问题标题】:JButton and JLabel dissappears when adding custom background添加自定义背景时,JButton 和 JLabel 消失
【发布时间】:2013-03-10 17:47:02
【问题描述】:

JButtonJLabel 在添加自定义背景时消失。我在我的程序中没有看到任何问题,但也许你们找到了解决方案!我想这只是我忘记的一件小事,但我想不出来。

代码如下:

GameWindow.java:

setContentPane(new StartImagePanel(RollrackLogo));
out.println("adding JLWelcome");
JLWelcome.setText("Welcome to Rollrack, " + namewindow.name);
add(JLWelcome);
JLWelcome.setVisible(true);
out.println("JLWelcome added");
out.println("adding JBRandom");
JBRandom.setText("Random");
add(JBRandom);
JBRandom.setVisible(true);
out.println("added JBRandom");

背景看起来很完美,但不是JButtonJLabel

代码到StartImagePanel.java:

public class StartImagePanel extends JComponent{
    private Image image;
    public StartImagePanel(Image image) {
        this.image = image;
    }
    @Override
    protected void paintComponent(Graphics g) {
        g.drawImage(image, 0, 0, null);
    }
}

【问题讨论】:

  • setContentPane(new StartImagePanel(.. 要尽快获得更好的帮助,请发布SSCCE。对于图像,只需在代码中创建一个,如this answer 所示。
  • 是否有机会很快看到 SSCCE,或者您是否打算浪费更多时间强迫人们猜测代码被破坏的原因?
  • 抱歉,我不知道该怎么做才能使它成为 SSCCE
  • @joapet99 你完全按照那个链接告诉你的去做。继续删除不必要的代码,直到只剩下有问题的、有缺陷的代码。然后发布简化的、错误的程序,这样其他人就不会浪费太多时间来查找错误。这次他们还是做了,但下次如果你能帮助别人做更少的工作就会有所帮助:)
  • @AndrewThompson 我添加的新编辑版本更好吗?

标签: java swing jframe jbutton jlabel


【解决方案1】:

您的按钮和标签将添加到您的 GameWindow 框架中,而它们应该添加到它的 contentPane 中,setContentPane(new StartImagePanel(RollrackLogo));。这就是它们不显示的原因,它们被添加到框架中。

创建StartImagePanel 的变量并将按钮和标签添加到其中,它们应该会显示出来。

StartImagePanel contentPanel = new StartImagePanel(RollrackLogo);
setContentPane(contentPanel);

...

out.println("adding JLWelcome");
JLWelcome.setText("Welcome to Rollrack, " + namewindow.name);
contentPanel.add(JLWelcome);
JLWelcome.setVisible(true);
out.println("JLWelcome added");
out.println("adding JBRandom");
JBRandom.setText("Random");
contentPanel.add(JBRandom);
JBRandom.setVisible(true);
out.println("added JBRandom");

回答争议

第一段中的主张是完全错误的。这是证明它的来源。

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

public class AddToCustomContentPane {

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                // the GUI as seen by the user (without frame)
                JPanel gui = new JPanel(new FlowLayout());
                gui.setBorder(new EmptyBorder(2, 3, 2, 3));
                gui.setBackground(Color.RED);

                JFrame f = new JFrame("Demo");
                f.setContentPane(gui);

                // Acid test.  Can we add buttons direct to the frame?
                f.add(new JButton("Button 1"));
                f.add(new JButton("Button 2"));

                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See http://stackoverflow.com/a/7143398/418556 for demo.
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }
}

在给出自定义面板代码后编辑

这是一个用于在黑色图像背景上显示按钮和标签的 sn-p,我删除了不需要的(侦听器)。

public static void main(String[] v) {

class StartImagePanel extends JPanel {
  private Image image;
  public StartImagePanel(Image image) {
      this.image = image;
  }
  @Override
  protected void paintComponent(Graphics g) {
    g.drawImage(image, 0, 0, null);
  }
}

class GameWindow extends JFrame{
  public GameWindow() {
    BufferedImage RollrackLogo;
    RollrackLogo = new BufferedImage(400,200,BufferedImage.TYPE_INT_RGB);
    final JButton JBRandom = new JButton();
    final JLabel JLWelcome = new JLabel();
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    StartImagePanel panel = new StartImagePanel(RollrackLogo);
    setContentPane(panel);
    setExtendedState(MAXIMIZED_BOTH);
    setVisible(true);
    JLWelcome.setText("Welcome to Rollrack");
    panel.add(JLWelcome);
    JLWelcome.setVisible(true);
    JBRandom.setText("Random");
    panel.add(JBRandom);
    JBRandom.setVisible(true);
  }
}

GameWindow window = new GameWindow();
window.pack();
window.setVisible(true);
}

【讨论】:

  • 我试过了,但它什么也没做......我想!如果背景不透明有什么要说的吗?
  • 查看回答争议之后的编辑,了解我为什么不同意您的技术观点。请注意,这可能最好在一个单独的问题上进行,但要简单地说。你错了。即使在设置了自定义内容窗格之后,如果我们将 add 组件添加到框架中,只要它具有适当的布局,它们最终也会出现在自定义内容窗格中。这导致我重复 OP..(这次声音稍微大一点)为了尽快获得更好的帮助,请发帖 SSCCE
  • 哦。如何创建 SSCCE?
  • @AndrewThompson 我同意你的观点,可以直接将它们添加到框架中,但是将它们添加到 contentPanel 确实有效。我不同意我错了,我给出了不同的解决方案。
  • @AndrewThompson 我没有尝试过你的解决方案,但我认为 setBackground 只能设置颜色而不是图像
【解决方案2】:

我宁愿使用JFrame 的实例,而不是像@Andrew Thompson 在另一个问题中建议的那样扩展它。
但是,如果要对其进行扩展,最好在构造函数中调用 super()

此外,我们可能需要知道您的 StartImagePanel 中发生了什么。
对我来说,这似乎是问题所在。

  1. 确保您的 GameWindowStartImagePanel 正确扩展它们的超类(调用 super();)。
  2. 确保您的StartImagePanel 具有正确的Layout
  3. 你设置你的框架可见之前添加你的组件。这也意味着您不需要JLWelcome.setVisible(true);
  4. 确保您的代码在 EDT 中执行(Event-Dispatch 线程)。

示例:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class GameWindow extends JFrame{
    BufferedImage rollrackLogo;
    JButton jbRandom;
    JLabel jlWelcome;

    public GameWindow() {
        super();
        jbRandom = new JButton("Random");
        jlWelcome = new JLabel("Welcome to Rollrack, " +
                namewindow.name);

        rollrackLogo = new BufferedImage(400, 200,
                BufferedImage.TYPE_INT_RGB);

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setContentPane(new StartImagePanel(rollrackLogo));

        // Add your components.
        add(jlWelcome);
        add(jbRandom);

        addKeyListener(new KeyListener() {
            @SuppressWarnings("static-access")
            @Override
            public void keyPressed(KeyEvent e) {
                if(e.getKeyCode() == e.VK_ESCAPE){
                    System.exit(7);
                }
            }

            @Override
            public void keyReleased(KeyEvent arg0) {}

            @Override
            public void keyTyped(KeyEvent arg0) {}
        });

        // Pack, or otherwise set fullscreen.
        pack();

        // Now, set frame visible.
        setVisible(true);
    }
}

编辑:现在您已经发布了StartImagePanel 的代码,我看到您正在扩展JComponent。按照我之前的建议(致电super),设置Layout,并改为扩展JPanel

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-14
    • 1970-01-01
    • 2016-02-04
    • 2015-01-14
    • 2012-03-23
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    相关资源
    最近更新 更多