Java how to add image as background in layout - java

I have a class that uses a CardLayout which has two cards that have a button on them. What I would like to be able to do is put an image that would act like a background such as a desktop background in Windows. The program eventually will have several different cards and I'd like to be able to put different backgrounds on each card. I've tried many suggestions posed in other similar questions on this site as well as whatever I can find through googling it, but I just can't seem to get it to work. I understand that with the CardLayout I can't put a panel on top of a panel, so putting an image on a JPanel wouldn't work. So my question is, based off the code posted below, is there a better way for me to setup my layout so that it works better, and also, how should I approach displaying the image so that it is in the background of the buttons? Any help would be greatly appreciated.
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Cards implements ActionListener {
private JPanel cards;
private JButton button1;
private JButton button2;
private Image backgroundImage;
public void addComponentToPane(Container pane) throws IOException {
backgroundImage = ImageIO.read(new File("background.jpg"));
//create cards
JPanel card1 = new JPanel()
{
#Override
public void paintComponent(Graphics g)
{
g.drawImage(backgroundImage, 0, 0, null);
}
};
JPanel card2 = new JPanel();
button1 = new JButton("Button 1");
button2 = new JButton("Button 2");
button1.addActionListener(this);
button2.addActionListener(this);
card1.add(button1);
card2.add(button2);
//create panel that contains cards
cards = new JPanel(new CardLayout());
cards.add(card1, "Card 1");
cards.add(card2, "Card 2");
pane.add(cards, BorderLayout.SOUTH);
}
public void itemStateChanged(ItemEvent evt) {
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, (String)evt.getItem());
}
public static void createAndShowGUI() throws IOException {
//create and setup window
JFrame frame = new JFrame("Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//create and setup content pane
Cards main = new Cards();
main.addComponentToPane(frame.getContentPane());
//display window
frame.pack();
frame.setSize(800, 600);
frame.setResizable(false);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == button1) {
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, "Card 2");
} else if (ae.getSource() == button2) {
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, "Card 1");
}
}
public static void main(String[] args) {
//set look and feel
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();
}
//schedule job for the event dispatch thread creating and showing GUI
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
createAndShowGUI();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}

You need to override the method paintComponent(Graphics g) of JPanel and use drawImage() on the Graphics object g as in this example.
Also, check these two examples by #trashgod:
example.
example.

