在JPanel上特定的x,y坐标放置一个JLabel

11

我试图在JPanel上特定的X和Y坐标放置一系列的JLabel(并设置其高度和宽度)。无论我做什么,每个标签都会立即出现在前一个标签的右侧,并且与所有其他标签具有完全相同的大小。

目前,我的JPanel位于网格布局中。我尝试过绝对布局(导致非法参数异常),自由设计(没有标签出现),流式布局(一切都被挤压到中心),以及其他一些方法。

不确定我需要做什么才能使其工作。有人能帮帮我吗?谢谢!

JLabel lbl1 = new JLabel("label 1");
JLabel lbl2 = new JLabel("label 2");
JLabel lbl3 = new JLabel("label 3");
JLabel lbl4 = new JLabel("label 4");
JLabel lbl5 = new JLabel("label 5");

myPanel.add(lbl1);
myPanel.add(lbl2);
myPanel.add(lbl3);
myPanel.add(lbl4);
myPanel.add(lbl5);

lbl1.setLocation(27, 20);
lbl2.setLocation(123, 20);
lbl3.setLocation(273, 20);
lbl4.setLocation(363, 20);
lbl5.setLocation(453, 20);

lbl1.setSize(86, 14);
lbl2.setSize(140, 14);
lbl3.setSize(80, 14);
lbl4.setSize(80, 14);
lbl5.setSize(130, 14);

1
你需要将容器的布局设置为null。myPanel.setLayout(null); - gersonZaragocin
啊!那是我没有尝试过的唯一布局。谢谢!如果您将其作为答案输入,我会将其标记为已接受。 - AndroidDev
1
"我正在尝试在JPanel上特定的X和Y坐标放置一系列的JLabel。" 为什么? - Andrew Thompson
1
你很可能不想手动调整容器中所有子元素的大小和位置 - 这是 LayoutManager 的专属任务。因此,你的任务是学习它们各自实现的不同行为,并选择适合你要求的一个。 - kleopatra
6个回答

16
你必须将容器的布局设置为null:
myPanel.setLayout(null);

但是建议您也可以看一下 Matisse 布局管理器,我想现在称为 GroupLayout。绝对定位的主要问题在于窗口改变大小时会发生什么。


3
"主要问题是窗口改变大小。因此,必须将次要问题留给:使用不同字体、PLAF(本地外观)、屏幕设置来确定组件大小的逻辑,或者容纳其他组件组。使用null布局通常是一个非常糟糕的想法。" - Andrew Thompson
@AndrewThompson 是的,我同意使用 null 布局通常是一个坏主意。但是考虑一些具有固定窗口大小或在运行单个应用程序的嵌入式设备上运行的应用程序。在这种情况下,使用布局来安排组件可能只是额外的工作和内存消耗。问候 - gersonZaragocin
“可能用布局排列组件只是多余的工作。”直到客户看着用户界面,皱起眉头说:“将'确定'按钮从下面移到复选框上方”。 - Andrew Thompson
1
@AndrewThompson,可能这是一个不同的问题或者是由于分析或设计过程不佳导致的结果,但这偏离了真正的问题:“在JPanel上放置一个特定的x,y坐标的JLabel”。我没有所有提问者拥有的上下文信息来批评他做事的方式或为什么他要那样做。 - gersonZaragocin
1
"我没有所有的上下文信息。" 因此,如果有人问你“我怎样才能自毁前程?”,缺乏进一步的上下文信息,你是否提供指导?有时候,挑战问题或策略的需要会比立即提供几乎肯定会引起更多问题的答案更好。不过,从另一个角度看,你似乎持有不同的观点。 - Andrew Thompson
@AndrewThompson 不,我同意你关于挑战人的观点。如果你再读一遍我的回答,你会发现我在提供答案后指出了策略的主要问题,但也知道有一个真正需要回答的问题。但如果你认为你是正确的,那么你就是正确的,我认为这并不值得为这么短的事情开始一场长时间的辩论。 致敬。 - gersonZaragocin

4
  1. 调用setLayout(null)方法将容器的布局管理器设置为null。

  2. 为容器的每个子组件调用Component类的setbounds方法。

  3. 调用Component类的repaint方法。

注意:

使用绝对定位容器创建容器可能会在包含该容器的窗口调整大小时导致问题。

请参考此链接: http://docs.oracle.com/javase/tutorial/uiswing/layout/none.html


3

布局管理器用于自动确定容器中组件的布局。如果您希望将组件放置在特定坐标位置,则不应该使用任何布局管理器。

myPanel = new JPanel(null);

或者

myPanel.setLayout(null);

2

我的建议是使用像NetBeans这样带GUI编辑器的IDE。为了检查代码,因为有许多方法:

设置布局管理器或对于绝对定位可以做一个myPanel.setLayout(null),都有几个影响。

一般来说,假设您在JFrame的构造函数中调用,您可以调用pack()开始布局。

然后,每个布局管理器使用自己的实现add(Component)add(Component, Constraint)。 BorderLayout的使用是与add(label, BorderLayout.CENTER)等类似。


1
    // Best solution!!

import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Main {

  public static void main(String args[]) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel panel = (JPanel) frame.getContentPane();
    panel.setLayout(null);

    JLabel label = new JLabel("aaa");
    panel.add(label);
    Dimension size = label.getPreferredSize();
    label.setBounds(100, 100, size.width, size.height);

    frame.setSize(300, 200);
    frame.setVisible(true);

  }
}

0

你可以使用自己的方法直接调用setSize、setLocation等数值...!同时我也会向你展示如何使用JProgress Bar。

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

class installComp{
    void install(Component comp, int w, int h, int x, int y){
        comp.setSize(w,h);
        comp.setLocation(x,y);
    }
}
class MyFrame extends JFrame{
    int cur_val = 0;
    JButton btn = new JButton("Mouse Over");
    JProgressBar progress = new JProgressBar(0,100);
    MyFrame (){
        installComp comp=new installComp();

        comp.install(btn,150,30,175,20);
        comp.install(progress,400,20,50,70);

        btn.addMouseListener(new MouseAdapter(){
            public void mouseEntered(MouseEvent evt){
                cur_val+=2;
                progress.setValue(cur_val);
                progress.setStringPainted(true);
                progress.setString(null);
            }
        }); 
        add(btn);
        add(progress);
        setLayout(null);    
        setSize(500,150); 
        setResizable(false);
        setDefaultCloseOperation(3);
        setLocationRelativeTo(null);
        setVisible(true);
    }
}
class Demo{
    public static void main(String args[]){
        MyFrame f1=new MyFrame();   
    }
}

手动定位/调整大小(即不使用LayoutManager)始终是错误的,现在和将来都是如此... - kleopatra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接