1

我最近开始了 Java 编程,正在尝试创建一个登录屏幕。但是,我无法弄清楚如何创建一个新行来放置我的按钮和文本。另外,我想将这些移动到 JPanel 的右下角。我为我糟糕的措辞道歉,希望你能从我的代码中明白我的意思。请帮助并提前感谢您。

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

public class CardLayoutDemo implements ItemListener {
JPanel cards;
final static String BUTTONPANEL = "Card with JButtons";

public void addComponentToPane(Container pane) {

    JPanel card1 = new JPanel();
    card1.add(new JLabel("Username:"));
    card1.add(new JTextField("Username", 10));
    card1.add(new JButton("Login")); //end line here
    //New line
    card1.add(new JLabel("Password:"));
    card1.add(new JTextField("Password", 10));
    card1.add(new JButton("Register")); //end line here
    //New line
    card1.add(new JCheckBox());
    card1.add(new JLabel("Remember credentials"));


    cards = new JPanel(new CardLayout());
    cards.add(card1, BUTTONPANEL);

    pane.add(cards, BorderLayout.BOTTOM_RIGHT);// Add cards to bottom right hand corner.
}

public void itemStateChanged(ItemEvent evt) {
    CardLayout cl = (CardLayout)(cards.getLayout());
    cl.show(cards, (String)evt.getItem());
}

private static void createAndShowGUI() {
    JFrame frame = new JFrame("Login");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    CardLayoutDemo demo = new CardLayoutDemo();
    demo.addComponentToPane(frame.getContentPane());

    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {

    try {

        UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
    } catch (UnsupportedLookAndFeelException ex) {
        ex.printStackTrace();
    } catch (IllegalAccessException ex) {
        ex.printStackTrace();
    } catch (InstantiationException ex) {
        ex.printStackTrace();
    } catch (ClassNotFoundException ex) {
        ex.printStackTrace();
    }

    UIManager.put("swing.boldMetal", Boolean.FALSE);

    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}
}
4

3 回答 3

5

如此处所示,您可以将顶级容器放置在屏幕的右下方。用您自己的组件替换getPreferredSize(). 另外,考虑 a JToolBar,它可以在许多实现上浮动。

附录:我想将按钮移动到右下角,而 JPanel不是移动 JPanel 到屏幕底部。

FlowLayout.RIGHT为您指定card1会产生显示的结果。替换您的面板CardLayout在内容窗格的BorderLayout.CENTER.

图片

public void addComponentToPane(Container pane) {

    JPanel card1 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
    …
    pane.add(new JPanel() {
        @Override // placeholder for actual content
        public Dimension getPreferredSize() {
            return new Dimension(800, 200);
        }
    }, BorderLayout.CENTER);
    pane.add(cards, BorderLayout.PAGE_END);
}

附录:这是您的示例的更新。

public void addComponentToPane(Container pane) {
    …
    pane.add(cards, BorderLayout.PAGE_END);
}
…
private static void createAndShowGUI() {
    JFrame frame = new JFrame("Login");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // Move frame to lower right corner of screen
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice defaultScreen = ge.getDefaultScreenDevice();
    Rectangle rect = defaultScreen.getDefaultConfiguration().getBounds();
    int x = (int) rect.getMaxX() - frame.getWidth();
    int y = (int) rect.getMaxY() - frame.getHeight();
    frame.setLocation(x, y);

    CardLayoutDemo demo = new CardLayoutDemo();
    demo.addComponentToPane(frame.getContentPane());

    frame.pack();
    frame.setVisible(true);
}
于 2013-10-27T17:25:52.137 回答
3

建议:

  1. 没有这样BorderLayout.BOTTOM_RIGHT的约束BorderLayout

    • BorderLayout.SOUTH: 将组件放在容器底部
    • BorderLayout.EAST : 将组件放在容器的右侧
    • BorderLayout.NORTH: 将组件放在容器的顶部
    • BorderLayout.WEST : 将组件放在容器的右侧
    • BorderLayout.CENTER: 将组件放在容器的中间

    如果您想根据需要定位组件,组件将按顺序显示,相对于彼此定位,响应主容器的重新大小,您需要先 了解布局管理器

  2. 了解事件监听器。与其实现一个ItemListener没有此类侦听器的 JPanel/顶级类,不如将其实现为具有命名约定的新类MyItemListener implements ItemListener并创建一个新实例以添加addItemListener(listener)函数或使用匿名类的方式将它们内联添加。

