繁体   English   中英

Java Swing-在光标悬停在按钮上方之前,按钮不会显示

[英]Java Swing - Buttons won't show up until cursor hovers over it

以前,我只有1个具有鼠标事件的画布,并且“按钮”只是当光标在其框内单击时执行一个方法的坐标。

然后我决定不这样做,而只是用ImageIcons实现了JButtons,但是这样做使得我不能将JButtons放在Canvas的顶部,所以我四处闲逛,看到一些主题告诉我使用JLabel和ImageIcon填满整个屏幕。 (此外,我尝试使用JPanel&PaintComponent而不是JLabel&ImageIcon进行相同的操作)

我在Reddit上发布了此内容,但显然它对其他人有用,而且我找不到为什么对我不起作用的原因。 这是我从实际项目中摘录的可行代码:

package hoverProblem;

import java.awt.Canvas;

public class ClientReddit extends Canvas {

    public static void main(String args[]) {
        ClientReddit client = new ClientReddit();
        ClientWindow window = new ClientWindow();
    }
}

这是窗口:

package hoverProblem;

import java.awt.Dimension;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class ClientWindow {

    // Attributes
    private JFrame frame;
    private static Dimension dm = new Dimension();
    private String title;
    private final Dimension BUTTONSIZE = new Dimension(100, 50);
    private final Dimension MENUSIZE = new Dimension(600, 500);

    // Main Menu
    private JLabel mainMenuBG = new JLabel(new ImageIcon("graphics/gui/MainMenu.png"));

    private ImageIcon loginButtonImg = new ImageIcon("graphics/gui/buttons/LoginButton.png");
    private ImageIcon signUpButtonImg = new ImageIcon("graphics/gui/buttons/SignUpButton.png");
    private ImageIcon optionsButtonImg = new ImageIcon("graphics/gui/buttons/OptionsButton.png");
    private ImageIcon updateButtonImg = new ImageIcon("graphics/gui/buttons/UpdateButton.png");
    private ImageIcon creditsButtonImg = new ImageIcon("graphics/gui/buttons/CreditsButton.png");

    private JButton loginButton = new JButton(loginButtonImg);
    private JButton signUpButton = new JButton(signUpButtonImg);
    private JButton optionsButton = new JButton(optionsButtonImg);
    private JButton updateButton = new JButton(updateButtonImg);
    private JButton creditsButton = new JButton(creditsButtonImg);



    // Borders count for some reason
    private final int hOffset = 29, wOffset = 6;

    public ClientWindow() {
        frame = new JFrame();
        frame.setLayout(null);

        title = "Reddit";
        dm.setSize(600 + wOffset, 500 + hOffset);

        loginButton.setSize(BUTTONSIZE);
        signUpButton.setSize(BUTTONSIZE);
        optionsButton.setSize(BUTTONSIZE);
        updateButton.setSize(BUTTONSIZE);
        creditsButton.setSize(BUTTONSIZE);

        loginButton.setLocation(20, 430);
        signUpButton.setLocation(135, 430);
        optionsButton.setLocation(250, 430);
        updateButton.setLocation(365, 430);
        creditsButton.setLocation(480, 430);

        mainMenuBG.setSize(MENUSIZE);

        frame.setTitle(title);
        frame.setSize(dm);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setAlwaysOnTop(true);

        frame.add(mainMenuBG);
        frame.add(loginButton);
        frame.add(signUpButton);
        frame.add(optionsButton);
        frame.add(updateButton);
        frame.add(creditsButton);

        frame.setVisible(true);
    }
}    

您正在错误地覆盖和放置对象。 如果要使用JLabel作为背景图像,并希望在其上放置组件,则将实际添加的组件提供给JLabel,而不是JFrame,然后最后仅将JLabel添加到JFrame。 您的另一个选择是在JPanel的paintComponent方法中绘制背景图像,然后将所有组件添加到其中。

其他问题包括您使用空布局以及设置大小和位置。 尽管null布局和setBounds()似乎是Swing新手喜欢创建复杂GUI的最简单和最佳方法,但您创建的Swing GUI越多,使用它们时将遇到的困难就越大。 当GUI调整大小时,它们不会调整组件的大小;它们是要增强或维护的皇家女巫;放置在滚动窗格中时,它们会完全失败;在所有平台或与原始分辨率不同的屏幕分辨率下查看时,它们看起来都是令人毛骨悚然的。

例如:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class ClientPanel extends JPanel {
    private static final String COMMON = "https://upload.wikimedia.org/wikipedia/commons/";
    private static final String BACKGROUND = "0/0e/Farol_-_Prieto_Coussent.jpg";
    private static final String[] BTN_PATHS = {
            "thumb/0/09/HanDev.jpg/100px-HanDev.jpg",
            "thumb/3/3f/SugababesInEntirety.png/100px-SugababesInEntirety.png",
            "thumb/c/c5/GeorgesDanton.jpg/100px-GeorgesDanton.jpg",
            "thumb/5/54/Written_on_the_wind8.jpg/100px-Written_on_the_wind8.jpg",
            "thumb/6/6d/COP_20000_anverso_%281996-2016%29.jpg/100px-COP_20000_anverso_%281996-2016%29.jpg"
    };
    private Image background = null;

    public ClientPanel() throws IOException {
        URL imgUrl = new URL(COMMON + BACKGROUND);
        background = ImageIO.read(imgUrl);

        JPanel btnPanel = new JPanel(new GridLayout(1, 0, 15, 0));
        btnPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        btnPanel.setOpaque(false);
        for (String btnPath : BTN_PATHS) {
            String imgPath = COMMON + btnPath;
            imgUrl = new URL(imgPath);
            Image img = ImageIO.read(imgUrl);
            Icon icon = new ImageIcon(img);
            JButton btn = new JButton(icon);
            JPanel wrapperPanel = new JPanel();
            wrapperPanel.setOpaque(false);
            wrapperPanel.add(btn);
            btnPanel.add(wrapperPanel);
        }
        setLayout(new BorderLayout());
        add(btnPanel, BorderLayout.PAGE_END);
    }

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

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet() || background == null) {
            return super.getPreferredSize();
        }
        int prefW = background.getWidth(this);
        int prefH = background.getHeight(this);
        return new Dimension(prefW, prefH);
    }


    private static void createAndShowGui() {
        ClientPanel mainPanel = null;
        try {
            mainPanel = new ClientPanel();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }

        JFrame frame = new JFrame("Client");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM