【问题标题】:How elements in Container adjust when we resize window?当我们调整窗口大小时,容器中的元素如何调整?
【发布时间】:2015-10-20 13:47:06
【问题描述】:

下面是一个窗口的代码,当用户点击一个按钮时它会改变颜色,当他点击另一个按钮时会改变标签的文本。

它有两个按钮,一个用于按住按钮的面板、一个标签和一个用于图形的面板。

概念解释: 首先,我使用默认的BorderLayoutlabel 添加到frameNorth 部分。然后我在一个单独的面板中添加了两个buttons,并将panel 添加到主要frameSouth 部分。然后我在主frameCenter中为图形添加了panel

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
class GuiAnimation extends JFrame
{

JButton colorBut;
JButton labelBut;
JLabel label;
PaintCanvas firstCanvas;
JPanel buttonPanel;

GuiAnimation()
{

    colorBut = new JButton("Color Change");
    labelBut = new JButton("Text Change");
    label = new JLabel("I will change");
    firstCanvas = new PaintCanvas();
    buttonPanel = new JPanel();
    addListener(); //May be i should make different method for different component for the flexibility.But here program is small.
    addEverything();
}

private void addListener()
{

    colorBut.addActionListener(new ColorListener());
    labelBut.addActionListener(new LabelListener());
}

private void setButtonInPanel()
{
    int pad = 80;
    buttonPanel.setLayout(new FlowLayout(FlowLayout.LEADING, pad, 20));
    buttonPanel.add(colorBut);
    buttonPanel.add(labelBut);
}
void addEverything()    //Here things are done with Layouts.
{
    //add the label to the top of the window.
    this.getContentPane().add(BorderLayout.NORTH, label);
    //add button inside the panel.  
    setButtonInPanel();
    //add that panel that has button to the frame.
    this.getContentPane().add(BorderLayout.SOUTH, buttonPanel);
    //add the graphics canvas to the frame.
    this.getContentPane().add(BorderLayout.CENTER, firstCanvas);
}

class PaintCanvas extends JPanel
{

    public void paintComponent(Graphics g)
    {
        int red = (int) (Math.random() * 255);
        int green = (int) (Math.random() * 255);
        int blue = (int) (Math.random() * 255);

        Color randomColor = new Color(red, green, blue);

        g.setColor(randomColor);
        g.fillRect(0, 0, getWidth(), getHeight());
    }

}

class ColorListener implements ActionListener
{

    public void actionPerformed(ActionEvent e){

        firstCanvas.repaint();
    }
}

class LabelListener implements ActionListener
{

    public void actionPerformed(ActionEvent e){

        if ( label.getText().equals("I will change"))
            label.setText("yes yes yes clicked");
        else 
            label.setText("I will change");
    }
}

 public static void main(String[] args) {

    GuiAnimation gui = new GuiAnimation();
    gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    gui.setSize(500,600);
    gui.setVisible(true);
 }
}

这是上面代码的输出。到目前为止一切顺利。

但是当我开始从右侧滑动时,会发生以下情况:

现在窗口的右墙向左移动,但按钮是静止的。继续我们得到:

但是,如果我们从左侧调整大小,我们会得到:

这里的按钮似乎与框架一起向右移动(保持与框架边界的距离)。这与前一种情况相反。但为什么?怎么样?

最后,我们有:

继续此操作,“ColorChange”按钮也变得部分不可见。

如果我们从右向左滑动而不是从左向右滑动,为什么会发生这两种不同的事情?

我已经搜索过,但我无法找到准确的答案,所以最后我在这里问:为什么和如何?

【问题讨论】:

  • 不要在paintComponent() 方法中生成随机颜色。每次调整框架大小时,背景都会改变。根据添加到框架的按钮,它应该仅在您单击“颜色更改”按钮时更改。因此,当您单击按钮时,您应该生成随机颜色并使用该颜色调用 setBackground(...) 方法。然后面板将自行重新绘制。

标签: java swing window panel frame


【解决方案1】:

这是因为你在

的差距值
int pad = 80;
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEADING, pad, 20));

。它始终是 80 像素。所以第一个按钮是always 80px 远离面板的“开始”。如果您从右向左滑动,则没有任何变化,除了一个按钮消失,因为没有足够的空间来填补 3 个空白。但是,如果您从左向右滑动,第一个按钮不会首先消失,因为如前所述,它必须从一开始就有 80px 的间隙。对不起,我的英语很糟糕,但我希望我有所帮助。

【讨论】:

  • 但是如果我不给它左右两边的任何填充,当我完全滑动到另一端时,其中一个按钮是可见的。但为什么不两者兼而有之?
  • (1+),这是正确的答案。当没有足够的空间让组件显示在第一行时,FlowLayout 将自动将组件移动到新行。如果您希望“包装”按钮也可见,那么您可以使用扩展FlowLayoutWrap Layout 来处理此行为。只需要改一行代码:buttonPanel.setLayout(new WrapLayout(WrapLayout.LEADING, pad, 20));
  • 您原来的说法是正确的,当面板显示在其preferred size:“换色”按钮前80像素处时,有3个间隙。 “颜色更改”按钮后 80 像素和“文本更改”按钮后 80 像素。随着框架的缩小,“文本更改”按钮后的间隙将减小,直到间隙完全消失,“文本更改”按钮换行到下一行。
  • @camickr 正如您所说,在“TextChange”按钮之后有一个间隙,当我们从右向左滑动时,间隙减小但是“ColorChange”按钮之前有一个间隙,为什么它不是当我们从左向右滑动时减少?换句话说,为什么在“ColorChange”按钮的情况下保持80px,而在另一种情况下则不保持?
  • @Rouftantical 这就是 FlowLayout 的工作方式,因为您使用的是左对齐。如果您使用 RIGHT 对齐方式,左侧的间隙将发生变化。如果您使用 CENTER 对齐,则两侧的间隙将发生变化。但差距在每个组件之前/之后最初是相同的。我建议了一个不同的布局管理器,它的工作方式不同,并允许您使用不同的间隙。
【解决方案2】:

您已经解释了问题,但没有解释要求。

也许你应该考虑Box Layout

panel.add( Box.createHorizontalGlue() );
panel.add( button1 );
panel.add( Box.createHorizontalStrut(20) );
panel.add( button2 );
panel.add( Box.createHorizontalGlue() );

这将创建一个面板,其中按钮保持居中,两个按钮之间有 20 像素的间隙。

【讨论】:

  • 正如你所说,在“TextChange”按钮之后有一个间隙,当我们从右向左滑动时,间隙减小但是“ColorChange”按钮之前有一个间隙,为什么它没有减小我们从左向右滑动?换句话说,为什么在“ColorChange”按钮的情况下保持80px,而在另一种情况下则不保持?
  • 我想从你这边得到一些建议。如果我只练习 GridBagLayout 是否足以编写任何类型的 GUI(几乎任何类型),以及其他 LayoutManagers 的基本知识?
  • @Rouftantical,我使用适合这项工作的任何布局管理器(或布局管理器组合)。
  • 我是否需要深入了解所有这些知识才能成为一名优秀的设计师?
【解决方案3】:

这可能是您需要的:https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/size.html

我有一段时间没有在 Swing/JavaFX 上工作了,但我相信你可以给 frame.pack();一枪。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-16
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-15
    • 1970-01-01
    • 2011-10-01
    相关资源
    最近更新 更多