Java Card Layout with Background Image - java

I am creating a Flight Reservation system for a project, having trouble with the GUI of the app. I am using a CardLayout to manage the multiple cards for this program.
In the login card I am trying to add a background image, but the input fields are shown below the image.
The code for the program is
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
import javax.imageio.*;
import java.net.*;
public class CardPanel {
public static void main(String[] args) {
try {
CardLayout cardLayout = null;
JFrame frame = new JFrame("Welcome");
JPanel contentPane = new JPanel(cardLayout);
URL url = new URL("https://i.stack.imgur.com/P59NF.png");
BufferedImage img = ImageIO.read(url);
ImageIcon imageIcon = new ImageIcon(img);
JLabel logo = new JLabel(imageIcon);
JPanel buttonsPanel = new JPanel();
JButton login = new JButton("Login");
buttonsPanel.add(login);
contentPane.setLayout(new BorderLayout(10, 15));
contentPane.add(logo, BorderLayout.NORTH);
contentPane.add(buttonsPanel, BorderLayout.SOUTH);
frame.add(contentPane, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
A screenshot of the app is also attached (http://i.imgur.com/PkjblPu.png).
I would like the button to be above the background image.

A test suggests a card layout cannot be used to show a BG image. It seems that internally it removes one card and adds another when swapping components. Use a custom painted JPanel to draw the BG image.
Here is the evidence.
That red color is the panel with the card layout, the button panel is set to be transparent.
import java.awt.*;
import javax.swing.*;
import java.net.URL;
public class CardPanel {
public static void main(String[] args) throws Exception {
CardLayout cardLayout = new CardLayout();
JFrame frame = new JFrame("Welcome");
JPanel contentPane = new JPanel(cardLayout);
contentPane.setBackground(Color.RED);
ImageIcon imageIcon = new ImageIcon(new URL("https://i.stack.imgur.com/OVOg3.jpg"));
JLabel logo = new JLabel(imageIcon);
JPanel buttonsPanel = new JPanel();
JButton login = new JButton("Login");
buttonsPanel.add(login);
buttonsPanel.setOpaque(false);
contentPane.add(logo, "logo");
contentPane.add(buttonsPanel, "button");
cardLayout.show(contentPane, "button");
frame.add(contentPane, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}

Related

How do I create bordered color style panel?

I'm trying to create a canvas for my oval shape, and I want it to be different from the main JFrame color. So far, using setSize upon the panel doesn't work, it ended up creating a small box that I couldn't draw in. Here is the panel design that I intended it to be, with the white-colored part as the main frame.
PanelDesign
As I've said, using all three Layout modes (Border, Flow, and Grid) only creates a yellow small box in the upper middle part of the frame. This is the code that I use.
How can I create the panel design similar to the image posted above?
setTitle("Oval Shape Mover");
setSize(500, 200);
setLayout(new BorderLayout());
JPanel mainpanel, panel1, panel2;
mainpanel = new JPanel();
panel1 = new JPanel();
panel2 = new JPanel();
panel1.setBackground(Color.YELLOW);
mainpanel.add(panel1, BorderLayout.CENTER);
mainpanel.add(panel2);
add(mainpanel);
setVisible(true);
The layouts used to make Java Swing GUIs will more often honor the preferred size than the size. Having said that, a custom rendered component should override (rather than set) getPreferredSize().
This example suggests a preferred size by using a JLabel to display the icon, and empty borders to pad the GUI out.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import java.net.*;
public class RedDotLayout {
private JComponent ui = null;
String urlToRedCircle = "https://i.stack.imgur.com/wCF8S.png";
RedDotLayout() {
try {
initUI();
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
}
public final void initUI() throws MalformedURLException {
ui = new JPanel(new BorderLayout());
ui.setBackground(Color.YELLOW);
ui.setBorder(new LineBorder(Color.BLACK, 2));
JLabel label = new JLabel(new ImageIcon(new URL(urlToRedCircle)));
label.setBorder(new CompoundBorder(
new LineBorder(Color.GREEN.darker(), 2),
new EmptyBorder(20, 200, 20, 200)));
ui.add(label, BorderLayout.CENTER);
JPanel bottomPanel = new JPanel();
bottomPanel.setBackground(Color.WHITE);
bottomPanel.setBorder(new EmptyBorder(30, 50, 30, 50));
ui.add(bottomPanel, BorderLayout.PAGE_END);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = () -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
RedDotLayout o = new RedDotLayout();
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);
}
}

Dynamically changing the size of JFrame when exposed to different screen resolutions

So for a school project I made a grade book in java. When creating the gui I used hardcoded values in the setBounds() methods. Now this worked when I had a 1024×768 screen resolution it looked alright, but when I got a new laptop and it had a 4k screen it looked super small when I ran the program.
So my question would be is there a way to dynamically change the size of the Jframe and all of the associated objects on the frame so it matches the resolution of the screen?
I know that you can get the screen resolution from this
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double width = screenSize.getWidth();
double height = screenSize.getHeight();
but I do not know what would be the best way to do this.
Taking your approach as example and taking this answer and this tutorial as base, here you have the clues:
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
public class Q1 extends JFrame {
public static void main(String[] args) {
Q1 frame = new Q1();
frame.setSize(300, 300);
frame.setMinimumSize(new Dimension(300, 300));
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public Q1() {
this.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// This is only called when the user releases the mouse button.
System.out.println("componentResized");
}
});
}
#Override
public void validate() {
resize();
super.validate();
};
private void resize() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double width = screenSize.getWidth();
double height = screenSize.getHeight();
System.out.println(width + "," + height);
}
}
This will print the size of the screen when your resize the frame, so you just need to add an if/else in the resize method to make frame bigger
OUTPUT
1366.0,768.0
1366.0,768.0
componentResized
1366.0,768.0
1366.0,768.0
componentResized
1366.0,768.0
1366.0,768.0
componentResized
A layout manager is an object that implements the LayoutManager
interface* and determines the size and position of the components
within a container. Although components can provide size and alignment
hints, a container's layout manager has the final say on the size and
position of the components within the container.
See the example I found using layout managers.Hope you get some idea.THe original author is here Set a layout manager like BorderLayout and then define more specifically, where your panel should go: like
MainPanel mainPanel = new MainPanel();
JFrame mainFrame = new JFrame();
mainFrame.setLayout(new BorderLayout());
mainFrame.add(mainPanel, BorderLayout.CENTER);
mainFrame.pack();
mainFrame.setVisible(true);
puts the panel into the center area of the frame and lets it grow automatically when resizing the frame.See below example for full usage:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestLayoutManagers {
private JPanel northFlowLayoutPanel;
private JPanel southBorderLayoutPanel;
private JPanel centerGridBagLayoutPanel;
private JPanel westBoxLayoutPanel;
private JPanel eastGridLayoutPanel;
private final JButton northButton = new JButton("North Button");
private final JButton southButton = new JButton("South Button");
private final JButton centerButton = new JButton("Center Button");
private final JButton eastButton = new JButton("East Button");
private final JButton westButton = new JButton("West Button");
public TestLayoutManagers() {
northFlowLayoutPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
southBorderLayoutPanel = new JPanel(new BorderLayout());
centerGridBagLayoutPanel = new JPanel(new GridBagLayout());
eastGridLayoutPanel = new JPanel(new GridLayout(1, 1));
Box box = Box.createHorizontalBox();
westBoxLayoutPanel = new JPanel();
northFlowLayoutPanel.add(northButton);
northFlowLayoutPanel.setBorder(BorderFactory.createTitledBorder("Flow Layout"));
southBorderLayoutPanel.add(southButton);
southBorderLayoutPanel.setBorder(BorderFactory.createTitledBorder("Border Layout"));
centerGridBagLayoutPanel.add(centerButton);
centerGridBagLayoutPanel.setBorder(BorderFactory.createTitledBorder("GridBag Layout"));
eastGridLayoutPanel.add(eastButton);
eastGridLayoutPanel.setBorder(BorderFactory.createTitledBorder("Grid Layout"));
box.add(westButton);
westBoxLayoutPanel.add(box);
westBoxLayoutPanel.setBorder(BorderFactory.createTitledBorder("Box Layout"));
JFrame frame = new JFrame("Test Layout Managers");
frame.setLayout(new BorderLayout()); // This is the deafault layout
frame.add(northFlowLayoutPanel, BorderLayout.PAGE_START);
frame.add(southBorderLayoutPanel, BorderLayout.PAGE_END);
frame.add(centerGridBagLayoutPanel, BorderLayout.CENTER);
frame.add(eastGridLayoutPanel, BorderLayout.LINE_END);
frame.add(westBoxLayoutPanel, BorderLayout.LINE_START);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
TestLayoutManagers testLayoutManagers
= new TestLayoutManagers();
}
});
}
}

Adding elements (i.e. JLabels) outside of the set layout

As part of a project we've got to have 9 boxes, here I've just implemented alternating colors as an example in place of the images we should be using. But whilst I want these 9 JLabels in this grid layout (3,3), I also want to have a message at the top (a JLabel) that I can just centralize, like a welcoming message as well as having around four JButtons underneath? Can somebody please point me in the right direction as to how to achieve this?
Thank you!
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class HomeController extends JPanel implements MouseListener
{
HomeController()
{
setLayout(new GridLayout(3,3));
JLabel apl1 = new JLabel("");
apl1.setBackground(Color.WHITE);
apl1.setOpaque(true);
this.add(apl1);
JLabel apl2 = new JLabel("");
apl2.setBackground(Color.BLACK);
apl2.setOpaque(true);
this.add(apl2);
JLabel apl3 = new JLabel("");
apl3.setBackground(Color.WHITE);
apl3.setOpaque(true);
this.add(apl3);
JLabel apl4 = new JLabel("");
apl4.setBackground(Color.BLACK);
apl4.setOpaque(true);
this.add(apl4);
JLabel apl5 = new JLabel("");
apl5.setBackground(Color.WHITE);
apl5.setOpaque(true);
this.add(apl5);
JLabel apl6 = new JLabel("");
apl6.setBackground(Color.BLACK);
apl6.setOpaque(true);
this.add(apl6);
JLabel apl7 = new JLabel("");
apl7.setBackground(Color.WHITE);
apl7.setOpaque(true);
this.add(apl7);
JLabel apl8 = new JLabel("");
apl8.setBackground(Color.BLACK);
apl8.setOpaque(true);
this.add(apl8);
JLabel apl9 = new JLabel("");
apl9.setBackground(Color.WHITE);
apl9.setOpaque(true);
this.add(apl9);
JLabel message = new JLabel("hello world");
this.add(message);
}
}
You can combine multiple panels with different layouts. For details take a look at A Visual Guide to Layout Managers.
For example, default layout of JFrame is BorderLayout. Using BorderLayout, you can place the title at BorderLayout.NORTH, panel with buttons at BorderLayout.SOUTH and panel with grid of labels at BorderLayout.CENTER. Each panel may have its own more complex layout. For example, grid of labels is using GridLayout, and buttons panel is using FlowLayout.
Here is a very simple example based on the posted code that demonstrates this approach:
import java.awt.*;
import javax.swing.*;
public class TestGrid {
public TestGrid() {
final JFrame frame = new JFrame("Grid");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel(new GridLayout(3, 3));
for (int idx = 0; idx < 9; idx++) {
JLabel label = new JLabel();
label.setBackground(idx % 2 == 0 ? Color.WHITE : Color.BLACK);
label.setOpaque(true);
mainPanel.add(label);
}
mainPanel.setPreferredSize(new Dimension(200, 200));
frame.add(mainPanel, BorderLayout.CENTER);
frame.add(new JLabel("Title", JLabel.CENTER), BorderLayout.NORTH);
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(new JButton("Start"));
buttonsPanel.add(new JButton("Stop"));
frame.add(buttonsPanel, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestGrid();
}
});
}
}

