Place buttons and text on new line and move them t

2019-08-05 06:53发布

I Have recently started Java programming and am trying to create a login screen. However, I cannot figure out how to create a new line to put my buttons and text on. Also, I would like to move these to the bottom right corner of the JPanel. I apologise for my poor wording and hopefully you can see what I mean from my code. Please help and thank you in advance.

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();
        }
    });
}
}

3条回答
聊天终结者
2楼-- · 2019-08-05 07:33

I've taken your code and modified it to the following:

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();
            }
        });
    }
}

You really need to learn about LayoutManagers -- the Oracle/Java site has a decent one, and there are others readily available. The thing I think most of them do least well is explain overall what the managers are for and how to design things with them - they tend to plunge right into code.

A LayoutManager is applied to a Container, and tells it how to treat the components that are added to it. FlowLayout and BoxLayout tend to lay things out in a line, either horizontal or vertical at your choice. GridLayout lays things out in a table, with all 'cells' in the grid the same size. BorderLayout has a center section and one section each for N, S, E, and W; N,S stretch horizontally, E,W stretch vertically; all four of these take their other dimension from their contained component, and the center of the BorderLayout stretches in both directions to fill the available space in its container. There is GroupLayout and GridBagLayout, etc., they are all designed to solve some problem or set of problems in UI design, and you need to learn what they do in order to design Swing UIs.

Something that some of the tutorials do but don't really explain: Each container has one layout manager, but the container can be a component in another container, and the enclosing container can have a different layout manager. That's what we've done here; the BorderLayout of the overall frame puts the panel we've built at the bottom, and the right-aligned panel within our panel puts them to the right; that's how they all get to the bottom right.

You may have meant for others of your controls to be on other lines; I'll leave doing that as an exercise for you... Good luck.

One more thing: CardLayout is for situations is where, for some reason, two or more panels are arranged on TOP of each other, i.e., one obscures the other. You have no such need in your UI that I could tell, so I eliminated the CardLayout manager.

查看更多
相关推荐>>
3楼-- · 2019-08-05 07:38

As shown here, you can position your top-level container in the lower, right portion of the screen. Substitute your own components for the placeholder mentioned in getPreferredSize(). Also, consider a JToolBar, which can float on many implementations.

Addendum: I want to move the buttons to the bottom right corner of the JPanel, not move the JPanel to the bottom of the screen.

Specifying FlowLayout.RIGHT for your card1 produces the result shown. Substitute your panel having CardLayout in the content pane's BorderLayout.CENTER.

image

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);
}

Addendum: Here's an update to your example.

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);
}
查看更多
可以哭但决不认输i
4楼-- · 2019-08-05 07:57

Suggestion:

  1. There is no such constraint BorderLayout.BOTTOM_RIGHT with BorderLayout.

    • BorderLayout.SOUTH : place the component at the bottom of container
    • BorderLayout.EAST : Place the component at the right side of container
    • BorderLayout.NORTH : place the component at the top of container
    • BorderLayout.WEST : place the component at the right side of container
    • BorderLayout.CENTER: place the component at the middle of container

    If you want to orient your component as you wish, where the component will appear in order, positioned in relative to each other, responsive with Main Container's re-size, the you need to learn about Layout Manager first.

  2. Learn about Event listeners. Instead of implementing an ItemListener to a JPanel/Top level class which doesn't have such listeners, either implement it to a new class with naming convention MyItemListener implements ItemListener and create a new instance to add with addItemListener(listener) function or add them inline using the means of anonymous class.

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

    ItemListener is for the Components which works with item i.e CheckBox, ComboBox etc. There are other kind of Even listeners exist too e.g, ActionListener, MouseListener etc

Tutorial Resource:

  1. Writing Event Listeners
  2. Using Layout Managers
查看更多
登录 后发表回答