如何更改 JLabel 或我添加的任何其他组件的位置?

Posted

技术标签:

【中文标题】如何更改 JLabel 或我添加的任何其他组件的位置?【英文标题】:How do I change the position of JLabel or any other Component I add? 【发布时间】:2014-10-23 09:58:11 【问题描述】:

我正在尝试使用 OverlayLayout 和扩展的 JPanel 创建一个半透明窗口,除了我放入的 JLabel 图像之外没有边框或背景...

我的问题是,当我尝试在最初添加的背景上添加更多组件时,我不知道如何更改新组件的位置.. x、y 等...

如果可能的话,请告诉我我能做什么,不要只指给我布局管理器,如果有人愿意告诉我,我需要一个例子。

或者更好的是,告诉我我需要对我的代码做什么才能获得预期的效果..比如将“文本”(A JLabel)位置更改为 10,10 ... x 和 y。

package core;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.OverlayLayout;

public class App 
    // Window & Panel...
    public JWindow frame;
    public TranslucentPanel panel;

    // OverlayLayout
    public LayoutManager overlay;

    // Components
    public JLabel bg;
    public JLabel test;

    // Constructor
    public App() 
        try 
            // Basics...
            frame = new JWindow();
            frame.setBackground(new Color(0, 0, 0, 0));

            // Overlay
            panel = new TranslucentPanel();
            overlay = new OverlayLayout(panel);
            panel.setLayout(overlay);
            frame.setContentPane(panel);

            // initComponents
            initComponents();

            // Finalize Frame
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        
        catch(Exception e) 
            e.printStackTrace();
        
    

    // Initialize Additional Components
    public void initComponents() throws Exception 
        test = new JLabel("test");
        test.setForeground(Color.WHITE);
        frame.add(test);

        bg = new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/ball.png"))));
        frame.add(bg);

        // What must I do to be able to do this???
        test.setLocation(10, 0);
    

    // TranslucentPanel Class...
    public class TranslucentPanel extends JPanel 
        private static final long serialVersionUID = 1L;

        public TranslucentPanel() 
            setOpaque(false);
        

        protected void paintComponent(Graphics g) 
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D)g.create();
            g2d.setComposite(AlphaComposite.SrcOver.derive(0.0f));
            g2d.setColor(getBackground());
            g2d.fillRect(0, 0, getWidth(), getHeight());
        
    

【问题讨论】:

创建另一个JPanel(使其透明),适当地设置它的布局管理器并向其中添加组件。考虑根据需要使用复合布局以获得所需的效果。 "..to get the desired effect" 提供 ASCII 艺术或简单的图形,说明 GUI 应如何以默认大小显示,并且(如果可调整大小)具有额外的宽度/高度. 这就是我想要的:imgur.com/ULxyKv8 我被顶部的图片卡住了。 【参考方案1】:

一种方法是丢弃Overlayout 管理器,将TranslucentPanel 的布局管理器设置为BorderLayout 并使用JLabelbg 作为其自身的容器...

bg = new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/ball.png"))));
frame.add(bg);

// Set the layout of the JLabel    
bg.setLayout(new GridBagLayout());
test = new JLabel("test");
test.setForeground(Color.WHITE);
// Add the test label to the bg JLabel...
bg.add(test);

就我个人而言,我不喜欢这样,因为JLabel 在计算首选尺寸时没有考虑组件(或布局管理器)。

就我个人而言,我会创建一个自定义背景组件,负责绘制背景图像。然后,在此之上,我将放置其他组件,使用任何我需要的组件和布局管理器组合来产生所需的结果。

像素完美的布局是现代 UI 设计中的一种错觉。影响组件单个尺寸的因素太多,您无法控制。 Swing 旨在与核心的布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正

【讨论】:

@Charl Du Plessis,按照这个答案,你的问题就解决了。 我尝试实现上面的代码,但我不知道该怎么做,如果可能的话,请让我看看。【参考方案2】:

从您的代码中阅读以下内容后:

// What must I do to be able to do this???
    test.setLocation(10, 0);

如果我理解正确,您想根据自定义坐标来安排组件的位置。如果是这样,那么您可以使用Insets 类http://docs.oracle.com/javase/7/docs/api/java/awt/Insets.html 来实现这一点。 所以你可以根据你想要的位置设置组件的位置

     Insets insets = panel.getInsets();
    Dimension size =test.getPreferredSize();

   // just replace 10 & 0 according to X & Y postion you want.
     test.setBounds(10 + insets.left, 0 + insets.top,size.width, size.height); 

这是你的修改版本:

*请注意,我没有您的 Icon ,所以我只是在您的标签上放了文字以帮助您查看结果。

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


public final class App
    // Window & Panel...
    public JWindow frame;
    public TranslucentPanel  panel;

    // OverlayLayout
    public LayoutManager overlay;

    // Components
    public JLabel bg;
    public JLabel test;

    // Constructor
    public App() 
        try 
            // Basics...
            frame = new JWindow();
            // Overlay
            // Overlay
            panel = new TranslucentPanel();
            overlay = new OverlayLayout(panel);
            panel.setLayout(overlay);
            frame.add(panel);


            initComponents();
          // Finalize Frame
            frame.pack();
            frame.setSize(400,400);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        
        catch(Exception e)  e.printStackTrace();

    

    // Initialize Additional Components
    public void initComponents() throws Exception 
        test = new JLabel("test");
        test.setForeground(Color.RED);

        panel.setLayout(null);
        panel.add(test);

        Insets insets = panel.getInsets();
        Dimension size =test.getPreferredSize();
        test.setBounds(10 + insets.left, 0 + insets.top,
                size.width, size.height);


        frame.add(panel);

    

    // TranslucentPanel Class...
   class TranslucentPanel extends JPanel 
        private static final long serialVersionUID = 1L;

        public TranslucentPanel() 
            setOpaque(false);
        

        protected void paintComponent(Graphics g) 
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D)g.create();
            g2d.setComposite(AlphaComposite.SrcOver.derive(0.0f));
            g2d.setColor(getBackground());
            g2d.fillRect(0, 0, getWidth(), getHeight());
        
    


public static void main (String args [])

    App ap = new App();      

  

输出:

如果您将您的职位声明为test.setBounds(500 + insets.left, 10 + insets.top,size.width, size.height);,那么输出将是:

【讨论】:

这看起来是一个相当不错的答案 - 为什么要删除它?

以上是关于如何更改 JLabel 或我添加的任何其他组件的位置?的主要内容,如果未能解决你的问题,请参考以下文章

如何在其他组件的状态更改时重新渲染 DOM

只能添加JLabel背景或JPanel背景

除非与mouselistener一起使用,否则JLabel不会显示

在JLabel上设置大小取代了java中的其他组件

添加到 BorderLayout 时,无法在 JPanel 中左对齐 JLabel

Terraform删除路由表,然后在第二次运行时将其添加(无更改)。错误或我缺少什么吗?