CardLayout alignment is not proper - java

I am a beginner to java. In second cardpanel the username and password alignment is not coming properly. Is there any way to fix it? I would also like to know what is the disadvantage of using multiple frames.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class CardLayoutTest extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel cardPanel, jp1, jp2, buttonPanel;
private JLabel jl1, jl2;
private JTextField jt1;
private JPasswordField jt2;
private JButton btn1, btn2;
private CardLayout cardLayout = new CardLayout();
public CardLayoutTest() {
setTitle("Login");
setSize(400, 300);
cardPanel = new JPanel();
buttonPanel = new JPanel();
cardPanel.setLayout(cardLayout);
jp1 = new JPanel();
jp2 = new JPanel();
jt1=new JTextField();
jt2=new JPasswordField();
jl1 = new JLabel("Username");
jl2 = new JLabel("Password");
//jp1.add(jl1);
jp2.add(jl1);
jp2.add(jt2);
jp2.add(jl2);
jp2.add(jt2);
cardPanel.add(jp1, "1");
cardPanel.add(jp2, "2");
btn2 = new JButton("Show Card 2");
btn2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cardLayout.show(cardPanel, "2");
}
});
buttonPanel.add(btn2);
add(cardPanel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
CardLayoutTest frame = new CardLayoutTest();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}

In second cardpanel the username and password alignment is not coming properly.
By default a JPanel uses a FlowLayout so the components are displayed on a single line.
Is there any way to fix it?
Use an appropriate layout manager (or combination of layout managers) to get the desired alignment.
Read the section from the Swing tutorial on Layout Managers for more information and examples.

Related

How to pass JTextfield info from a JDialog into a JFrame (separate classes)

I have been trying to pass the info of my JTextField that is in a JDialog into my JFrame. Both the JDialog and JFrame are in separate classes. I have tried to store the JTextField into a JLable using the .setText and .getText and then passing the JLable into the JFrame but with no luck.
I know there are many similar questions but I have tried many different approaches but still no luck. I am relatively new to Java and do not know all the in's and out's. Any help is very appreciated!
My code for the JFrame:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JPanel;
public class StockApp extends JFrame implements PropertyChangeListener {
private JPanel main = new JPanel();
private JPanel north = new JPanel();
private JPanel center = new JPanel();
private JPanel south = new JPanel();
private JButton buyStock = new JButton("Buy Stock");
private JButton sellStock = new JButton("Sell Stock");
public TestTest variables = new TestTest();
private JLabel stockNameNorth = new JLabel("Stock Name");
private JLabel stockPriceNorth = new JLabel("Stock Price");
String stockName = variables.getStockName();
String stockPrice = variables.getStockPrice();
public StockApp() {
setTitle("StockApp");
getContentPane().setBackground(Color.white);
setSize(400,400);
setLocation(500,200);
setVisible(true);
main.setLayout(new BorderLayout());
north.setLayout(new FlowLayout());
center.setLayout(new FlowLayout());
south.setLayout(new FlowLayout());
stockNameNorth.setText(stockName);
stockPriceNorth.setText(stockPrice);
add(main);
north.add(stockNameNorth);
north.add(stockPriceNorth);
south.add(buyStock);
south.add(sellStock);
main.add(north, BorderLayout.NORTH);
main.add(center, BorderLayout.CENTER);
main.add(south, BorderLayout.SOUTH);
}
}
And Dialog:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestTest extends JDialog implements ActionListener {
private JPanel main = new JPanel();
private JPanel north = new JPanel();
private JPanel center = new JPanel();
private JPanel south = new JPanel();
private JLabel stockNameLabel = new JLabel("Stock name: ");
private JLabel stockPriceLabel = new JLabel("Stock price(£): ");
private JTextField stockNameIn = new JTextField(5);
private JTextField stockPriceIn = new JTextField(5);
private JButton buttonOK = new JButton("OK");
public JLabel stockPrice = new JLabel();
public JLabel stockName = new JLabel();
public TestTest() {
getContentPane().setBackground(Color.white);
setSize(400,400);
setLocation(500,200);
setModal(false);
setVisible(true);
getRootPane().setDefaultButton(buttonOK);
main.setLayout(new BorderLayout());
north.setLayout(new FlowLayout());
center.setLayout(new FlowLayout());
south.setLayout(new FlowLayout());
add(main);
north.add(stockNameLabel);
north.add(stockNameIn);
center.add(stockPriceLabel);
center.add(stockPriceIn);
south.add(buttonOK);
main.add(north, BorderLayout.NORTH);
main.add(center, BorderLayout.CENTER);
main.add(south, BorderLayout.SOUTH);
buttonOK.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == buttonOK){
stockName.setText(stockNameIn.getText());
stockPrice.setText(stockPriceIn.getText());
dispose();
new StockApp();
}
}
public String getStockName() {
return stockNameIn.getText();
}
public String getStockPrice() {
return stockPriceIn.getText();
}
}
I am trying to pass the stockName and stockPrice variables from the JDialog into the JFrame. I then want the name and price to display at the top of the JFrame.
For demonstration, what the problem is, we need less Fields and Buttons.
So far, no component of StockApp needs to be accessed from different methods, so there is no need to make them visible outside of the ctor.
More explanations in the code.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
public class StockApp extends JFrame {
public StockApp() {
// move those unreferenced panels here, so we don't have to reason about them:
JPanel main = new JPanel();
JPanel north = new JPanel();
JPanel center = new JPanel();
JPanel south = new JPanel();
// add price later, when name works
JButton buyStock = new JButton("Buy Stock");
JLabel stockNameNorth = new JLabel("Stock Name");
// critical change: Make the label, which you like to update,
// accessible by whom it should be updated:
TestTest variables = new TestTest (stockNameNorth);
setTitle ("StockApp");
getContentPane().setBackground(Color.white);
setSize (600,400);
setLocation (500,200);
setVisible (true);
// make the close-frame action terminate the program:
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
main.setLayout (new BorderLayout());
north.setLayout (new FlowLayout());
center.setLayout (new FlowLayout());
south.setLayout (new FlowLayout());
add (main);
north.add (stockNameNorth);
south.add (buyStock);
main.add (north, BorderLayout.NORTH);
main.add (center, BorderLayout.CENTER);
main.add (south, BorderLayout.SOUTH);
}
// Main method to start the damn thing
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new StockApp ();
}
});
}
}
// no need to make this class public in a short test:
class TestTest extends JDialog implements ActionListener {
// this are elements, visible outside the construction phase,
// we need to have access to from more than one method.
// Make this important distinction visible to the reader:
JLabel name;
JTextField stockNameIn = new JTextField (5);
JButton buttonOK = new JButton ("OK");
// add the JLabel to update to the ctor, so that it can't be forgotten
// to be set
public TestTest (JLabel pname) {
// we copy the reference to the label, to have access to it in
// the actionPerformed method.
name = pname;
JPanel main = new JPanel();
JPanel north = new JPanel();
JPanel center = new JPanel();
JPanel south = new JPanel();
JLabel stockNameLabel = new JLabel ("Stock name: ");
getContentPane().setBackground(Color.white);
// different size/location than frame, so that they don't hide
// each other completly
setSize (400,600);
setLocation (700,300);
setModal (false);
setVisible (true);
getRootPane().setDefaultButton(buttonOK);
main.setLayout (new BorderLayout());
north.setLayout (new FlowLayout());
center.setLayout (new FlowLayout());
south.setLayout (new FlowLayout());
add (main);
north.add (stockNameLabel);
north.add (stockNameIn);
south.add (buttonOK);
main.add (north, BorderLayout.NORTH);
main.add (center, BorderLayout.CENTER);
main.add (south, BorderLayout.SOUTH);
buttonOK.addActionListener(this);
}
// here we need access to the button - was it the OK-Button, clicked?
// and the textfield stockNameIn, to read the text
// and the name field from the frame, to set the text
public void actionPerformed(ActionEvent e) {
if (e.getSource () == buttonOK) {
name.setText (stockNameIn.getText());
dispose();
}
}
}

How to tidy up code into class files and methods