multiple 'imageviews' in jframe

hi all i am trying to add multiple components to my jframe. but i cant seem to get it to work.
private void initGUI() {
setAlwaysOnTop(true);
setUndecorated(true);
AWTUtilities.setWindowOpaque(this, false);
AWTUtilities.setWindowOpacity(this, 0.5f);
setLocation(ini.getButtonsX(), ini.getButtonsY());
setSize(ini.getButtonsW(), ini.getButtonsH());
setLayout(null);
JPanel panel = new JPanel();
panel.setLayout(null);
ImageView baron = new ImageView("image/nashor.png", 50, 50);
baron.setBounds(50, 50, 50, 50);
ImageView test = new ImageView("image/dragon.png", 50, 50);
test.setBounds(50, 150, 50, 50);
panel.add(baron);
panel.add(test);
panel.setBounds(0, 0, ini.getButtonsW(), ini.getButtonsH());
add(panel);
}
my ImageView is a class that extends a JPanel which paints a image.
at this point only nashor is painted
any help is greatly appreciated.
I recommend that you have your JPanel panel use a GridLayout, not a null layout, and that you not set your ImageView sizes but rather make sure that the class has a getPreferredSize() method override that makes sense, that returns a Dimension of the appropriate size. Then if you call pack() on your JFrame after adding components, the layout managers will take care of sizing things for you.
Consider this program:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.awt.*;
import java.awt.event.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Init extends JFrame{
JPanel view = new JPanel();
JMenuBar mBar = new JMenuBar();
JMenu menu = new JMenu("File");
JMenuItem mItemOpen = new JMenuItem("Open");
JMenuItem mItemExit = new JMenuItem("Exit");
JFileChooser fc = new JFileChooser();
JTextField txtPath = new JTextField();
BufferedImage myPicture;
File filePath;
String path;
public Init(){
mBar.add(menu);
menu.add(mItemOpen);
menu.addSeparator();
menu.add(mItemExit);
setJMenuBar(mBar);
txtPath.setEditable(false);
mItemOpen.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
fc.showOpenDialog(null);
filePath = fc.getSelectedFile();
path = filePath.getPath();
txtPath.setText(path);
try {
//view.removeAll();
myPicture = ImageIO.read(new File(path));
JLabel picLabel = new JLabel(new ImageIcon(myPicture));
view.add(picLabel);
revalidate();
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
setLayout(new BorderLayout());
getContentPane().add(new JScrollPane(view),BorderLayout.CENTER);
getContentPane().add(txtPath,BorderLayout.SOUTH);
setTitle(".:My Picture Viewer:.");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//pack();
setSize(1024,768);
setVisible(true);
}
public static void main(String [] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new Init();
}
});
}
}

