添加到JPanel的Java Swing组件大小不正确。

5

这是我在这里发布的第一篇文章,如果我做错了什么,请原谅。

我的问题是:

我正在尝试向具有定义大小等值的JPanel添加组件。但是,当我将它们添加到面板时,它们根本没有应该有的大小和位置。例如:

public class Console extends JFrame {
    private JPanel mainPanel = new JPanel();
    private JTextArea textField = new JTextArea();
    private JTextArea textField2 = new JTextArea();

    public Console() {
        this.setSize(500,300);

        this.mainPanel.setSize(this.getWidth(),this.getHeight());

        this.textField.setEditable(false);
        this.textField.setSize(this.mainPanel.getWidth(), 100);
        this.textField.setPreferredSize(new Dimension(this.mainPanel.getWidth(),this.mainPanel.getHeight()));
        this.textField.setLocation(0, 0);
        this.textField.setText("some text");
        this.textField.setVisible(true);

        this.textField2.setSize(this.mainPanel.getWidth(),200);
        this.textField2.setPreferredSize(new Dimension(this.getWidth(),this.getHeight()));
        this.textField2.setLocation(0,this.mainPanel.getHeight()-this.textField.getHeight());
        this.textField2.setText("blabla");
        this.textField2.setVisible(true);

        this.mainPanel.add(textField);
        this.mainPanel.add(textField2);
        this.mainPanel.setVisible(true);

        this.add(this.mainPanel);
        // I know you should not call setVisible() in the Constructor, just for making Code more simple here.
        this.setVisible(true);
    }
}

当我启动应用程序时,两个JTextArea非常小并且在中间位置(不像上面设置的那样),而mainPanel是正确的。我尝试在代码的不同位置调用setSize()和setPreferredSize(),但这没有起作用。据我所知,使用布局管理器更好,但老实说,我不知道如何正确使用它。我在Oracle文档中检查了它,但如果有人能发布一个干净的解决方案,我会非常感激。谢谢提前。

你需要使用正确的布局 - Nikolay Kuznetsov
抱歉如果这听起来很蠢:你是指 setLayout() 吗?如果是的话,我想我需要创建一个 GridLayout。但是我需要将组件添加到此布局中吗?它是如何工作的? - Furious Gamer
请查看我的回答中的指南。 - Nikolay Kuznetsov
你真的没有提供任何“行”和“列”,这也可以确定它们的大小。在初始化时使用适当的“构造函数”或按照答案中建议的设置“行”和“列”。使用“FlowLayout(JPanel的默认值)”,因此不需要对布局进行任何更改,正如一些答案中所指出的那样(依我之见),只要为其指定“行”和“列”,就能看到你的“JTextArea”。 - nIcE cOw
尽可能地,不要为 setXxXSize() 方法指定任意值,让你使用的布局来担心那部分。 - nIcE cOw
1
谢谢大家!真是太感谢了!有很多有用的答案,我都很喜欢(特别是那些很有用的)。最后我选择了Nikolay的回答,因为我最终使用了invokeLater()。不过我同样要感谢Gagandeep和Joey。 - Furious Gamer
4个回答

6
你需要为你的容器设置适当的布局,例如JFrameJPanel等,使用setLayout方法进行设置。你不需要将其他组件添加到布局中,而是添加到容器中,然后它会相应地进行布局。这就是它的工作原理。
有了适当的布局,你就不需要调用setLocation()方法。同时,在你的代码中,setVisible(true)也是多余的,因为这些组件的默认值就是true。
最好不要继承JFrame,而是继承JPanel,然后将其添加到JFrame中。
请了解EDT和SwingUtilities.invoketLater(),你需要使用它。
此外,你可以节省一些字节,不用一直输入this.

搜索了SwingUtilities.invoketLater()并了解到JPanel默认使用FlowLayout :)。谢谢 - Furious Gamer
"此外,您可以节省一些字节,不必一直输入 this.。使用自动完成的IDE时可能具有讽刺意味的是,这样做实际上可以节省击键次数,因为IDE会弹出方法名称列表。 ;) 感谢您的回答。" - Andrew Thompson
1
@AndrewThompson,是的,有点讽刺。我认为在Eclipse中,可以按Ctrl+Space键,无需输入“this.”即可查看方法和字段列表。 - Nikolay Kuznetsov
快速测试Eclipse和Netbeans-都做到了。太好了!谢谢提示。 :) - Andrew Thompson
@AndrewThompson,同样可以在Eclipse中用于自动完成。 - Nikolay Kuznetsov

2

针对你的JTextArea问题,可以使用以下方法:

       JTextArea j=new JTextArea();
       j.setColumns(20);
       j.setRows(5);

更改setColumns()setRows()的值以改变大小;同时建议使用布局管理器(Layout Managers)

希望这能够起到作用 ;)


将信息加1,或使用适当的构造函数初始化JTextArea。布局与此无关,因为JPanel默认具有FlowLayout,只是您的答案与问题密切相关。 - nIcE cOw

2

这里涉及到布局,具体可以参考Swing布局


谢谢你和Nikolay,我会再次检查它。在Oracle文档中读错了一些地方,现在才意识到^^。抱歉。 - Furious Gamer

-1
尝试使用JPanel的绝对布局。

什么是“绝对布局”?以前从未听说过。不过,如果你指的是绝对定位,那么首先应该尝试阅读绝对定位的第一段,了解Java文档对这个东西的看法,并尽可能克制自己使用它。 - nIcE cOw
1
-1 这是最糟糕的建议。你几乎永远不应该使用绝对布局。 - Guillaume Polet

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