I am still learning Java and I am currently creating a program in Swing. I have been confused regarding when and when I should use methods and class files. I have created an application that has two cards, card 1: homeJPanel and card 2: guestFixturesJPanel and I want these to switch between each other on button click - which i have done to an extent. However, my code looks extremely messy and is hard to look at as all JPanels are in one method. I was wondering if there was any way I could put guestFixturesJPanel into a separate method or class file and still be able to call the card on button click. Is this possible? Also, does anyone know of any good tutorials that explain methods and class files well as I have been confused and this may be the solution to my problem.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
public class Main
{
protected static final Component c1 = null;
private JButton viewFixturesButton, loginButton, guestBackButton;
private JLabel testTextJLabel, testTextJLabel2;
JPanel container = new JPanel();
CardLayout cardLayout = new CardLayout();
public Main()
{
final JFrame window = new JFrame ("Main Game");
final CardLayout c1 = new CardLayout();
final JPanel container = new JPanel(c1);
JPanel homeJPanel = new JPanel(new BorderLayout());
container.add(homeJPanel);
JPanel centerJPanel = new JPanel(new BorderLayout());
testTextJLabel = new JLabel("TEST");
centerJPanel.add(testTextJLabel);
JPanel southPanel = new JPanel(new FlowLayout());
viewFixturesButton = new JButton("View Fixtures");
loginButton = new JButton("Login");
southPanel.add(viewFixturesButton);
southPanel.add(loginButton);
homeJPanel.add(centerJPanel, BorderLayout.CENTER);
homeJPanel.add(southPanel, BorderLayout.SOUTH);
centerJPanel.setBackground(Color.BLUE);
southPanel.setBackground(Color.GREEN);
JPanel guestFixturesJPanel = new JPanel(new BorderLayout());
container.add(guestFixturesJPanel);
JPanel guestCenterJPanel = new JPanel(new BorderLayout());
JPanel guestSouthPanel = new JPanel(new FlowLayout());
guestBackButton = new JButton("Back");
guestSouthPanel.add(guestBackButton);
guestFixturesJPanel.add(guestCenterJPanel, BorderLayout.CENTER);
guestFixturesJPanel.add(guestSouthPanel, BorderLayout.SOUTH);
guestCenterJPanel.setBackground(Color.BLUE);
guestSouthPanel.setBackground(Color.GREEN);
viewFixturesButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
c1.show(container, "2");
}
});
container.add(homeJPanel, "1");
container.add(guestFixturesJPanel, "2");
c1.show(container, "1");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(container);
window.setSize(600, 500);
window.setLocationRelativeTo(null);
window.setVisible(true);
window.setResizable(false);
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new Main();
}
});
}
}
You could extract the guestFixturesPanel to a class of its own like this:
public class GuestFixturesPanel extends JPanel {
public GuestFixturesPanel() {
this.setLayout(new BorderLayout());
JPanel guestCenterJPanel = new JPanel(new BorderLayout());
JPanel guestSouthPanel = new JPanel(new FlowLayout());
JButton guestBackButton = new JButton("Back");
guestSouthPanel.add(guestBackButton);
add(guestCenterJPanel, BorderLayout.CENTER);
add(guestSouthPanel, BorderLayout.SOUTH);
guestCenterJPanel.setBackground(Color.BLUE);
guestSouthPanel.setBackground(Color.GREEN);
}
}
Then in your Main class you could instantiate a GuestFixturesPanel and add it to your container. This would preserve the functionality you have now, and extract the code out of your Main class.
GuestFixturesPanel guestFixturesPanel = new GuestFixturesPanel();
container.add(guestFixturesPanel, "2");
Not sure if that addresses the question you had, but I hope this helps.

How to set Jbuttons to a specific place when you have a background in JLabel : code below