     checkBox.addItemListener(new ItemListener() {
    
        @Override
        public void itemStateChanged(ItemEvent e) {
           // put your code
        }
    });
    

    ItemListener适用于与itemieCheckBox等一起使用的组件ComboBox。还有其他类型的 Even 监听器也存在,例如ActionListener,MouseListener

教程资源:

  1. 编写事件监听器
  2. 使用布局管理器
于 2013-10-27T17:12:53.900 回答
1

我已获取您的代码并将其修改为以下内容:

package sandbox;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class LoginLayoutDemo
{
    JPanel cards;

    public void addComponentToPane(Container pane)
    {
        // Panel for text and fields
        JPanel textAndFieldsPanel = new JPanel();
        textAndFieldsPanel.setLayout(new GridLayout(2,2));
        textAndFieldsPanel.add(new JLabel("Username ", JLabel.RIGHT));
        textAndFieldsPanel.add(new JTextField("Username", 10));
        textAndFieldsPanel.add(new JLabel("Password ", JLabel.RIGHT));
        textAndFieldsPanel.add(new JPasswordField("password", 10));

        JPanel controlsPanel = new JPanel();
        controlsPanel.setLayout(new BoxLayout(controlsPanel, BoxLayout.PAGE_AXIS));

        controlsPanel.add(textAndFieldsPanel);
        controlsPanel.add(new JCheckBox("Remember credentials"));

        JPanel bottomPanel = new JPanel();

        bottomPanel.add(controlsPanel);
        bottomPanel.add(new JButton("Login")); // end line here

        bottomPanel.add(new JButton("Register")); // end line here

        cards = new JPanel(new BorderLayout());
//      cards.setLayout(new BorderLayout(cards, BoxLayout.LINE_AXIS));
        cards.add(bottomPanel, BorderLayout.LINE_END);

        pane.add(cards, BorderLayout.PAGE_END);   // BOTTOM_RIGHT);// Add cards to bottom right hand
                                                                                                // corner.
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("Login");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//      CardLayoutDemo demo = new CardLayoutDemo();
        new LoginLayoutDemo().addComponentToPane(frame.getContentPane());

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {

        try
        {

            UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
        } catch (UnsupportedLookAndFeelException ex)
        {
            ex.printStackTrace();
        } catch (IllegalAccessException ex)
        {
            ex.printStackTrace();
        } catch (InstantiationException ex)
        {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex)
        {
            ex.printStackTrace();
        }

        UIManager.put("swing.boldMetal", Boolean.FALSE);

        javax.swing.SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
}

您确实需要了解 LayoutManagers —— Oracle/Java 站点有一个不错的,还有其他现成的。我认为他们中的大多数人做得最差的事情是总体上解释经理的用途以及如何与他们一起设计事物-他们倾向于直接投入到代码中。

一个 LayoutManager 应用于一个 Container,并告诉它如何处理添加到它的组件。FlowLayout 和 BoxLayout 倾向于将事物排成一行,可以选择水平或垂直。GridLayout 将事物布置在表格中,网格中的所有“单元格”大小相同。BorderLayout 有一个中心部分和一个用于 N、S、E 和 W 的部分;N,S 水平拉伸,E,W 垂直拉伸;所有这四个都从其包含的组件中获取其他维度,并且 BorderLayout 的中心在两个方向上延伸以填充其容器中的可用空间。有 GroupLayout 和 GridBagLayout 等,它们都是为解决 UI 设计中的某个问题或一组问题而设计的,您需要了解它们的作用才能设计 Swing UI。

一些教程做了但没有真正解释的事情:每个容器都有一个布局管理器,但容器可以是另一个容器中的组件,并且封闭容器可以有不同的布局管理器。这就是我们在这里所做的;整个框架的 BorderLayout 将我们构建的面板放在底部,而我们面板中的右对齐面板将它们放在右侧;这就是他们都到达右下角的方式。

您可能打算让您的其他控件位于其他线路上;我将把它作为练习留给你......祝你好运。

还有一件事:CardLayout 适用于以下情况:由于某种原因,两个或多个面板彼此重叠排列,即一个遮挡另一个。我可以告诉您,您的 UI 中没有这种需求,因此我取消了 CardLayout 管理器。

于 2013-10-28T01:10:35.670 回答