Java AWT setLayout(null) 似乎不起作用
Java AWT setLayout(null) doesn't seem to be working
我正在尝试将现有的 Java AWT(独立)应用程序重新用于 运行 专用的单一用途硬件(想想博物馆中也控制硬件的信息亭在幕后)和我的假设,如果我只是将主面板上的布局管理器设置为 null
,我就可以使用 Rectangle(starting x, starting y, x-width, y-height)
之类的东西或其他类似的方法来布置项目,已被证明是假的!所以,我比我想象的更迷茫!
以下是一些摘录:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
[...]
public class myGUI extends JFrame
{
JPanel MainPanel = new JPanel();
JMenuBar Menu = new JMenuBar();
int MaxWidth = 1920;
int MaxHeight = 1080;
Dimension FullScreen = new Dimension(MaxHeight, MaxWidth);
Rectangle recHZbar = new Rectangle(0, 32, MaxWidth, 4);
[...]
MainPanel.setLayout(null);
MainPanel.setPreferredSize(FullScreen);
MainPanel.setEnabled(true);
MainPanel.setBackground(LightBlue);
各种各样的组件总共有一百多个,在这里展示它们没有意义。可以说我正在尝试消除独立帧,而是在非常大的屏幕边缘显示所有数据,然后使用关键数据单独管理屏幕的中心 space,希望能够使用可见性来切换用户看到的内容(而不是窗格/面板),因为在许多情况下有很多共性。
我认为通过将布局管理器设置为 null,我将能够使用类似水平条的东西在 MainPanel 上定位组件,其中嵌入了一条消息:
JLabel HorizontalBar = new JLabel();
HorizontalBar.setBackground(DarkBlue);
HorizontalBar.setFont(new java.awt.Font("Dialog", 0, 10));
HorizontalBar.setForeground(LightBlue);
HorizontalBar.setPreferredSize(dimMxW10pt);
HorizontalBar.setOpaque(true);
HorizontalBar.setHorizontalTextPosition(SwingConstants.CENTER);
HorizontalBar.setText(HZBarTxt);
HorizontalBar.setBounds(recHZbar);
MainPanel.add(HorizontalBar, null);
... 这当然有效,但是,当我试图定位这个水平条时(通过 setBounds(rectangle)
),很明显坐标是基于 JMenuBar I 的底部较早添加,而不是从屏幕的左上角添加!这让我很担心! (我假设下一个栏将基于第一个栏下方的 space,等等?!)我认为我有一个我没有(明确)要求的布局管理器是否正确? (如果是这样,我该如何避免?)
我希望我忽略了一些简单的事情,以便能够在不需要做太多工作的情况下进行自我定位。如果我不能直接选择我想要的东西在屏幕上的位置,我就会在这个项目上遇到麻烦!我希望避免使用很多小面板等。我需要创建不规则的列等等。我知道我可以通过计算来按我想要的方式布置东西,但我不愿意相信布局管理器能把它做好,尤其是因为对实际生产硬件的测试非常困难,而且如果布局管理器不同的话,这将意味着麻烦。我可能忽略了正确的布局管理器 - "do it yourself layout manager",也许吧? - 但我看不出 "GridLayout" 对我有用,至少,不容易。所以我希望学习如何尽可能简单直接地做我自己的布局(这就是我认为我已经在做的)。
TIA。
事实证明,我最初认为对 setLayout(null)
的调用没有成功的假设本身就是错误的,这是一件好事!
鉴于我的要求,我做出完全不使用 window 经理的完全正确的选择。 是的,从对许多人认为不使用 window 经理是愚蠢甚至愚蠢的问题,但就我而言,我做出了完全正确的选择,原因如下:
这个项目的情况是 "doing it yourself" 的罕见情况之一,事实上,如果我使用 window 经理,它就不会成功 _AT_ALL!_ ...至少在我有空的时候没有。
本项目use-case的简要回顾
这是用于专用硬件控制的,事实上,它不能 运行 在任何地方的生产中,而是 Java 代码提供 [=67] 的专用硬件的非常单一的安装=] 为。此外,它永远不会有任何互联网连接,也永远不会升级。对操作系统或其他软件升级的担忧为零——这是不可能发生的。因为它有一个单一的固定 运行ning 环境,所以不用担心 font-change 处理或类似的事情。
应用程序设计;为什么布局管理器会把它搞砸
我选择使用一帧,"undecorated" 这样 if 就会填满整个显示屏,如下所示:
这完全填满了 1090 X 1920 的显示器,所以我不知道它在这里的表现如何。
我创建了一个 JFrame
作为整件事的背景。在其中,我首先创建了一个菜单栏,然后是标题栏,对于这些东西,布局管理器当然可以做得很好,但这就是简单部分的结尾。
我通过使用 item.setBounds(X, Y, W, H)
放置项目创建了宽度必然不同的左右栏,然后在底部创建了一个部分。我使用变量作为值,并使用它们来创建标准的行和列位置、宽度和高度。这使得在需要它的地方可以很容易地从标准转移;我只是使用一组不同的变量(使用我发明的命名约定以保持简单)。我想您可以为这部分使用布局管理器,但这会很乏味,而且一点也不清楚它是否会减少工作量。特别是,如何让两个垂直列位于您想要的位置?您必须为每列中每个不同格式的区域创建单独的嵌入窗格/面板 - 甚至是底部行!您还必须让它们堆叠或 space 恰到好处。然后是那些垂直和水平条 - 你是怎么做到的?
重要的是,我在中央留出了一个插入面板的空间,其中的数量非常多 (!!) 远远超过您在示例图像中看到的数量。他们是 JPanels
,当然,这里只能看到其中一个。 这就是布局管理器会完全崩溃的地方。 良好的 UI 设计保持一致,因此用户可以知道在哪里可以找到各种things. 在各个面板上,有些面板之间存在共同点,而在其他面板上则不同,具有不同的共性,并且还有更多的面板与不同组的面板之间的共性交叉,但很少面板确实足够满,通用布局管理器打包算法可以处理;由于各种原因,各种项目 - 并且需要 - 在可能看起来是 non-standard 的位置,因此使用布局管理器需要用很多 sub-panels 等填充窗格,以便每个各种布局管理器的一部分可以正确地完成他们的工作。 通过不使用布局管理器, 从而在查看不同的嵌入窗格时可以自由地准确指定组件的不同位置,我能够非常简单地使用 panel.add(item)
语法在窗格之间移动项目并保持位置准确。 此外,由于外部面板和内部面板的顶部位置相同,因此完全正确地排列行是小菜一碟!
这是hands-down最简单的方法。我会一直在与该死的布局管理器作斗争。 ...不要害怕跳过布局管理器并自己动手,只需准备好自己完成整个工作. 如果你能胜任这项任务,并且如果你有像我一样的固定 use-case 情况,那一点也不坏,而且 它甚至可能是某些任务的唯一实用方法。
我正在尝试将现有的 Java AWT(独立)应用程序重新用于 运行 专用的单一用途硬件(想想博物馆中也控制硬件的信息亭在幕后)和我的假设,如果我只是将主面板上的布局管理器设置为 null
,我就可以使用 Rectangle(starting x, starting y, x-width, y-height)
之类的东西或其他类似的方法来布置项目,已被证明是假的!所以,我比我想象的更迷茫!
以下是一些摘录:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
[...]
public class myGUI extends JFrame
{
JPanel MainPanel = new JPanel();
JMenuBar Menu = new JMenuBar();
int MaxWidth = 1920;
int MaxHeight = 1080;
Dimension FullScreen = new Dimension(MaxHeight, MaxWidth);
Rectangle recHZbar = new Rectangle(0, 32, MaxWidth, 4);
[...]
MainPanel.setLayout(null);
MainPanel.setPreferredSize(FullScreen);
MainPanel.setEnabled(true);
MainPanel.setBackground(LightBlue);
各种各样的组件总共有一百多个,在这里展示它们没有意义。可以说我正在尝试消除独立帧,而是在非常大的屏幕边缘显示所有数据,然后使用关键数据单独管理屏幕的中心 space,希望能够使用可见性来切换用户看到的内容(而不是窗格/面板),因为在许多情况下有很多共性。
我认为通过将布局管理器设置为 null,我将能够使用类似水平条的东西在 MainPanel 上定位组件,其中嵌入了一条消息:
JLabel HorizontalBar = new JLabel();
HorizontalBar.setBackground(DarkBlue);
HorizontalBar.setFont(new java.awt.Font("Dialog", 0, 10));
HorizontalBar.setForeground(LightBlue);
HorizontalBar.setPreferredSize(dimMxW10pt);
HorizontalBar.setOpaque(true);
HorizontalBar.setHorizontalTextPosition(SwingConstants.CENTER);
HorizontalBar.setText(HZBarTxt);
HorizontalBar.setBounds(recHZbar);
MainPanel.add(HorizontalBar, null);
... 这当然有效,但是,当我试图定位这个水平条时(通过 setBounds(rectangle)
),很明显坐标是基于 JMenuBar I 的底部较早添加,而不是从屏幕的左上角添加!这让我很担心! (我假设下一个栏将基于第一个栏下方的 space,等等?!)我认为我有一个我没有(明确)要求的布局管理器是否正确? (如果是这样,我该如何避免?)
我希望我忽略了一些简单的事情,以便能够在不需要做太多工作的情况下进行自我定位。如果我不能直接选择我想要的东西在屏幕上的位置,我就会在这个项目上遇到麻烦!我希望避免使用很多小面板等。我需要创建不规则的列等等。我知道我可以通过计算来按我想要的方式布置东西,但我不愿意相信布局管理器能把它做好,尤其是因为对实际生产硬件的测试非常困难,而且如果布局管理器不同的话,这将意味着麻烦。我可能忽略了正确的布局管理器 - "do it yourself layout manager",也许吧? - 但我看不出 "GridLayout" 对我有用,至少,不容易。所以我希望学习如何尽可能简单直接地做我自己的布局(这就是我认为我已经在做的)。
TIA。
事实证明,我最初认为对 setLayout(null)
的调用没有成功的假设本身就是错误的,这是一件好事!
鉴于我的要求,我做出完全不使用 window 经理的完全正确的选择。 是的,从对许多人认为不使用 window 经理是愚蠢甚至愚蠢的问题,但就我而言,我做出了完全正确的选择,原因如下:
这个项目的情况是 "doing it yourself" 的罕见情况之一,事实上,如果我使用 window 经理,它就不会成功 _AT_ALL!_ ...至少在我有空的时候没有。
本项目use-case的简要回顾
这是用于专用硬件控制的,事实上,它不能 运行 在任何地方的生产中,而是 Java 代码提供 [=67] 的专用硬件的非常单一的安装=] 为。此外,它永远不会有任何互联网连接,也永远不会升级。对操作系统或其他软件升级的担忧为零——这是不可能发生的。因为它有一个单一的固定 运行ning 环境,所以不用担心 font-change 处理或类似的事情。
应用程序设计;为什么布局管理器会把它搞砸
我选择使用一帧,"undecorated" 这样 if 就会填满整个显示屏,如下所示:
这完全填满了 1090 X 1920 的显示器,所以我不知道它在这里的表现如何。
我创建了一个 JFrame
作为整件事的背景。在其中,我首先创建了一个菜单栏,然后是标题栏,对于这些东西,布局管理器当然可以做得很好,但这就是简单部分的结尾。
我通过使用 item.setBounds(X, Y, W, H)
放置项目创建了宽度必然不同的左右栏,然后在底部创建了一个部分。我使用变量作为值,并使用它们来创建标准的行和列位置、宽度和高度。这使得在需要它的地方可以很容易地从标准转移;我只是使用一组不同的变量(使用我发明的命名约定以保持简单)。我想您可以为这部分使用布局管理器,但这会很乏味,而且一点也不清楚它是否会减少工作量。特别是,如何让两个垂直列位于您想要的位置?您必须为每列中每个不同格式的区域创建单独的嵌入窗格/面板 - 甚至是底部行!您还必须让它们堆叠或 space 恰到好处。然后是那些垂直和水平条 - 你是怎么做到的?
重要的是,我在中央留出了一个插入面板的空间,其中的数量非常多 (!!) 远远超过您在示例图像中看到的数量。他们是 JPanels
,当然,这里只能看到其中一个。 这就是布局管理器会完全崩溃的地方。 良好的 UI 设计保持一致,因此用户可以知道在哪里可以找到各种things. 在各个面板上,有些面板之间存在共同点,而在其他面板上则不同,具有不同的共性,并且还有更多的面板与不同组的面板之间的共性交叉,但很少面板确实足够满,通用布局管理器打包算法可以处理;由于各种原因,各种项目 - 并且需要 - 在可能看起来是 non-standard 的位置,因此使用布局管理器需要用很多 sub-panels 等填充窗格,以便每个各种布局管理器的一部分可以正确地完成他们的工作。 通过不使用布局管理器, 从而在查看不同的嵌入窗格时可以自由地准确指定组件的不同位置,我能够非常简单地使用 panel.add(item)
语法在窗格之间移动项目并保持位置准确。 此外,由于外部面板和内部面板的顶部位置相同,因此完全正确地排列行是小菜一碟!
这是hands-down最简单的方法。我会一直在与该死的布局管理器作斗争。 ...不要害怕跳过布局管理器并自己动手,只需准备好自己完成整个工作. 如果你能胜任这项任务,并且如果你有像我一样的固定 use-case 情况,那一点也不坏,而且 它甚至可能是某些任务的唯一实用方法。