How to set Jbuttons to a specific place when you have a background in JLabel : code below
i can't get the jlabel to stay at the top and the buttons to stay south(bottom) ??
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonsClass extends JFrame
implements ActionListener {
JButton b1 = new JButton("button1");
JButton b2 = new JButton("button2");
JButton b3 = new JButton("button3");
JButton b4 = new JButton("button4");
JLabel label = new JLabel("buttons:");
public static void main(String[] args) {
new ButtonsClass();
}
public Jukebox() {
setLayout(new BorderLayout());
setContentPane(new JLabel(new ImageIcon("image.png")));
setLayout(new FlowLayout());
setSize(500,150);
setTitle("Backgroundwithbuttons");
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
JPanel top = new JPanel();
top.add(label);
add("North", top);
JPanel bottom = new JPanel();
bottom.add(b1);
bottom.add(b2);
bottom.add(b3);
bottom.add(b4);
add("South", bottom);
setVisible(true);
}
}
" i can't get the jlabel to stay at the top and the buttons to stay south(bottom)"
That's because you set the layout the BorderLayout, then immediately set it to FlowLayout. With FlowLayout, your BorderLayout positioning will do nothing.
setLayout(new BorderLayout());
setContentPane(new JLabel(new ImageIcon("image.png")));
setLayout(new FlowLayout());
Just get rid of the setLayout(new FlowLayout());
Also your constructor is wrong
public Jukebox() {
-Should be-
public ButtonClass() {
Also you need to set the layout of the JLabel that you set as the content pane. Yout constructor should look like this
public ButtonClass() {
JLabel background = new JLabel(new ImageIcon("image.png"));
background.setLayout(new BorderLayout());
setContentPane(background);
setTitle("Background with buttons");
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
JPanel top = new JPanel();
top.add(label);
add(top, BorderLayout.NORTH);
JPanel bottom = new JPanel();
bottom.add(b1);
bottom.add(b2);
bottom.add(b3);
bottom.add(b4);
add(bottom, BorderLayout.SOUTH);
//pack();
setVisible(true);
}
Also, add("North", top); is a deprecated method. Instead use add(top, BorderLayout.NORTH) and same for add(bottom, BorderLayout.SOUTH)
Also, Swing apps should be run on the Event Dispatch Thread. You can do so by wrapping the code in your main with a SwingUtilities.invokeLater...
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ButtonClass();
}
});
}
Also, you should set the panel's opaque property to false, if you want the image to show behind them.
top.setOpaque(false);
bottom.setOpaque(false);
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonClass extends JFrame
implements ActionListener {
JButton b1 = new JButton("button1");
JButton b2 = new JButton("button2");
JButton b3 = new JButton("button3");
JButton b4 = new JButton("button4");
JLabel label = new JLabel("buttons:");
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ButtonClass();
}
});
}
public ButtonClass() {
label.setForeground(Color.WHITE);
JLabel background = new JLabel(new ImageIcon(getClass().getResource("/resources/space.png")));
background.setLayout(new BorderLayout());
setContentPane(background);
setTitle("Background with buttons");
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
JPanel top = new JPanel();
top.setOpaque(false);
top.add(label);
add(top, BorderLayout.NORTH);
JPanel bottom = new JPanel();
bottom.setOpaque(false);
bottom.add(b1);
bottom.add(b2);
bottom.add(b3);
bottom.add(b4);
add(bottom, BorderLayout.SOUTH);
setSize(400, 300);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {}
}
Try using:
add(bottom, BorderLayout.SOUTH);
instead of:
add("South", bottom);
BorderLayout tutorial

Dynamically add components to a JDialog on button click

I want to know how to add components dynamically to a JDialog. I know there is a similar question on SO here, but as you can see, I have his solution as a part of my code.
So the idea is that on click of the button, I need to add a component on the dialog. The sample code is below:
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Test extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
public static void main(String args[]) {
Test test = new Test();
test.createDialog();
}
public void createDialog() {
DynamicDialog dialog = new DynamicDialog(this);
dialog.setSize(300, 300);
dialog.setVisible(true);
}
}
class DynamicDialog extends JDialog {
/**
*
*/
private static final long serialVersionUID = 1L;
public DynamicDialog(final JFrame owner) {
super(owner, "Dialog Title", Dialog.DEFAULT_MODALITY_TYPE);
final JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
final JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.add(Box.createRigidArea(new Dimension(3, 10)));
panel.add(createLabel("Click on add"));
panel.add(Box.createRigidArea(new Dimension(23, 10)));
panel.add(createLabel("To add another line of text"));
panel.add(Box.createHorizontalGlue());
mainPanel.add(panel);
mainPanel.add(Box.createRigidArea(new Dimension(3, 10)));
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
buttonPanel.add(Box.createHorizontalGlue());
JButton button = new JButton();
button.setText("Add another line");
buttonPanel.add(button);
mainPanel.add(buttonPanel);
mainPanel.add(Box.createRigidArea(new Dimension(3, 10)));
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
Container contentPane = owner.getContentPane();
JPanel _panel = new JPanel();
_panel.setLayout(new BoxLayout(_panel, BoxLayout.X_AXIS));
_panel.add(Box.createHorizontalGlue());
_panel.add(createLabel("Added!"));
contentPane.add(_panel);
contentPane.validate();
contentPane.repaint();
owner.pack();
}
});
pack();
setLocationRelativeTo(owner);
this.add(mainPanel);
}
JLabel createLabel(String name) {
JLabel label = new JLabel(name);
return label;
}
}
If you add it to the main panel it will work, you were adding it to the content pane of the frame which it seems it does not show up anywhere.
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
JPanel _panel = new JPanel();
_panel.setLayout(new BoxLayout(_panel, BoxLayout.X_AXIS));
_panel.add(Box.createHorizontalGlue());
_panel.add(createLabel("Added!"));
mainPanel.add(_panel);
mainPanel.validate();
mainPanel.repaint();
owner.pack();
}
})

