java JLabel、网格布局

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7155508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 18:52:34  来源:igfitidea点击:

JLabel, GridLayout

swinggrid-layoutjava

提问by good_evening

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

public class Gui extends JFrame
{
    private JFrame window = new JFrame();
    private JButton but[] = new JButton[9];

    public Gui()
    {
        window.setSize(300,400);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setLayout(new GridLayout(4, 3));

        JLabel txt = new JLabel("Will you dare?", JLabel.CENTER);
        txt.setLayout(new GridLayout(1, 1));
        txt.setHorizontalTextPosition(JLabel.CENTER);
        txt.setFont(new Font("Serif", Font.PLAIN, 21));
        window.add(txt);

        for(int i = 0; i < 9; i++)
        {
            but[i] = new JButton();
            window.add(but[i]);
        }  

        window.setVisible(true);

    }

    public void actionPerformed(ActionEvent e) 
    {

    }

}

I am Java noob, so, can you tell me, why "Will you dare" text doesn't appear in one line? Can you tell me how you found the solution, so other time I also will be able to do that by myself.

我是 Java noob,所以,你能告诉我,为什么“你敢”文本没有出现在一行中?你能告诉我你是如何找到解决方案的,所以其他时候我也可以自己做。

回答by Snicolas

There are two caveats in your code :

您的代码中有两个警告:

you use the following expression to add components

您使用以下表达式添加组件

 window.add(txt);
 //....
 window.add(but[i]);

both calls are shortcuts to

这两个电话都是快捷方式

window.getContentPane().add

and the content pane of a JFrame has BorderLayout by default. And by default, this layout will add components in the center area if no other area/constraint is specified when adding. So you just put components one above the other, only the last will remain.

并且 JFrame 的内容窗格默认具有 BorderLayout。默认情况下,如果添加时没有指定其他区域/约束,则此布局将在中心区域添加组件。因此,您只需将组件一个放在另一个之上,只剩下最后一个。

You should "cut"(poor translation, slice ?) more your GUI, adding your JLabel at center, and adding another JPanel on south, and inside it, use a flow layout and add your buttons.

您应该“剪切”(糟糕的翻译,切片?)更多的 GUI,在中心添加 JLabel,并在南部添加另一个 JPanel,并在其中使用流布局并添加按钮。

Here is a good startfor using the layout I mentionned, which are very standard.

这是使用我提到的非常标准的布局的良好开端

Alsoyou use a JLabel as a container. Almost all swing components inherit from java.awt.Container, this is used by swing to provide compound components but actually, you should never use them as container, i.e. not putting other components inside them or giving them a layout. You do that, giving it a layout at line

使用一个JLabel作为容器。几乎所有的 Swing 组件都继承自java.awt.Container,这是 Swing 用来提供复合组件的,但实际上,您永远不应该将它们用作容器,即不要将其他组件放入其中或给它们布局。你这样做,给它一个在线布局

txt.setLayout(new GridLayout(1, 1));

so remove this line. Use swing components as components and JPanel (or JTabbedPane, etc.) as containers.

所以删除这一行。使用 Swing 组件作为组件,使用 JPanel(或 JTabbedPane 等)作为容器。

Regards, Stéphane btw, never hardcode values, use constants. No 9 but a BUTTON_COUNT = 9 static member. You could consider buying a java book. I used to recommend Deitel and Deitel to my students.

问候,Stéphane btw,从不硬编码值,使用常量。没有 9,而是一个 BUTTON_COUNT = 9 静态成员。你可以考虑买一本java书。我曾经向我的学生推荐 Deitel 和 Deitel。

回答by camickr

Wild guess here, but I'm thinking you want something like:

在这里胡乱猜测,但我想你想要这样的东西:

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

public class Gui extends JFrame
{
    private JFrame window = new JFrame();
    private JButton but[] = new JButton[9];

    public Gui()
    {
        window.setSize(300,400);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//        window.setLayout(new GridLayout(4, 3));
        JPanel panel = new JPanel( new GridLayout(3, 3) );
        window.add(panel, BorderLayout.CENTER);

        JLabel txt = new JLabel("Will you dare?", JLabel.CENTER);
//        txt.setLayout(new GridLayout(1, 1));
        txt.setHorizontalTextPosition(JLabel.CENTER);
        txt.setFont(new Font("Serif", Font.PLAIN, 21));
//        window.add(txt);
        window.add(txt, BorderLayout.NORTH);

        for(int i = 0; i < 9; i++)
        {
            but[i] = new JButton();
//            window.add(but[i]);
            panel.add(but[i]);
        }

        window.setVisible(true);

    }

    public static void main(String args[]) throws Exception
    {
        new Gui();
    }

}

回答by corecase

The problemhere is quite simple: You are adding a layout to your label "txt".

这里的问题很简单:您正在向标签“txt”添加布局。

You are saying that the label "txt" should take up the first row, first column of your JFrame. The first row, first column would result in a box. When you create a box like that you need to make sure the box is wide enough for your text to completely fit on a single line. In this case your text is simply jumping to the next line because there isn't enough room in that "box" you created for the entire label to fit on a single line.

您是说标签“txt”应该占据 JFrame 的第一行第一列。第一行,第一列将导致一个框。当您创建这样的框时,您需要确保框的宽度足以让您的文本完全适合一行。在这种情况下,您的文本只是跳到下一行,因为您为整个标签创建的“框”中没有足够的空间容纳在一行中。

Fixes to the problem:

修复问题:

  • Remove this line: txt.setLayout(new GridLayout(1, 1));
  • 删除这一行: txt.setLayout(new GridLayout(1, 1));

OR

或者

  • Change the following line: txt.setLayout(new GridLayout(1, 1));totxt.setLayout(new GridLayout(1,2));
  • 更改以下行:txt.setLayout(new GridLayout(1, 1));txt.setLayout(new GridLayout(1,2));

You have one other problem that i noticed:

你还有一个我注意到的问题:

  • The following line should go at the top, beneath private JButton but[] = new JButton[9];:JLabel txt = new JLabel("Will you dare?");//Removing the 'JLabel.CENTER'
  • 以下行应位于顶部,下方private JButton but[] = new JButton[9];JLabel txt = new JLabel("Will you dare?");//Removing the 'JLabel.CENTER'

That should do it.(i don't think i missed anything). :)

应该这样做。(我认为我没有错过任何东西)。:)