问题
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();
}
});
}
}
回答1:
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
.
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);
}
回答2:
Suggestion:
There is no such constraint
BorderLayout.BOTTOM_RIGHT
with BorderLayout.BorderLayout.SOUTH
: place the component at the bottom of containerBorderLayout.EAST
: Place the component at the right side of containerBorderLayout.NORTH
: place the component at the top of containerBorderLayout.WEST
: place the component at the right side of containerBorderLayout.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.
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 conventionMyItemListener implements ItemListener
and create a new instance to add withaddItemListener(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 withitem
i.eCheckBox
,ComboBox
etc. There are other kind of Even listeners exist too e.g,ActionListener
,MouseListener
etc
Tutorial Resource:
- Writing Event Listeners
- Using Layout Managers
回答3:
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.
来源:https://stackoverflow.com/questions/19620514/place-buttons-and-text-on-new-line-and-move-them-to-the-bottom-of-the-screen-in