Creating a window - but buttons layout error

I made a small program with two buttons. I label
the buttons one exiting the program and the second importing files.
I actually let them both to exit the program when ever someone pressed on it
the problem is the buttons taking all the window, why?
I tried GridBagConstraints to resize the buttons some how but no luck anyway here's the full class without imports..
public class Window2 extends JFrame{
private static final long serialVersionUID = 1L;
public Window2(){
super ("ALANAZ imagtor");
setSize(600,400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel pnl1 = new JPanel(new GridLayout());
JPanel pnl2 = new JPanel();
//button
JButton butn1 = new JButton("EXIT");
JButton butn2 =new JButton("IMPORT");
butn1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
JOptionPane.showMessageDialog(null, "exiting ... bye...");
System.exit(0);
}
});
butn2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
JOptionPane.showMessageDialog(null, "can't import now exiting");
System.exit(0);
}
});
GridBagConstraints gb1 = new GridBagConstraints();
gb1.insets = new Insets(15,15,15,15);
//Jlabel
JLabel lbl1 = new JLabel("exit or import an image");
pnl1.add(butn1);
pnl1.add(butn2);
pnl2.add(lbl1);
add(pnl2, BorderLayout.SOUTH);
add(pnl1, BorderLayout.CENTER);
}}
You are misusing your layout managers. Your pnl1 JPanel uses GridLayout (without any row or column constants?!), and if you only add one component to it, it will take up the entire JPanel. You seem to have GridBagConstraints in your code, but no GridBagLayout, which is confusing to me.
The solution is to read up on and understand how to use layout managers. Please have a look at the tutorial link: Laying Out Components Within a Container.
Key is to keep remembering that you can nest JPanels within JPanels. For example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;
public class Window2 extends JFrame {
private static final long serialVersionUID = 1L;
private static final int PREF_W = 600;
private static final int PREF_H = 400;
public Window2() {
super("ALANAZ imagtor");
setDefaultCloseOperation(EXIT_ON_CLOSE);
int gap = 3;
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, gap, 0));
buttonPanel.setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
JPanel pnl2 = new JPanel();
JButton butn1 = new JButton("EXIT");
JButton butn2 = new JButton("IMPORT");
butn1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "exiting ... bye...");
System.exit(0);
}
});
butn2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
JOptionPane.showMessageDialog(null, "can't import now exiting");
System.exit(0);
}
});
JLabel lbl1 = new JLabel("exit or import an image");
buttonPanel.add(butn1);
buttonPanel.add(butn2);
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.add(buttonPanel, BorderLayout.SOUTH);
pnl2.add(lbl1);
add(pnl2, BorderLayout.SOUTH);
add(centerPanel, BorderLayout.CENTER);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public static void main(String[] args) {
Window2 win2 = new Window2();
win2.pack();
win2.setLocationRelativeTo(null);
win2.setVisible(true);
}
}
If you initialize your panel with a BorderLayout instead, and add your buttons using EAST, NORTH, WEST, SOUTH, you will have a quick fix - however I do also recommend reading up on layout managers
JPanel pnl1 = new JPanel(new BorderLayout());
pnl1.add(new JButton(), BorderLayout.SOUTH);

Categories