#Eng.Fouad's answer is well chosen, but the image probably dominates the layout. You might want to override getPreferredSize() as shown below. Then you can just pack() the window, and the size will be right. See also Loading Images Using getResource.
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Cards implements ActionListener {
private JPanel cards;
private JButton button1;
private JButton button2;
private Image backgroundImage;
public void addComponentToPane(Container pane) {
try {
backgroundImage = ImageIO.read(new File("background.jpg"));
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
//create cards
JPanel card1 = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(backgroundImage, 0, 0, null);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(
backgroundImage.getWidth(null),
backgroundImage.getHeight(null));
}
};
JPanel card2 = new JPanel();
button1 = new JButton("Button 1");
button2 = new JButton("Button 2");
button1.addActionListener(this);
button2.addActionListener(this);
card1.add(button1);
card2.add(button2);
//create panel that contains cards
cards = new JPanel(new CardLayout());
cards.add(card1, "Card 1");
cards.add(card2, "Card 2");
pane.add(cards, BorderLayout.SOUTH);
}
public void itemStateChanged(ItemEvent evt) {
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, (String) evt.getItem());
}
public static void createAndShowGUI() {
//create and setup window
JFrame frame = new JFrame("Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//create and setup content pane
Cards main = new Cards();
main.addComponentToPane(frame.getContentPane());
//display window
frame.pack();
frame.setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == button1) {
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, "Card 2");
} else if (ae.getSource() == button2) {
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, "Card 1");
}
}
public static void main(String[] args) {
//schedule job for the event dispatch thread creating and showing GUI
EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

Related

Best way to switch Panels in Frame

I have started working with JFrames and am creating a simple programme with 3 panels that are different colours and I was just wondering what would be the best way to switch between panels for my programme. The panels are to be changed when a JMenuItem with the colours name is selected. I was looking at cards and was wondering if they would be a good solution and if it would be possible to implement them into my programme? Any other suggestions would be greatly appreciated & apologies if I have done anything wrong ive only started on stack overflow and am quite a newcomer to Java :)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Colour extends JFrame
{
CardLayout card;
JPanel childPanel = new JPanel(), redPanel, bluePanel, greenPanel;
Container c;
public Colour(){
// Get Container
c=getContentPane();
//Create Menu and items
childPanel = new JPanel();
JMenuBar menuBar = new JMenuBar();
JMenu customer = new JMenu("Colour");
customer.setMnemonic(KeyEvent.VK_U);
JMenuItem blue = new JMenuItem("Blue");
JMenuItem red = new JMenuItem("Red");
JMenuItem green = new JMenuItem("Green");
customer.add(blue);
customer.add(red);
customer.add(green);
menuBar.add(customer);
this.setJMenuBar(menuBar);
//Adding panel to container
c.add(childPanel);
childPanel.setBackground(Color.PINK);
//Action Listeners for switching panels
blue.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
} );
red.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
} );
green.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
} );}
//Creating my different panels and adding them to childPanel
public void redC() {
redPanel = new JPanel();
redPanel.setBackground(Color.RED);
childPanel.add(redPanel, "Red");
}
public void blueC() {
bluePanel = new JPanel();
bluePanel.setBackground(Color.BLUE);
childPanel.add(bluePanel, "Blue");
}
public void greenC() {
greenPanel = new JPanel();
greenPanel.setBackground(Color.GREEN);
childPanel.add(greenPanel, "Green");
}
public static void main(String[] args) {
Colour cl=new Colour();
cl.setSize(400,400);
cl.setVisible(true);
cl.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
You are almost done with you code.
Here is the working code.
You need to revalidate the childPanel after adding/removing a panel so that it will be repainted:
//Action Listeners for switching panels
blue.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (childPanel.getComponentCount() >0)
childPanel.remove(0);
blueC();
childPanel.revalidate();
}
});
red.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (childPanel.getComponentCount() > 0)
childPanel.removeAll();
redC();
childPanel.revalidate();
}
});
green.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (childPanel.getComponentCount() > 0)
childPanel.remove(0);
greenC();
childPanel.revalidate();
}
});

Card Layout - Get Input from previous Card

