Reputation: 39
Previously I had just 1 canvas with mouse events, and the "buttons" were just coordinates that executed a method when the cursor clicked within its box.
Then I decided against doing that, and just implemented JButtons with ImageIcons, but that made it so that I couldn't put the JButtons on top of my Canvas, so instead I poked around and saw some topics telling me to use a JLabel & ImageIcon that fills up the whole screen. (In addition, I tried doing the same thing with a JPanel & PaintComponent instead of a JLabel & ImageIcon)
I posted this on Reddit but apparently it worked for other people, and I couldn't find out why it didn't work for me. Here is workable code that I snipped off from my actual project:
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();
}
}
And here is the Window:
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);
}
}
Upvotes: 1
Views: 686
Reputation: 285403
You're overlaying and placing objects incorrectly. If you're going to use the JLabel as a background image and want to place components over it, then give the actually add components to the JLabel, not to the JFrame, and then finally add only the JLabel to the JFrame. Your other option is to draw the background image in a JPanel's paintComponent method and then add all your components to it.
Other problems include your use of null layout and set size and position. While null layouts and setBounds()
might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
For example:
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());
}
}
Upvotes: 4