Create a form with a background Image (JLayeredPane)(创建带有背景图像的表单 (JLayeredPane))
问题描述
我一直在努力做一些我认为很简单的事情:
I've been struggling to do something I guess pretty simple :
我想创建一个带有背景图像的表单 (JTextField).为了使表单不覆盖背景图像,我使用了 JLayeredPane.我一直在尝试不同的东西,但似乎没有任何效果:出于某种原因,我要么只显示背景,要么只显示 JTextField,但从不同时显示两者.我的目标是拥有一个永不改变的背景图像,并在其上使用我的按钮/文本字段.
I want to create a form (JTextField) with a background image. In order for the form not to cover the background Image, I'm using a JLayeredPane. I've been trying different stuff, nothing seems to work : for some reason, I'm either displaying only the background, or only the JTextField, but never both. My goal would be to have a background image that never changes, and just use my buttons / textfields on top of it.
package gestion;
import java.awt.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class Main extends JFrame{
JLayeredPane layeredPane;
JPanel board;
JPanel background;
public Main(){
super("Test");
background = new JPanel();
layeredPane = new JLayeredPane();
board = new JPanel();
// Creating frame with LayeredPane
Dimension boardSize = new Dimension(1280, 1024);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setSize(boardSize.width, boardSize.height);
this.setVisible(true);
this.setLocationRelativeTo(null);
layeredPane.setPreferredSize( boardSize );
this.add(layeredPane);
// Add a background to the Layered Pane
JLabel picLabel = new JLabel(new ImageIcon("background.jpg"));
background.add(picLabel);
background.setPreferredSize(boardSize);
background.setBounds(0,0,boardSize.width, boardSize.height);
layeredPane.add(background, JLayeredPane.DEFAULT_LAYER);
// Add a JTextField
final JTextField jtf = new JTextField("Default Value");
Font police = new Font("Arial", Font.BOLD, 14);
jtf.setFont(police);
jtf.setPreferredSize(new Dimension(600, 800));
background.setBounds(0,0,boardSize.width, boardSize.height);
jtf.setForeground(Color.BLUE);
board.add(jtf);
layeredPane.add(board, JLayeredPane.PALETTE_LAYER);
}
public static void main(String[] args)
{
new Main();
}
}
似乎只出现了图像,并且由于某种原因(我最好的选择是黑魔法)JTextField 不存在.任何想法或帮助将不胜感激!谢谢!
Only the image seems to appear, and for some reason (My best bet is dark magic) the JTextField is not there. Any ideas or help would be greatly appreciated ! Thank you !
推荐答案
任何时候你依赖任何使用 null
布局的东西(比如 JLayeredPane
),你都会运行进入问题.
Any time you rely on anything that uses a null
layout (like JLayeredPane
), you will run into issues.
你应该使用类似...
board.setBounds(new Rectangle(new Point(0, 0), board.getPreferredSize()));
layeredPane.add(board, JLayeredPane.PALETTE_LAYER);
设置board
的大小和位置.
null
布局还有很多其他问题,这些问题只会让它们在代码中完全痛苦,最终浪费的时间比节省的时间多...
There are also a rafter of other issues with null
layouts which just make them a complete pain in the code and end up wasting more time than they save...
坦率地说,一个更简单、更实用的解决方案是创建一个可以为您绘制背景图像的自定义组件,这样您就可以使用您需要的任何布局管理器,而不会遇到这些问题.在任何人跳到我身上之前,使用你可以"使用带有 JLayeredPane
的布局管理器,但这会引入更多问题,必须让组件重叠,以便背景层可以充当背景...只是更多的混乱
Frankly, a simpler and more usable solution would be to create a custom component which could paint the background image for you, this way, you can use what ever layout manager(s) you need and not suffer from these issues. Before anyone jumps all over me, use a you "can" use a layout manager with JLayeredPane
, but this then introduces more issues with having to get components to overlap so the background layer can act as the background...just more of a mess
另外,在有人跳过我之前,您可以使用 JLabel
作为背景组件,在其上设置布局管理器并将您的组件添加到其中,但 JLabel
code> 不会根据它包含的子组件计算它所需的大小,而是使用 icon
和 text
属性.如果您的背景图像足够大,这可能不是问题,但似乎总是一个等待突破的弱点.
Also, before anyone jumps all over me, you could use a JLabel
as the background component, setting a layout manager on it and adding your components to it, but the JLabel
doesn't calculate it's required size based on the child components it contains, but instead, uses the icon
and text
properties. This might not be an issue if your background image is sufficiently big enough, but always seems like a weak point waiting to break.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
BackgroundPane bgPane = new BackgroundPane();
bgPane.setLayout(new GridBagLayout());
add(bgPane);
try {
BufferedImage bg = ImageIO.read(new File("C:\Users\shane\Dropbox\MegaTokyo\thumnails\megatokyo_omnibus_1_3_cover_by_fredrin-d4oupef.jpg"));
bgPane.setBackgroundImage(bg);
} catch (IOException ex) {
ex.printStackTrace();
}
JLabel show = new JLabel("Bananas are yellow");
show.setOpaque(true);
show.setForeground(Color.RED);
show.setBackground(Color.YELLOW);
show.setBorder(new EmptyBorder(20, 20, 20, 20));
bgPane.add(show);
}
}
public class BackgroundPane extends JPanel {
private BufferedImage img;
@Override
public Dimension getPreferredSize() {
BufferedImage img = getBackgroundImage();
Dimension size = super.getPreferredSize();
if (img != null) {
size.width = Math.max(size.width, img.getWidth());
size.height = Math.max(size.height, img.getHeight());
}
return size;
}
public BufferedImage getBackgroundImage() {
return img;
}
public void setBackgroundImage(BufferedImage value) {
if (img != value) {
BufferedImage old = img;
img = value;
firePropertyChange("background", old, img);
revalidate();
repaint();
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
BufferedImage bg = getBackgroundImage();
if (bg != null) {
int x = (getWidth() - bg.getWidth()) / 2;
int y = (getHeight() - bg.getHeight()) / 2;
g.drawImage(bg, x, y, this);
}
}
}
}
这个实现缺少像自动缩放或重复这样的东西,但你明白了
This implementation is missing things like auto scaling or repeating, but you get the idea
这篇关于创建带有背景图像的表单 (JLayeredPane)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:创建带有背景图像的表单 (JLayeredPane)
基础教程推荐
- 在螺旋中写一个字符串 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01