I need a running order of pages 1-5 pages. I am using the card layout to navigate between each page after entering data on each page. The navigation to the next page works via an Action Listener on each text field.
My question is how do I pass the input from each card/page to the next? I can System.out.println each TextFeilds data. But I can't grab this information in the next card/action listener. The reason I need this to happen is I'd like to compare the strings of each page and also display a label of page 1's input on page/card2.
I apologize in advance for the massive block of code... Most of you will recognise most of this code anyway as it's copied from the CardLayout sample java code. I have just added two cards just now until I get the basics of passing variables back and fourth.
All help is appreciated even a small push the the right direction.
import java.awt.*;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Scanner;
import javax.swing.*;
public class CardLayoutDemo implements ItemListener {
JPanel cards; //a panel that uses CardLayout
final static String TEXTPANEL = "Card1 with text";
final static String TEXTPANEL2 = "Card with JTextField";
public void addComponentToPane(Container pane) {
//Put the JComboBox in a JPanel to get a nicer look.
JPanel comboBoxPane = new JPanel(); //use FlowLayout
String comboBoxItems[] = { TEXTPANEL, TEXTPANEL2};
JComboBox cb = new JComboBox(comboBoxItems);
cb.setEditable(false);
cb.addItemListener(this);
comboBoxPane.add(cb);
//Create the "cards".
JPanel card1 = new JPanel();
JTextField jtf=new JTextField("", 40);
jtf.setSize(40, 10);
card1.add(jtf);
JLabel lab1 = new JLabel("Page1 Text", JLabel.LEFT);
card1.add(lab1 = new JLabel("Page1"));
JPanel card2 = new JPanel();
JTextField jtf2=new JTextField("", 40);
jtf2.setSize(40, 10);
card2.add(jtf2);
JLabel lab2 = new JLabel("Page2 Text", JLabel.LEFT);
card2.add(lab2 = new JLabel("Page2 "));
//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(card1, TEXTPANEL);
cards.add(card2, TEXTPANEL2);
pane.add(cards, BorderLayout.CENTER);
jtf.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String getText1 = jtf.getText();
System.out.println("PAGE1 ");
System.out.println(getText1);
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, TEXTPANEL2);
jtf2.requestFocus();
jtf2.requestFocusInWindow();
}
//JOptionPane.showMessageDialog(null,"Action Listener is working");
});
//PAGE2
jtf2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String getText2 = jtf2.getText();
System.out.println("PAGE2 ");
System.out.println(getText2);
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, TEXTPANEL);
jtf.requestFocus();
jtf.requestFocusInWindow();
jtf.setText("");
}
});
}//ADD COMPONENT TO PANE
public void itemStateChanged(ItemEvent evt) {
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, (String)evt.getItem());
// String getLoginUser1 = jtf.getText();
//System.out.println(getLoginUser1);
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event dispatch thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("CardLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(600, 300));
JFrame.setDefaultLookAndFeelDecorated(true);
//Create and set up the content pane.
CardLayoutDemo demo = new CardLayoutDemo();
demo.addComponentToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
/* Use an appropriate Look and Feel */
try {
//UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
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();
}
/* Turn off metal's use of bold fonts */
UIManager.put("swing.boldMetal", Boolean.FALSE);
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Here is another view on the problem. You could create some kind of cards manager and hold all required info inside of it. Here is an example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
public class CardLayoutDemo implements ItemListener {
private static class QuizManager {
final java.util.List<String> quizData = new ArrayList<>();
final java.util.List<JPanel> cards = new ArrayList<>();
final JPanel rootView;
public QuizManager(JPanel root){
rootView = root;
}
private JPanel createQuizPanel(String pageText, final int index) {
JPanel card = new JPanel();
JTextField jtf=new JTextField("", 40);
jtf.setSize(40, 10);
JLabel prev = new JLabel("", JLabel.LEFT);
card.add(prev);
card.add(jtf);
card.add(new JLabel(pageText, JLabel.LEFT));
jtf.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
QuizManager.this.onCardSubmited(card, index, jtf.getText());
}
});
card.addComponentListener(new ComponentAdapter() {
#Override
public void componentShown(ComponentEvent e) {
super.componentShown(e);
jtf.requestFocus();
jtf.requestFocusInWindow();
String text = QuizManager.this.getPrevStringFor(index);
if (text != null) {
prev.setText(text);
}
}
});
return card;
}
private String getPrevStringFor(int index) {
if (index == 0) return null;
return quizData.get(index-1);
}
private String buildPanelName(int index) {
return String.format("card-%d", index);
}
public QuizManager addCard(String title) {
int index = cards.size();
quizData.add(null);//not set yet, just allocating
JPanel card = createQuizPanel(title, index);
cards.add(card);//this array looks like redundant
rootView.add(card, buildPanelName(index));
return this;
}
private void showCard(int index) {
CardLayout cl = (CardLayout) (rootView.getLayout());
cl.show(rootView, buildPanelName(index));
}
public void show() {
showCard(0);
}
public void onCardSubmited(JPanel card, int cardIndex, String text) {
System.out.println("page " + cardIndex);
System.out.println("text : " + text);
quizData.set(cardIndex, text);
if (cardIndex < cards.size() - 1) {
showCard(cardIndex + 1);
} else {
System.out.println("WE FINISHED");
//add finalazing code here
}
}
}
JPanel cardsRoot;
public void addComponentToPane(Container pane) {
cardsRoot = new JPanel(new CardLayout());
QuizManager manager = new QuizManager(cardsRoot)
.addCard("First page")
.addCard("Second page")
.addCard("Third card")
.addCard("Forth card");
pane.add(cardsRoot, BorderLayout.CENTER);
manager.show();
}
public void itemStateChanged(ItemEvent evt) {
CardLayout cl = (CardLayout)(cardsRoot.getLayout());
cl.show(cardsRoot, (String)evt.getItem());
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event dispatch thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("CardLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(600, 300));
JFrame.setDefaultLookAndFeelDecorated(true);
//Create and set up the content pane.
CardLayoutDemo demo = new CardLayoutDemo();
demo.addComponentToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
/* Use an appropriate Look and Feel */
try {
//UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
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();
}
/* Turn off metal's use of bold fonts */
UIManager.put("swing.boldMetal", Boolean.FALSE);
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Take a look how easy would be to create many of cards.
You've got the variable declaration of key components buried within the addComponentToPane(...) method, limiting their scope to this method only, preventing you from getting the information you need. While the canonical solution for this sort of problem is to use an model-view-controller or MVC type pattern so that the model (the underlying program logic and data) is extracted out of the view (the GUI), you can do a quick and dirty solution just by giving your variables private class scope.
For instance, if the JTextField was called textField and was held in a JPanel that acts as a "card", say called cardPanel, you could create a class that looked something like so:
public class CardPanel extends JPanel {
// constants to give the GUI a bigger size
private static final int PREF_W = 300;
private static final int PREF_H = 100;
// our key JTextField declared at class level
private JTextField textField = new JTextField(20);
// a JLabel to display the previous cardpanel's text
private JLabel label = new JLabel(" ");
// create the JPanel
public CardPanel(String name) {
setName(name);
setBorder(BorderFactory.createTitledBorder("Panel " + name));
JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
labelPanel.add(new JLabel("Prior Card's Word: "));
labelPanel.add(label);
setLayout(new BorderLayout());
add(textField, BorderLayout.PAGE_START);
add(labelPanel, BorderLayout.CENTER);
}
// have to jump through this hoop if we want to JTextField to
// have focus when a card is swapped
public void setFocusOnTextField() {
textField.requestFocusInWindow();
textField.selectAll();
}
// to make our GUI larger
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
// allow outside classes to add a listener to the JTextField
public void addActionListener(ActionListener listener) {
textField.addActionListener(listener);
}
// allow outside classes to get text from the text field
public String getTextFieldText() {
return textField.getText();
}
// allow outside classes to put text into the JLabel
public void setLabelText(String text) {
label.setText(text);
}
}
And then we could use it like so:
public class MyCardLayoutDemo extends JPanel {
private static final String[] NAMES = {"One", "Two", "Three", "Four"};
private Map<String, CardPanel> namePanelMap = new HashMap<>();
private CardLayout cardLayout = new CardLayout();
private int nameIndex = 0;
public MyCardLayoutDemo() {
setLayout(cardLayout);
MyListener listener = new MyListener();
for (String name : NAMES) {
CardPanel cardPanel = new CardPanel(name);
cardPanel.addActionListener(listener);
add(cardPanel, name);
namePanelMap.put(name, cardPanel);
}
}
private class MyListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// get the current CardPanel
String name = NAMES[nameIndex];
CardPanel currentCard = namePanelMap.get(name);
// advance the name index to get the next CardPanel
nameIndex++;
nameIndex %= NAMES.length;
name = NAMES[nameIndex];
CardPanel nextCard = namePanelMap.get(name);
// get text from current CardPanel
String text = currentCard.getTextFieldText();
nextCard.setLabelText(text); // and put it into next one
// swap cards
cardLayout.show(MyCardLayoutDemo.this, name);
nextCard.setFocusOnTextField();
}
}
private static void createAndShowGui() {
MyCardLayoutDemo mainPanel = new MyCardLayoutDemo();
JFrame frame = new JFrame("My CardLayout Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}

Why is Plot2DPanel not reacting to its MouseListener's click event?

I learned recently how to switch between Jpanels in CardLayout.
The code works fine but when I attempt to change one of jPanels to Plot2DPanel I get a strange behaviour at runtime. The Plot2DPanel isn't picking up its mouse click events. What have I done wrong? (I assume that is not a bug in jmathplot).
Here's the code:
public class Window {
private JFrame frame;
private JPanel cards;
private JPanel panelOne;
private Plot2DPanel panelTwo;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Window window = new Window();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Window() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 790, 483);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cards = new JPanel();
cards.setLayout(new CardLayout());
panelOne = new JPanel();
panelOne.setBackground(Color.BLACK);
panelOne.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e){
java.awt.Toolkit.getDefaultToolkit().beep(); //debug beep
CardLayout cl = (CardLayout) cards.getLayout();
cl.next(cards);
}
});
panelTwo = new Plot2DPanel();
panelTwo.setBackground(Color.WHITE);
panelTwo.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e){
java.awt.Toolkit.getDefaultToolkit().beep(); //debug beep
CardLayout cl = (CardLayout) cards.getLayout();
cl.next(cards);
}
});
cards.add(panelOne, "panel1");
cards.add(panelTwo, "panel2");
frame.getContentPane().add(cards);
}
}