how to save panel as image in swing?

Hi i want to convert panel which contains components like label and buttons to image file.
I have done the following code. The image was saved. but the content of the panel not visible or saved. Can anyone tell me how to save the panel with its components.
Code:
package PanelToImage;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;
public class sample extends JPanel {
public JPanel firstpanel;
public JPanel secondpanel;
JLabel label1, label2;
JButton button1, button2;
public sample() {
firstpanel = new JPanel();
firstpanel.setSize(400,300);
firstpanel.setBackground(Color.RED);
secondpanel = new JPanel();
secondpanel.setBackground(Color.GREEN);
secondpanel.setSize(400,300);
label1 = new JLabel("label1");
label2 = new JLabel("label2");
button1 = new JButton("button1");
button2 = new JButton("button2");
firstpanel.add(label1);
firstpanel.add(button1);
secondpanel.add(label2);
secondpanel.add(button2);
saveImage(firstpanel);
add(firstpanel);
// add(secondpanel);
}
public static void main(String args[]) {
JFrame frame = new JFrame();
sample sam = new sample();
frame.setContentPane(sam);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
}
private void saveImage(JPanel panel) {
BufferedImage img = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB);
panel.paint(img.getGraphics());
try {
ImageIO.write(img, "png", new File("E://Screen.png"));
System.out.println("panel saved as image");
} catch (Exception e) {
System.out.println("panel not saved" + e.getMessage());
}
}
}
Tthis code works for me (in the JFrame):
Container c = getContentPane();
BufferedImage im = new BufferedImage(c.getWidth(), c.getHeight(), BufferedImage.TYPE_INT_ARGB);
c.paint(im.getGraphics());
ImageIO.write(im, "PNG", new File("shot.png"));
Maybe you have used custom panels. If true, try to add super.paint(g) at the beginning of the paint methods of your panels.
EDIT: You have to call saveImage after display the frame:
public static void main(String args[]) {
...
frame.setSize(400, 300);
sam.saveImage(sam.firstpanel);
}
EDIT 2: This is the saved image (is little because the layout, but is the proof that it should work):
I called the saveImage as last call in the main, and used a file in the user dir (new File("Screen.png")) as nIcE cOw said.
Here try this example program, instead of using getGraphics() seems like you have to use createGraphics() for the BufferedImage you are about to make.
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;
public class SnapshotExample
{
private JPanel contentPane;
private void displayGUI()
{
JFrame frame = new JFrame("Snapshot Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel();
contentPane.setOpaque(true);
contentPane.setBackground(Color.WHITE);
JLabel label = new JLabel("This JLabel will display"
+ " itself on the SNAPSHOT", JLabel.CENTER);
contentPane.add(label);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
makePanelImage(contentPane);
}
private void makePanelImage(Component panel)
{
Dimension size = panel.getSize();
BufferedImage image = new BufferedImage(
size.width, size.height
, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
panel.paint(g2);
try
{
ImageIO.write(image, "png", new File("snapshot.png"));
System.out.println("Panel saved as Image.");
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new SnapshotExample().displayGUI();
}
});
}
}

Categories

Resources