【问题标题】:Java - Swing library - JComboBox on top of JLabel with image - invisible JLabel [duplicate]Java - Swing 库 - 带有图像的 JLabel 顶部的 JComboBox - 不可见的 JLabel [重复]
【发布时间】:2018-07-07 00:47:03
【问题描述】:

这是我在这里的第一篇文章,请尽快。 我有一个带有 JLabel 的小 JFrame 窗口,其中图像作为所述 JFrame 的背景。 JFrame 也有 2 个 JButton。到目前为止,它运行良好,直到我决定添加 JComboBox。这个动作的结果是现在当我运行我的 JFrame 时它显示为空白,没有来自 JLabel 的背景图像,没有可见的 ComboBox,显示了 JButton。当我调整这个窗口的大小时,会出现 JLabel 背景图像,一切都很好,但应该没有调整大小。我在这里想念什么?我对 Swing 非常熟悉,并且正在为我的 java 类项目做“游戏”。这是截图和代码:

Running

After resizing

public class View_Startup extends JFrame {
    JLabel lBackground;
    JButton bStart,bExit;
    JComboBox cbResolutions;
    ImageIcon iBackground,iStart,iExit;
    Image icon;
    String resolutions[] = {"1280x720 HD","1366x768 WXGA","1600x900HD+","1920x1080 fullHD"};

    public View_Startup() {

        iBackground = new ImageIcon("xdddddddddd/resolution_background.jpg");
        iStart = new ImageIcon("xddddddddddd/iStart2.png");
        iExit = new ImageIcon("xdddddddddd/iExit2.png");    

        this.setSize(656,399);
        this.setTitle("xddddddddd");
        this.icon = Toolkit.getDefaultToolkit().getImage("C:xdddddddddd\\images.jpg"); 
        this.setIconImage(icon);
        this.setVisible(true);
        this.setLayout(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice defaultScreen = ge.getDefaultScreenDevice();
        Rectangle rect = defaultScreen.getDefaultConfiguration().getBounds();   
        int x=(int) rect.getMaxX();
        int y=(int) rect.getMaxY();
        this.setLocation(x/2-328,y/2-199);

        bStart = new JButton(iStart);
        bStart.setBounds(490,240,150,50);
        bStart.setOpaque(false);
        bStart.setContentAreaFilled(false);
        //bStart.setBorderPainted(false);
        add(bStart);

        bExit = new JButton(iExit);
        bExit.setBounds(490,300,150,50);
        bExit.setOpaque(false);
        bExit.setContentAreaFilled(false);
        //bExit.setBorderPainted(false);
        add(bExit);

        cbResolutions = new JComboBox(resolutions);
        cbResolutions.setBounds(490,180,150,50);
        add(cbResolutions);

        lBackground = new JLabel(iBackground);
        lBackground.setBounds(0,0,640,360);
        add(lBackground);




    }
   }

【问题讨论】:

  • 您遇到了一系列问题。 setLayout(null) 将是您的第一个。您的组件的 Z 排序将是您的第二个。 Have a look at this example 看看你应该如何使用JLabel 作为背景,以及为什么你不应该使用它以及更好的解决方案
  • 请查看编辑以回答

标签: java swing jlabel jcombobox invisible


【解决方案1】:

这里有几个问题:

  • 您正在使用空布局,这是一件危险且笨拙的事情
  • 您在 JFrame 上调用setVisible(true)完全构建它之前。仅在添加所有组件后调用。
  • 您将 JLabel 用作背景图像显示器,但没有将它也用作容纳组件的容器。

改为考虑

  • 使用 JPanel 的 paintComponent 方法显示背景图片
  • 将此 JPanel 添加到您的 JFrame 的 contentPane 或使其成为 contentPane
  • 给它一个不错的布局(如果需要,如果需要复杂的布局,可以添加嵌套的非透明 JPanel,每个 JPanel 都有自己的布局)
  • 在您的 JFrame 上调用 .setVisible(true) 添加所有组件。

类似这样的:

可以使用以下代码创建:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.*;

public class LayoutExample extends JPanel {
    private static final long serialVersionUID = 1L;
    private BufferedImage background;
    private JButton startButton = new JButton("Start");
    private JButton exitButton = new JButton("Exit");
    private JComboBox<String> combo = new JComboBox<>(new String[] {"1280 x 780 HD"});

    public LayoutExample(BufferedImage background) {
        this.background = background;

        JPanel rightLowerPanel = new JPanel(new GridLayout(0, 1, 5, 5));
        rightLowerPanel.setOpaque(false);
        rightLowerPanel.add(combo);
        rightLowerPanel.add(startButton);
        rightLowerPanel.add(exitButton);

        JPanel rightPanel = new JPanel(new BorderLayout());
        rightPanel.setOpaque(false);
        rightPanel.add(rightLowerPanel, BorderLayout.PAGE_END);

        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        setLayout(new BorderLayout());
        add(rightPanel, BorderLayout.LINE_END);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (background != null) {
            g.drawImage(background, 0, 0, this);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (background != null) {
            int w = background.getWidth();
            int h = background.getHeight();
            return new Dimension(w, h);
        }
        return super.getPreferredSize();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        String imgPath = "https://pbs.twimg.com/media/DRHUe_tV4AA96G4.jpg";
        BufferedImage img = null;
        try {
            URL imageUrl = new URL(imgPath);
            img = ImageIO.read(imageUrl);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
        LayoutExample mainPanel = new LayoutExample(img);
        JFrame frame = new JFrame("LayoutExample");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
}

【讨论】:

  • "添加所有组件后在您的 JFrame 上调用 .setVisible(true)。"这条线帮助了我。我确实意识到我的项目是完全业余的,例如由于 null 布局等事实,但我没有时间掌握它,我只会让它工作,在我的“daedline”之后,我会继续为自己工作并使它成为尽可能专业
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-19
  • 2023-03-25
  • 1970-01-01
相关资源
最近更新 更多