How to center component vertically in JPanel which useFlowLayout

I have a certain panel which contains a random number of items. This panel is added to the EAST of a JPanel which use BorderLayout.
I'd like to have them vertically centered.
How do i achieve this?
here is a code you can run
public class MainFrame {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new AlignDemo());
}
}
class AlignDemo implements Runnable {
#Override
public void run(){
try {
JFrame mainWindow = new JFrame();
mainWindow.getContentPane().add(initPanel());
mainWindow.pack();
mainWindow.setVisible(true);
} catch (Throwable th) {
JOptionPane.showMessageDialog(null,null,"General Error", JOptionPane.ERROR_MESSAGE);
}
}
private JPanel initPanel() {
FlowLayout layout = new FlowLayout(FlowLayout.LEFT);
layout.setHgap(15);
JPanel myContent = new JPanel();
myContent.setPreferredSize(new Dimension(400,200));
myContent.setBorder(BorderFactory.createLineBorder(Color.blue));
JButton button1 = new JButton("I'm a button");
JButton button2 = new JButton("I'm a button");
JButton button3 = new JButton("I'm a button");
myContent.add(button1,Component.CENTER_ALIGNMENT);
myContent.add(button2,Component.CENTER_ALIGNMENT);
myContent.add(button3,Component.CENTER_ALIGNMENT);
return myContent;
}
}
It can easily be achieved by combining layouts. A JPanel with FlowLayout (controls) to position the buttons relative to one another, placed as a single component into a JPanel with a GridBagLayout (ui).
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class CenteredButtons2 {
private JComponent ui = null;
CenteredButtons2() {
initUI();
}
public void initUI() {
if (ui!=null) return;
ui = new JPanel(new GridBagLayout()); // to center a single component
ui.setBorder(new EmptyBorder(4,4,4,4));
JPanel controls = new JPanel(new FlowLayout());
for (int ii=1; ii<4; ii++) {
controls.add(new JButton("Button " + ii));
}
controls.setBorder(new EmptyBorder(50, 90, 50, 90));
ui.add(controls);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
CenteredButtons2 o = new CenteredButtons2();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}

Not able to switch cards in cardlayout in single jframe

Sorry if its an obvious question.I have been trying to switch panels in the same window using cardlayout.But when i run my application nothing happens.
System.out.println(mntmBookingStatus);
the above statement does get printed on console.but not able to make out why cards arent switching when i click on menuitem "booking status" and "invoice entry".
public class StartDemo {
private JFrame frame;
private JPanel cards = new JPanel(new CardLayout());
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
StartDemo window = new StartDemo();
window.initialize();
window.frame.pack();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 772, 700);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.setVisible(true);
// main menu
menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
// mainmenuoption-1
mnNewMenu = new JMenu("Entries");
menuBar.add(mnNewMenu);
// option-1 items
mntmBookingStatus = new JMenuItem("Booking Status");
mnNewMenu.add(mntmBookingStatus);
mntmBookingStatus.addActionListener(new MenuListenerAdapter());
mntmInvoiceEntry = new JMenuItem("Invoice Entry");
mnNewMenu.add(mntmInvoiceEntry);
mntmInvoiceEntry.addActionListener(new MenuListenerAdapter());
StartDemo demo = new StartDemo();
demo.addComponentToPane(frame.getContentPane());
}
public void addComponentToPane(Container pane) {
JPanel booking_status = new JPanel();
JPanel invoice_entry = new JPanel();
JPanel customer_ledger = new JPanel();
JPanel create_user = new JPanel();
try {
JPanelWithBackground panelWithBackground = new JPanelWithBackground(
"D:\\Kepler Workspace\\WEDemo\\images\\abc.jpg");
cards.add(panelWithBackground, "name_282751308799");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//the layout code for all the panels is written here.
//its to big to post here
cards.add(booking_status, BOOKINGPANEL);
cards.add(invoice_entry, INVOICEPANEL);
cards.add(customer_ledger, CUSTOMERLEDGER);
cards.add(create_user, CREATEUSER);
pane.add(cards, BorderLayout.CENTER);
}
public class MenuListenerAdapter implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
CardLayout c = (CardLayout) (cards.getLayout());
if (e.getSource() == mntmBookingStatus) {
c.show(cards, BOOKINGPANEL);
System.out.println(mntmBookingStatus);
} else if (e.getSource() == mntmInvoiceEntry) {
c.show(cards, INVOICEPANEL);
System.out.println(mntmInvoiceEntry);
}
}
This is my JPanelWithBackground class
public class JPanelWithBackground extends JPanel {
private Image backgroungImage;
private Image scaledBackgroundImage;
// Some code to initialize the background image.
// Here, we use the constructor to load the image. This
// can vary depending on the use case of the panel.
public JPanelWithBackground(String fileName) throws IOException {
backgroungImage = ImageIO.read(new File(fileName));
}
public void paintComponent(Graphics g){
super.paintComponent(g);
// Draw the backgroung image
g.drawImage(backgroungImage, 0, 0,getWidth(),getHeight(),null);
}
It's these two lines right here
StartDemo demo = new StartDemo();
demo.addComponentToPane(frame.getContentPane());
Since your initialize() method isn't static I think it's safe to assume that you instantiate youe StartDemo again in the main method. In that case, the above code truly is your problem and would totally explain why it doesn't work. Just do this
//StartDemo demo = new StartDemo(); <-- get rid of this.
addComponentToPane(frame.getContentPane());
Tested with code additions only to get it running. Also please not my comments above. setVisible(true) generally is the last thing you should do after adding all components.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class StartDemo {
private JFrame frame;
private JPanel cards = new JPanel(new CardLayout());
JMenuBar menuBar;
JMenu mnNewMenu;
JMenuItem mntmBookingStatus;
JMenuItem mntmInvoiceEntry;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new StartDemo().initialize();
}
});
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 772, 700);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// main menu
menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
// mainmenuoption-1
mnNewMenu = new JMenu("Entries");
menuBar.add(mnNewMenu);
// option-1 items
mntmBookingStatus = new JMenuItem("Booking Status");
mnNewMenu.add(mntmBookingStatus);
mntmBookingStatus.addActionListener(new MenuListenerAdapter());
//StartDemo demo = new StartDemo();
addComponentToPane(frame.getContentPane()); mntmInvoiceEntry = new JMenuItem("Invoice Entry");
mnNewMenu.add(mntmInvoiceEntry);
mntmInvoiceEntry.addActionListener(new MenuListenerAdapter());
frame.setVisible(true);
}
public void addComponentToPane(Container pane) {
JPanel booking_status = new JPanel();
JPanel invoice_entry = new JPanel();
//JPanel customer_ledger = new JPanel();
//JPanel create_user = new JPanel();
try {
JPanelWithBackground panelWithBackground = new JPanelWithBackground(
"/resources/stackoverflow5.png");
cards.add(panelWithBackground, "name_282751308799");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
cards.add(booking_status, "booking");
cards.add(invoice_entry, "invoice");
//cards.add(customer_ledger, CUSTOMERLEDGER);
//cards.add(create_user, CREATEUSER);
pane.add(cards, BorderLayout.CENTER);
}
class JPanelWithBackground extends JPanel {
Image img;
public JPanelWithBackground(String path) throws IOException {
img = ImageIO.read(getClass().getResource(path));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
}
public class MenuListenerAdapter implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
CardLayout c = (CardLayout) (cards.getLayout());
if (e.getSource() == mntmBookingStatus) {
c.show(cards,"booking");
System.out.println(mntmBookingStatus);
} else if (e.getSource() == mntmInvoiceEntry) {
c.show(cards, "invoice");
System.out.println(mntmInvoiceEntry);
}
}
}
}

Categories

Resources